@copilotkit/react-ui 1.10.0-next.8 → 1.10.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/CHANGELOG.md +132 -0
- package/dist/{chunk-U5ATIGWH.mjs → chunk-BJHJBS5M.mjs} +45 -5
- package/dist/chunk-BJHJBS5M.mjs.map +1 -0
- package/dist/{chunk-KLV4ERV6.mjs → chunk-GBP47ONN.mjs} +2 -2
- package/dist/{chunk-3DVMCBME.mjs → chunk-GJ4SX4JE.mjs} +97 -35
- package/dist/chunk-GJ4SX4JE.mjs.map +1 -0
- package/dist/{chunk-APLX7E54.mjs → chunk-J5ZZR6YB.mjs} +2 -2
- package/dist/chunk-MIVUCSGO.mjs +126 -0
- package/dist/chunk-MIVUCSGO.mjs.map +1 -0
- package/dist/{chunk-JHUTTP5C.mjs → chunk-T5QU6KSB.mjs} +5 -1
- package/dist/chunk-T5QU6KSB.mjs.map +1 -0
- package/dist/{chunk-BPU3FDT4.mjs → chunk-Y44VLEUH.mjs} +30 -11
- package/dist/chunk-Y44VLEUH.mjs.map +1 -0
- package/dist/components/chat/Chat.d.ts +32 -2
- package/dist/components/chat/Chat.js +1084 -865
- package/dist/components/chat/Chat.js.map +1 -1
- package/dist/components/chat/Chat.mjs +7 -6
- package/dist/components/chat/Messages.d.ts +1 -1
- package/dist/components/chat/Messages.js +984 -23
- package/dist/components/chat/Messages.js.map +1 -1
- package/dist/components/chat/Messages.mjs +9 -1
- package/dist/components/chat/Modal.js +1107 -875
- package/dist/components/chat/Modal.js.map +1 -1
- package/dist/components/chat/Modal.mjs +8 -7
- package/dist/components/chat/Popup.js +1109 -877
- package/dist/components/chat/Popup.js.map +1 -1
- package/dist/components/chat/Popup.mjs +9 -8
- package/dist/components/chat/Sidebar.js +1109 -877
- package/dist/components/chat/Sidebar.js.map +1 -1
- package/dist/components/chat/Sidebar.mjs +9 -8
- package/dist/components/chat/index.js +1111 -879
- package/dist/components/chat/index.js.map +1 -1
- package/dist/components/chat/index.mjs +16 -15
- package/dist/components/chat/messages/LegacyRenderMessage.d.ts +28 -0
- package/dist/components/chat/messages/LegacyRenderMessage.js +980 -0
- package/dist/components/chat/messages/LegacyRenderMessage.js.map +1 -0
- package/dist/components/chat/messages/LegacyRenderMessage.mjs +17 -0
- package/dist/components/chat/messages/LegacyRenderMessage.mjs.map +1 -0
- package/dist/components/chat/messages/RenderMessage.js +4 -0
- package/dist/components/chat/messages/RenderMessage.js.map +1 -1
- package/dist/components/chat/messages/RenderMessage.mjs +1 -1
- package/dist/components/chat/props.d.ts +55 -1
- package/dist/components/chat/props.js.map +1 -1
- package/dist/components/index.js +1111 -879
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +16 -15
- package/dist/index.js +1113 -881
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +16 -15
- package/package.json +4 -4
- package/src/components/chat/Chat.tsx +144 -21
- package/src/components/chat/Messages.tsx +56 -3
- package/src/components/chat/Modal.tsx +24 -3
- package/src/components/chat/messages/LegacyRenderMessage.tsx +143 -0
- package/src/components/chat/messages/RenderMessage.tsx +3 -0
- package/src/components/chat/props.ts +64 -1
- package/dist/chunk-3DVMCBME.mjs.map +0 -1
- package/dist/chunk-BPU3FDT4.mjs.map +0 -1
- package/dist/chunk-JHUTTP5C.mjs.map +0 -1
- package/dist/chunk-U5ATIGWH.mjs.map +0 -1
- /package/dist/{chunk-KLV4ERV6.mjs.map → chunk-GBP47ONN.mjs.map} +0 -0
- /package/dist/{chunk-APLX7E54.mjs.map → chunk-J5ZZR6YB.mjs.map} +0 -0
|
@@ -395,559 +395,137 @@ var ChatContextProvider = ({
|
|
|
395
395
|
};
|
|
396
396
|
|
|
397
397
|
// src/components/chat/Messages.tsx
|
|
398
|
-
var
|
|
398
|
+
var import_react6 = require("react");
|
|
399
399
|
var import_react_core = require("@copilotkit/react-core");
|
|
400
|
+
|
|
401
|
+
// src/components/chat/messages/UserMessage.tsx
|
|
400
402
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
401
|
-
var
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
onRegenerate,
|
|
408
|
-
onCopy,
|
|
409
|
-
onThumbsUp,
|
|
410
|
-
onThumbsDown,
|
|
411
|
-
markdownTagRenderers
|
|
412
|
-
}) => {
|
|
413
|
-
const { labels } = useChatContext();
|
|
414
|
-
const { visibleMessages, interrupt } = (0, import_react_core.useCopilotChatInternal)();
|
|
415
|
-
const initialMessages = (0, import_react2.useMemo)(() => makeInitialMessages(labels.initial), [labels.initial]);
|
|
416
|
-
const messages = [...initialMessages, ...visibleMessages];
|
|
417
|
-
const { messagesContainerRef, messagesEndRef } = useScrollToBottom(messages);
|
|
418
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "copilotKitMessages", ref: messagesContainerRef, children: [
|
|
419
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "copilotKitMessagesContainer", children: [
|
|
420
|
-
messages.map((message, index) => {
|
|
421
|
-
const isCurrentMessage = index === messages.length - 1;
|
|
422
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
423
|
-
RenderMessage2,
|
|
424
|
-
{
|
|
425
|
-
message,
|
|
426
|
-
inProgress,
|
|
427
|
-
index,
|
|
428
|
-
isCurrentMessage,
|
|
429
|
-
AssistantMessage: AssistantMessage2,
|
|
430
|
-
UserMessage: UserMessage2,
|
|
431
|
-
onRegenerate,
|
|
432
|
-
onCopy,
|
|
433
|
-
onThumbsUp,
|
|
434
|
-
onThumbsDown,
|
|
435
|
-
markdownTagRenderers
|
|
436
|
-
},
|
|
437
|
-
index
|
|
438
|
-
);
|
|
439
|
-
}),
|
|
440
|
-
interrupt
|
|
441
|
-
] }),
|
|
442
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("footer", { className: "copilotKitMessagesFooter", ref: messagesEndRef, children })
|
|
443
|
-
] });
|
|
444
|
-
};
|
|
445
|
-
function makeInitialMessages(initial) {
|
|
446
|
-
if (!initial)
|
|
447
|
-
return [];
|
|
448
|
-
if (Array.isArray(initial)) {
|
|
449
|
-
return initial.map((message) => {
|
|
450
|
-
return {
|
|
451
|
-
id: message,
|
|
452
|
-
role: "assistant",
|
|
453
|
-
content: message
|
|
454
|
-
};
|
|
455
|
-
});
|
|
403
|
+
var UserMessage = (props) => {
|
|
404
|
+
const { message, ImageRenderer: ImageRenderer2 } = props;
|
|
405
|
+
const isImageMessage = message && "image" in message && message.image;
|
|
406
|
+
if (isImageMessage) {
|
|
407
|
+
const imageMessage = message;
|
|
408
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ImageRenderer2, { image: imageMessage.image, content: imageMessage.content }) });
|
|
456
409
|
}
|
|
457
|
-
return
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
};
|
|
476
|
-
const handleScroll = () => {
|
|
477
|
-
if (isProgrammaticScrollRef.current) {
|
|
478
|
-
isProgrammaticScrollRef.current = false;
|
|
410
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: message == null ? void 0 : message.content });
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
// src/components/chat/Markdown.tsx
|
|
414
|
+
var import_react3 = require("react");
|
|
415
|
+
var import_react_markdown = __toESM(require("react-markdown"));
|
|
416
|
+
|
|
417
|
+
// src/components/chat/CodeBlock.tsx
|
|
418
|
+
var import_react2 = require("react");
|
|
419
|
+
var import_react_syntax_highlighter = require("react-syntax-highlighter");
|
|
420
|
+
|
|
421
|
+
// src/hooks/use-copy-to-clipboard.tsx
|
|
422
|
+
var React2 = __toESM(require("react"));
|
|
423
|
+
function useCopyToClipboard({ timeout = 2e3 }) {
|
|
424
|
+
const [isCopied, setIsCopied] = React2.useState(false);
|
|
425
|
+
const copyToClipboard = (value) => {
|
|
426
|
+
var _a;
|
|
427
|
+
if (typeof window === "undefined" || !((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) {
|
|
479
428
|
return;
|
|
480
429
|
}
|
|
481
|
-
if (
|
|
482
|
-
const { scrollTop, scrollHeight, clientHeight } = messagesContainerRef.current;
|
|
483
|
-
isUserScrollUpRef.current = scrollTop + clientHeight < scrollHeight;
|
|
484
|
-
}
|
|
485
|
-
};
|
|
486
|
-
(0, import_react2.useEffect)(() => {
|
|
487
|
-
const container = messagesContainerRef.current;
|
|
488
|
-
if (container) {
|
|
489
|
-
container.addEventListener("scroll", handleScroll);
|
|
490
|
-
}
|
|
491
|
-
return () => {
|
|
492
|
-
if (container) {
|
|
493
|
-
container.removeEventListener("scroll", handleScroll);
|
|
494
|
-
}
|
|
495
|
-
};
|
|
496
|
-
}, []);
|
|
497
|
-
(0, import_react2.useEffect)(() => {
|
|
498
|
-
const container = messagesContainerRef.current;
|
|
499
|
-
if (!container) {
|
|
430
|
+
if (!value) {
|
|
500
431
|
return;
|
|
501
432
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
mutationObserver.observe(container, {
|
|
508
|
-
childList: true,
|
|
509
|
-
subtree: true,
|
|
510
|
-
characterData: true
|
|
433
|
+
navigator.clipboard.writeText(value).then(() => {
|
|
434
|
+
setIsCopied(true);
|
|
435
|
+
setTimeout(() => {
|
|
436
|
+
setIsCopied(false);
|
|
437
|
+
}, timeout);
|
|
511
438
|
});
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
};
|
|
515
|
-
}, []);
|
|
516
|
-
(0, import_react2.useEffect)(() => {
|
|
517
|
-
isUserScrollUpRef.current = false;
|
|
518
|
-
scrollToBottom();
|
|
519
|
-
}, [messages.filter((m) => m.role === "user").length]);
|
|
520
|
-
return { messagesEndRef, messagesContainerRef };
|
|
439
|
+
};
|
|
440
|
+
return { isCopied, copyToClipboard };
|
|
521
441
|
}
|
|
522
442
|
|
|
523
|
-
// src/components/chat/
|
|
524
|
-
var import_react5 = require("react");
|
|
525
|
-
|
|
526
|
-
// src/components/chat/Textarea.tsx
|
|
527
|
-
var import_react3 = require("react");
|
|
443
|
+
// src/components/chat/CodeBlock.tsx
|
|
528
444
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
529
|
-
var
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
445
|
+
var programmingLanguages = {
|
|
446
|
+
javascript: ".js",
|
|
447
|
+
python: ".py",
|
|
448
|
+
java: ".java",
|
|
449
|
+
c: ".c",
|
|
450
|
+
cpp: ".cpp",
|
|
451
|
+
"c++": ".cpp",
|
|
452
|
+
"c#": ".cs",
|
|
453
|
+
ruby: ".rb",
|
|
454
|
+
php: ".php",
|
|
455
|
+
swift: ".swift",
|
|
456
|
+
"objective-c": ".m",
|
|
457
|
+
kotlin: ".kt",
|
|
458
|
+
typescript: ".ts",
|
|
459
|
+
go: ".go",
|
|
460
|
+
perl: ".pl",
|
|
461
|
+
rust: ".rs",
|
|
462
|
+
scala: ".scala",
|
|
463
|
+
haskell: ".hs",
|
|
464
|
+
lua: ".lua",
|
|
465
|
+
shell: ".sh",
|
|
466
|
+
sql: ".sql",
|
|
467
|
+
html: ".html",
|
|
468
|
+
css: ".css"
|
|
469
|
+
// add more file extensions here, make sure the key is same as language prop in CodeBlock.tsx component
|
|
470
|
+
};
|
|
471
|
+
var generateRandomString = (length, lowercase = false) => {
|
|
472
|
+
const chars = "ABCDEFGHJKLMNPQRSTUVWXY3456789";
|
|
473
|
+
let result = "";
|
|
474
|
+
for (let i = 0; i < length; i++) {
|
|
475
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
476
|
+
}
|
|
477
|
+
return lowercase ? result.toLowerCase() : result;
|
|
478
|
+
};
|
|
479
|
+
var CodeBlock = (0, import_react2.memo)(({ language, value }) => {
|
|
480
|
+
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2e3 });
|
|
481
|
+
const downloadAsFile = () => {
|
|
482
|
+
if (typeof window === "undefined") {
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
const fileExtension = programmingLanguages[language] || ".file";
|
|
486
|
+
const suggestedFileName = `file-${generateRandomString(3, true)}${fileExtension}`;
|
|
487
|
+
const fileName = window.prompt("Enter file name", suggestedFileName);
|
|
488
|
+
if (!fileName) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
const blob = new Blob([value], { type: "text/plain" });
|
|
492
|
+
const url = URL.createObjectURL(blob);
|
|
493
|
+
const link = document.createElement("a");
|
|
494
|
+
link.download = fileName;
|
|
495
|
+
link.href = url;
|
|
496
|
+
link.style.display = "none";
|
|
497
|
+
document.body.appendChild(link);
|
|
498
|
+
link.click();
|
|
499
|
+
document.body.removeChild(link);
|
|
500
|
+
URL.revokeObjectURL(url);
|
|
501
|
+
};
|
|
502
|
+
const onCopy = () => {
|
|
503
|
+
if (isCopied)
|
|
504
|
+
return;
|
|
505
|
+
copyToClipboard(value);
|
|
506
|
+
};
|
|
507
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "copilotKitCodeBlock", children: [
|
|
508
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "copilotKitCodeBlockToolbar", children: [
|
|
509
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "copilotKitCodeBlockToolbarLanguage", children: language }),
|
|
510
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "copilotKitCodeBlockToolbarButtons", children: [
|
|
511
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: downloadAsFile, children: DownloadIcon }),
|
|
512
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: onCopy, children: isCopied ? CheckIcon : CopyIcon })
|
|
513
|
+
] })
|
|
514
|
+
] }),
|
|
515
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
516
|
+
import_react_syntax_highlighter.Prism,
|
|
566
517
|
{
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
style: {
|
|
575
|
-
overflow: "auto",
|
|
576
|
-
resize: "none",
|
|
577
|
-
maxHeight: `${maxHeight}px`
|
|
518
|
+
language,
|
|
519
|
+
style: highlightStyle,
|
|
520
|
+
PreTag: "div",
|
|
521
|
+
customStyle: {
|
|
522
|
+
margin: 0,
|
|
523
|
+
borderBottomLeftRadius: "0.375rem",
|
|
524
|
+
borderBottomRightRadius: "0.375rem"
|
|
578
525
|
},
|
|
579
|
-
|
|
526
|
+
children: value
|
|
580
527
|
}
|
|
581
|
-
)
|
|
582
|
-
}
|
|
583
|
-
);
|
|
584
|
-
var Textarea_default = AutoResizingTextarea;
|
|
585
|
-
|
|
586
|
-
// src/hooks/use-push-to-talk.tsx
|
|
587
|
-
var import_react_core2 = require("@copilotkit/react-core");
|
|
588
|
-
var import_runtime_client_gql = require("@copilotkit/runtime-client-gql");
|
|
589
|
-
var import_react4 = require("react");
|
|
590
|
-
var startRecording = (mediaStreamRef, mediaRecorderRef, audioContextRef, recordedChunks, onStop) => __async(void 0, null, function* () {
|
|
591
|
-
if (!mediaStreamRef.current || !audioContextRef.current) {
|
|
592
|
-
mediaStreamRef.current = yield navigator.mediaDevices.getUserMedia({ audio: true });
|
|
593
|
-
audioContextRef.current = new window.AudioContext();
|
|
594
|
-
yield audioContextRef.current.resume();
|
|
595
|
-
}
|
|
596
|
-
mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current);
|
|
597
|
-
mediaRecorderRef.current.start(1e3);
|
|
598
|
-
mediaRecorderRef.current.ondataavailable = (event) => {
|
|
599
|
-
recordedChunks.push(event.data);
|
|
600
|
-
};
|
|
601
|
-
mediaRecorderRef.current.onstop = onStop;
|
|
602
|
-
});
|
|
603
|
-
var stopRecording = (mediaRecorderRef) => {
|
|
604
|
-
if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
|
|
605
|
-
mediaRecorderRef.current.stop();
|
|
606
|
-
}
|
|
607
|
-
};
|
|
608
|
-
var transcribeAudio = (recordedChunks, transcribeAudioUrl) => __async(void 0, null, function* () {
|
|
609
|
-
const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
|
|
610
|
-
const formData = new FormData();
|
|
611
|
-
formData.append("file", completeBlob, "recording.mp4");
|
|
612
|
-
const response = yield fetch(transcribeAudioUrl, {
|
|
613
|
-
method: "POST",
|
|
614
|
-
body: formData
|
|
615
|
-
});
|
|
616
|
-
if (!response.ok) {
|
|
617
|
-
throw new Error(`Error: ${response.statusText}`);
|
|
618
|
-
}
|
|
619
|
-
const transcription = yield response.json();
|
|
620
|
-
return transcription.text;
|
|
621
|
-
});
|
|
622
|
-
var playAudioResponse = (text, textToSpeechUrl, audioContext) => {
|
|
623
|
-
const encodedText = encodeURIComponent(text);
|
|
624
|
-
const url = `${textToSpeechUrl}?text=${encodedText}`;
|
|
625
|
-
fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer)).then((audioBuffer) => {
|
|
626
|
-
const source = audioContext.createBufferSource();
|
|
627
|
-
source.buffer = audioBuffer;
|
|
628
|
-
source.connect(audioContext.destination);
|
|
629
|
-
source.start(0);
|
|
630
|
-
}).catch((error) => {
|
|
631
|
-
console.error("Error with decoding audio data", error);
|
|
632
|
-
});
|
|
633
|
-
};
|
|
634
|
-
var usePushToTalk = ({
|
|
635
|
-
sendFunction,
|
|
636
|
-
inProgress
|
|
637
|
-
}) => {
|
|
638
|
-
const [pushToTalkState, setPushToTalkState] = (0, import_react4.useState)("idle");
|
|
639
|
-
const mediaStreamRef = (0, import_react4.useRef)(null);
|
|
640
|
-
const audioContextRef = (0, import_react4.useRef)(null);
|
|
641
|
-
const mediaRecorderRef = (0, import_react4.useRef)(null);
|
|
642
|
-
const recordedChunks = (0, import_react4.useRef)([]);
|
|
643
|
-
const generalContext = (0, import_react_core2.useCopilotContext)();
|
|
644
|
-
const messagesContext = (0, import_react_core2.useCopilotMessagesContext)();
|
|
645
|
-
const context = __spreadValues(__spreadValues({}, generalContext), messagesContext);
|
|
646
|
-
const [startReadingFromMessageId, setStartReadingFromMessageId] = (0, import_react4.useState)(null);
|
|
647
|
-
(0, import_react4.useEffect)(() => {
|
|
648
|
-
if (pushToTalkState === "recording") {
|
|
649
|
-
startRecording(
|
|
650
|
-
mediaStreamRef,
|
|
651
|
-
mediaRecorderRef,
|
|
652
|
-
audioContextRef,
|
|
653
|
-
recordedChunks.current,
|
|
654
|
-
() => {
|
|
655
|
-
setPushToTalkState("transcribing");
|
|
656
|
-
}
|
|
657
|
-
);
|
|
658
|
-
} else {
|
|
659
|
-
stopRecording(mediaRecorderRef);
|
|
660
|
-
if (pushToTalkState === "transcribing") {
|
|
661
|
-
transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl).then(
|
|
662
|
-
(transcription) => __async(void 0, null, function* () {
|
|
663
|
-
recordedChunks.current = [];
|
|
664
|
-
setPushToTalkState("idle");
|
|
665
|
-
const message = yield sendFunction(transcription);
|
|
666
|
-
setStartReadingFromMessageId(message.id);
|
|
667
|
-
})
|
|
668
|
-
);
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
return () => {
|
|
672
|
-
stopRecording(mediaRecorderRef);
|
|
673
|
-
};
|
|
674
|
-
}, [pushToTalkState]);
|
|
675
|
-
(0, import_react4.useEffect)(() => {
|
|
676
|
-
if (inProgress === false && startReadingFromMessageId) {
|
|
677
|
-
const lastMessageIndex = context.messages.findIndex(
|
|
678
|
-
(message) => message.id === startReadingFromMessageId
|
|
679
|
-
);
|
|
680
|
-
const aguiMessages = (0, import_runtime_client_gql.gqlToAGUI)(context.messages);
|
|
681
|
-
const messagesAfterLast = aguiMessages.slice(lastMessageIndex + 1).filter((message) => message.role === "assistant");
|
|
682
|
-
const text = messagesAfterLast.map((message) => message.content).join("\n");
|
|
683
|
-
playAudioResponse(text, context.copilotApiConfig.textToSpeechUrl, audioContextRef.current);
|
|
684
|
-
setStartReadingFromMessageId(null);
|
|
685
|
-
}
|
|
686
|
-
}, [startReadingFromMessageId, inProgress]);
|
|
687
|
-
return { pushToTalkState, setPushToTalkState };
|
|
688
|
-
};
|
|
689
|
-
|
|
690
|
-
// src/components/chat/Input.tsx
|
|
691
|
-
var import_react_core3 = require("@copilotkit/react-core");
|
|
692
|
-
|
|
693
|
-
// src/hooks/use-dark-mode.ts
|
|
694
|
-
var useDarkMode = () => {
|
|
695
|
-
if (typeof window === "undefined")
|
|
696
|
-
return false;
|
|
697
|
-
return document.documentElement.classList.contains("dark") || document.body.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark" || document.body.getAttribute("data-theme") === "dark" || window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
698
|
-
};
|
|
699
|
-
|
|
700
|
-
// src/components/chat/PoweredByTag.tsx
|
|
701
|
-
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
702
|
-
function PoweredByTag({ showPoweredBy = true }) {
|
|
703
|
-
const isDark = useDarkMode();
|
|
704
|
-
if (!showPoweredBy) {
|
|
705
|
-
return null;
|
|
706
|
-
}
|
|
707
|
-
const poweredByStyle = {
|
|
708
|
-
visibility: "visible",
|
|
709
|
-
display: "block",
|
|
710
|
-
position: "static",
|
|
711
|
-
textAlign: "center",
|
|
712
|
-
fontSize: "12px",
|
|
713
|
-
padding: "3px 0",
|
|
714
|
-
color: isDark ? "rgb(69, 69, 69)" : "rgb(214, 214, 214)"
|
|
715
|
-
};
|
|
716
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "poweredBy", style: poweredByStyle, children: "Powered by CopilotKit" }) });
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
// src/components/chat/Input.tsx
|
|
720
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
721
|
-
var MAX_NEWLINES = 6;
|
|
722
|
-
var Input = ({
|
|
723
|
-
inProgress,
|
|
724
|
-
onSend,
|
|
725
|
-
isVisible = false,
|
|
726
|
-
onStop,
|
|
727
|
-
onUpload,
|
|
728
|
-
hideStopButton = false
|
|
729
|
-
}) => {
|
|
730
|
-
var _a, _b;
|
|
731
|
-
const context = useChatContext();
|
|
732
|
-
const copilotContext = (0, import_react_core3.useCopilotContext)();
|
|
733
|
-
const showPoweredBy = !((_a = copilotContext.copilotApiConfig) == null ? void 0 : _a.publicApiKey);
|
|
734
|
-
const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0;
|
|
735
|
-
const textareaRef = (0, import_react5.useRef)(null);
|
|
736
|
-
const [isComposing, setIsComposing] = (0, import_react5.useState)(false);
|
|
737
|
-
const handleDivClick = (event) => {
|
|
738
|
-
var _a2;
|
|
739
|
-
const target = event.target;
|
|
740
|
-
if (target.closest("button"))
|
|
741
|
-
return;
|
|
742
|
-
if (target.tagName === "TEXTAREA")
|
|
743
|
-
return;
|
|
744
|
-
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
745
|
-
};
|
|
746
|
-
const [text, setText] = (0, import_react5.useState)("");
|
|
747
|
-
const send = () => {
|
|
748
|
-
var _a2;
|
|
749
|
-
if (inProgress)
|
|
750
|
-
return;
|
|
751
|
-
onSend(text);
|
|
752
|
-
setText("");
|
|
753
|
-
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
754
|
-
};
|
|
755
|
-
const { pushToTalkState, setPushToTalkState } = usePushToTalk({
|
|
756
|
-
sendFunction: onSend,
|
|
757
|
-
inProgress
|
|
758
|
-
});
|
|
759
|
-
const isInProgress = inProgress || pushToTalkState === "transcribing";
|
|
760
|
-
const buttonIcon = isInProgress && !hideStopButton ? context.icons.stopIcon : context.icons.sendIcon;
|
|
761
|
-
const showPushToTalk = pushToTalkConfigured && (pushToTalkState === "idle" || pushToTalkState === "recording") && !inProgress;
|
|
762
|
-
const canSend = (0, import_react5.useMemo)(() => {
|
|
763
|
-
var _a2;
|
|
764
|
-
const interruptEvent = (_a2 = copilotContext.langGraphInterruptAction) == null ? void 0 : _a2.event;
|
|
765
|
-
const interruptInProgress = (interruptEvent == null ? void 0 : interruptEvent.name) === "LangGraphInterruptEvent" && !(interruptEvent == null ? void 0 : interruptEvent.response);
|
|
766
|
-
return !isInProgress && text.trim().length > 0 && pushToTalkState === "idle" && !interruptInProgress;
|
|
767
|
-
}, [(_b = copilotContext.langGraphInterruptAction) == null ? void 0 : _b.event, isInProgress, text, pushToTalkState]);
|
|
768
|
-
const canStop = (0, import_react5.useMemo)(() => {
|
|
769
|
-
return isInProgress && !hideStopButton;
|
|
770
|
-
}, [isInProgress, hideStopButton]);
|
|
771
|
-
const sendDisabled = !canSend && !canStop;
|
|
772
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `copilotKitInputContainer ${showPoweredBy ? "poweredByContainer" : ""}`, children: [
|
|
773
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
|
|
774
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
775
|
-
Textarea_default,
|
|
776
|
-
{
|
|
777
|
-
ref: textareaRef,
|
|
778
|
-
placeholder: context.labels.placeholder,
|
|
779
|
-
autoFocus: false,
|
|
780
|
-
maxRows: MAX_NEWLINES,
|
|
781
|
-
value: text,
|
|
782
|
-
onChange: (event) => setText(event.target.value),
|
|
783
|
-
onCompositionStart: () => setIsComposing(true),
|
|
784
|
-
onCompositionEnd: () => setIsComposing(false),
|
|
785
|
-
onKeyDown: (event) => {
|
|
786
|
-
if (event.key === "Enter" && !event.shiftKey && !isComposing) {
|
|
787
|
-
event.preventDefault();
|
|
788
|
-
if (canSend) {
|
|
789
|
-
send();
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
),
|
|
795
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "copilotKitInputControls", children: [
|
|
796
|
-
onUpload && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: onUpload, className: "copilotKitInputControlButton", children: context.icons.uploadIcon }),
|
|
797
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flexGrow: 1 } }),
|
|
798
|
-
showPushToTalk && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
799
|
-
"button",
|
|
800
|
-
{
|
|
801
|
-
onClick: () => setPushToTalkState(pushToTalkState === "idle" ? "recording" : "transcribing"),
|
|
802
|
-
className: pushToTalkState === "recording" ? "copilotKitInputControlButton copilotKitPushToTalkRecording" : "copilotKitInputControlButton",
|
|
803
|
-
children: context.icons.pushToTalkIcon
|
|
804
|
-
}
|
|
805
|
-
),
|
|
806
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
807
|
-
"button",
|
|
808
|
-
{
|
|
809
|
-
disabled: sendDisabled,
|
|
810
|
-
onClick: isInProgress && !hideStopButton ? onStop : send,
|
|
811
|
-
"data-copilotkit-in-progress": inProgress,
|
|
812
|
-
"data-test-id": inProgress ? "copilot-chat-request-in-progress" : "copilot-chat-ready",
|
|
813
|
-
className: "copilotKitInputControlButton",
|
|
814
|
-
children: buttonIcon
|
|
815
|
-
}
|
|
816
|
-
)
|
|
817
|
-
] })
|
|
818
|
-
] }),
|
|
819
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PoweredByTag, { showPoweredBy })
|
|
820
|
-
] });
|
|
821
|
-
};
|
|
822
|
-
|
|
823
|
-
// src/components/chat/messages/UserMessage.tsx
|
|
824
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
825
|
-
var UserMessage = (props) => {
|
|
826
|
-
const { message, ImageRenderer: ImageRenderer2 } = props;
|
|
827
|
-
const isImageMessage = message && "image" in message && message.image;
|
|
828
|
-
if (isImageMessage) {
|
|
829
|
-
const imageMessage = message;
|
|
830
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ImageRenderer2, { image: imageMessage.image, content: imageMessage.content }) });
|
|
831
|
-
}
|
|
832
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: message == null ? void 0 : message.content });
|
|
833
|
-
};
|
|
834
|
-
|
|
835
|
-
// src/components/chat/Markdown.tsx
|
|
836
|
-
var import_react7 = require("react");
|
|
837
|
-
var import_react_markdown = __toESM(require("react-markdown"));
|
|
838
|
-
|
|
839
|
-
// src/components/chat/CodeBlock.tsx
|
|
840
|
-
var import_react6 = require("react");
|
|
841
|
-
var import_react_syntax_highlighter = require("react-syntax-highlighter");
|
|
842
|
-
|
|
843
|
-
// src/hooks/use-copy-to-clipboard.tsx
|
|
844
|
-
var React4 = __toESM(require("react"));
|
|
845
|
-
function useCopyToClipboard({ timeout = 2e3 }) {
|
|
846
|
-
const [isCopied, setIsCopied] = React4.useState(false);
|
|
847
|
-
const copyToClipboard = (value) => {
|
|
848
|
-
var _a;
|
|
849
|
-
if (typeof window === "undefined" || !((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) {
|
|
850
|
-
return;
|
|
851
|
-
}
|
|
852
|
-
if (!value) {
|
|
853
|
-
return;
|
|
854
|
-
}
|
|
855
|
-
navigator.clipboard.writeText(value).then(() => {
|
|
856
|
-
setIsCopied(true);
|
|
857
|
-
setTimeout(() => {
|
|
858
|
-
setIsCopied(false);
|
|
859
|
-
}, timeout);
|
|
860
|
-
});
|
|
861
|
-
};
|
|
862
|
-
return { isCopied, copyToClipboard };
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
// src/components/chat/CodeBlock.tsx
|
|
866
|
-
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
867
|
-
var programmingLanguages = {
|
|
868
|
-
javascript: ".js",
|
|
869
|
-
python: ".py",
|
|
870
|
-
java: ".java",
|
|
871
|
-
c: ".c",
|
|
872
|
-
cpp: ".cpp",
|
|
873
|
-
"c++": ".cpp",
|
|
874
|
-
"c#": ".cs",
|
|
875
|
-
ruby: ".rb",
|
|
876
|
-
php: ".php",
|
|
877
|
-
swift: ".swift",
|
|
878
|
-
"objective-c": ".m",
|
|
879
|
-
kotlin: ".kt",
|
|
880
|
-
typescript: ".ts",
|
|
881
|
-
go: ".go",
|
|
882
|
-
perl: ".pl",
|
|
883
|
-
rust: ".rs",
|
|
884
|
-
scala: ".scala",
|
|
885
|
-
haskell: ".hs",
|
|
886
|
-
lua: ".lua",
|
|
887
|
-
shell: ".sh",
|
|
888
|
-
sql: ".sql",
|
|
889
|
-
html: ".html",
|
|
890
|
-
css: ".css"
|
|
891
|
-
// add more file extensions here, make sure the key is same as language prop in CodeBlock.tsx component
|
|
892
|
-
};
|
|
893
|
-
var generateRandomString = (length, lowercase = false) => {
|
|
894
|
-
const chars = "ABCDEFGHJKLMNPQRSTUVWXY3456789";
|
|
895
|
-
let result = "";
|
|
896
|
-
for (let i = 0; i < length; i++) {
|
|
897
|
-
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
898
|
-
}
|
|
899
|
-
return lowercase ? result.toLowerCase() : result;
|
|
900
|
-
};
|
|
901
|
-
var CodeBlock = (0, import_react6.memo)(({ language, value }) => {
|
|
902
|
-
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2e3 });
|
|
903
|
-
const downloadAsFile = () => {
|
|
904
|
-
if (typeof window === "undefined") {
|
|
905
|
-
return;
|
|
906
|
-
}
|
|
907
|
-
const fileExtension = programmingLanguages[language] || ".file";
|
|
908
|
-
const suggestedFileName = `file-${generateRandomString(3, true)}${fileExtension}`;
|
|
909
|
-
const fileName = window.prompt("Enter file name", suggestedFileName);
|
|
910
|
-
if (!fileName) {
|
|
911
|
-
return;
|
|
912
|
-
}
|
|
913
|
-
const blob = new Blob([value], { type: "text/plain" });
|
|
914
|
-
const url = URL.createObjectURL(blob);
|
|
915
|
-
const link = document.createElement("a");
|
|
916
|
-
link.download = fileName;
|
|
917
|
-
link.href = url;
|
|
918
|
-
link.style.display = "none";
|
|
919
|
-
document.body.appendChild(link);
|
|
920
|
-
link.click();
|
|
921
|
-
document.body.removeChild(link);
|
|
922
|
-
URL.revokeObjectURL(url);
|
|
923
|
-
};
|
|
924
|
-
const onCopy = () => {
|
|
925
|
-
if (isCopied)
|
|
926
|
-
return;
|
|
927
|
-
copyToClipboard(value);
|
|
928
|
-
};
|
|
929
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "copilotKitCodeBlock", children: [
|
|
930
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "copilotKitCodeBlockToolbar", children: [
|
|
931
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "copilotKitCodeBlockToolbarLanguage", children: language }),
|
|
932
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "copilotKitCodeBlockToolbarButtons", children: [
|
|
933
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: downloadAsFile, children: DownloadIcon }),
|
|
934
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: onCopy, children: isCopied ? CheckIcon : CopyIcon })
|
|
935
|
-
] })
|
|
936
|
-
] }),
|
|
937
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
938
|
-
import_react_syntax_highlighter.Prism,
|
|
939
|
-
{
|
|
940
|
-
language,
|
|
941
|
-
style: highlightStyle,
|
|
942
|
-
PreTag: "div",
|
|
943
|
-
customStyle: {
|
|
944
|
-
margin: 0,
|
|
945
|
-
borderBottomLeftRadius: "0.375rem",
|
|
946
|
-
borderBottomRightRadius: "0.375rem"
|
|
947
|
-
},
|
|
948
|
-
children: value
|
|
949
|
-
}
|
|
950
|
-
)
|
|
528
|
+
)
|
|
951
529
|
] });
|
|
952
530
|
});
|
|
953
531
|
CodeBlock.displayName = "CodeBlock";
|
|
@@ -1232,308 +810,887 @@ var highlightStyle = {
|
|
|
1232
810
|
boxShadow: "inset 5px 0 0 #f7d87c",
|
|
1233
811
|
zIndex: "0"
|
|
1234
812
|
}
|
|
1235
|
-
};
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
// src/components/chat/Markdown.tsx
|
|
816
|
+
var import_remark_gfm = __toESM(require("remark-gfm"));
|
|
817
|
+
var import_remark_math = __toESM(require("remark-math"));
|
|
818
|
+
var import_rehype_raw = __toESM(require("rehype-raw"));
|
|
819
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
820
|
+
var defaultComponents = {
|
|
821
|
+
a(_a) {
|
|
822
|
+
var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
|
|
823
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { target: "_blank", rel: "noopener noreferrer", children }));
|
|
824
|
+
},
|
|
825
|
+
// @ts-expect-error -- inline
|
|
826
|
+
code(_c) {
|
|
827
|
+
var _d = _c, { children, className, inline } = _d, props = __objRest(_d, ["children", "className", "inline"]);
|
|
828
|
+
if (Array.isArray(children) && children.length) {
|
|
829
|
+
if (children[0] == "\u258D") {
|
|
830
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
831
|
+
"span",
|
|
832
|
+
{
|
|
833
|
+
style: {
|
|
834
|
+
animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
|
|
835
|
+
marginTop: "0.25rem"
|
|
836
|
+
},
|
|
837
|
+
children: "\u258D"
|
|
838
|
+
}
|
|
839
|
+
);
|
|
840
|
+
}
|
|
841
|
+
children[0] = (children == null ? void 0 : children[0]).replace("`\u258D`", "\u258D");
|
|
842
|
+
}
|
|
843
|
+
const match = /language-(\w+)/.exec(className || "");
|
|
844
|
+
const hasLanguage = match && match[1];
|
|
845
|
+
const content = String(children);
|
|
846
|
+
const hasNewlines = content.includes("\n");
|
|
847
|
+
const isInline = !hasLanguage && !hasNewlines;
|
|
848
|
+
if (isInline) {
|
|
849
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
850
|
+
"code",
|
|
851
|
+
__spreadProps(__spreadValues({
|
|
852
|
+
className: `copilotKitMarkdownElement copilotKitInlineCode ${className || ""}`
|
|
853
|
+
}, props), {
|
|
854
|
+
children
|
|
855
|
+
})
|
|
856
|
+
);
|
|
857
|
+
}
|
|
858
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
859
|
+
CodeBlock,
|
|
860
|
+
__spreadValues({
|
|
861
|
+
language: match && match[1] || "",
|
|
862
|
+
value: String(children).replace(/\n$/, "")
|
|
863
|
+
}, props),
|
|
864
|
+
Math.random()
|
|
865
|
+
);
|
|
866
|
+
},
|
|
867
|
+
h1: (_e) => {
|
|
868
|
+
var _f = _e, { children } = _f, props = __objRest(_f, ["children"]);
|
|
869
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h1", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
870
|
+
},
|
|
871
|
+
h2: (_g) => {
|
|
872
|
+
var _h = _g, { children } = _h, props = __objRest(_h, ["children"]);
|
|
873
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
874
|
+
},
|
|
875
|
+
h3: (_i) => {
|
|
876
|
+
var _j = _i, { children } = _j, props = __objRest(_j, ["children"]);
|
|
877
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
878
|
+
},
|
|
879
|
+
h4: (_k) => {
|
|
880
|
+
var _l = _k, { children } = _l, props = __objRest(_l, ["children"]);
|
|
881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h4", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
882
|
+
},
|
|
883
|
+
h5: (_m) => {
|
|
884
|
+
var _n = _m, { children } = _n, props = __objRest(_n, ["children"]);
|
|
885
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h5", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
886
|
+
},
|
|
887
|
+
h6: (_o) => {
|
|
888
|
+
var _p = _o, { children } = _p, props = __objRest(_p, ["children"]);
|
|
889
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h6", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
890
|
+
},
|
|
891
|
+
p: (_q) => {
|
|
892
|
+
var _r = _q, { children } = _r, props = __objRest(_r, ["children"]);
|
|
893
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
894
|
+
},
|
|
895
|
+
pre: (_s) => {
|
|
896
|
+
var _t = _s, { children } = _t, props = __objRest(_t, ["children"]);
|
|
897
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("pre", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
898
|
+
},
|
|
899
|
+
blockquote: (_u) => {
|
|
900
|
+
var _v = _u, { children } = _v, props = __objRest(_v, ["children"]);
|
|
901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("blockquote", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
902
|
+
},
|
|
903
|
+
ul: (_w) => {
|
|
904
|
+
var _x = _w, { children } = _x, props = __objRest(_x, ["children"]);
|
|
905
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
906
|
+
},
|
|
907
|
+
li: (_y) => {
|
|
908
|
+
var _z = _y, { children } = _z, props = __objRest(_z, ["children"]);
|
|
909
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
910
|
+
}
|
|
911
|
+
};
|
|
912
|
+
var MemoizedReactMarkdown = (0, import_react3.memo)(
|
|
913
|
+
import_react_markdown.default,
|
|
914
|
+
(prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.components === nextProps.components
|
|
915
|
+
);
|
|
916
|
+
var Markdown = ({ content, components }) => {
|
|
917
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "copilotKitMarkdown", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
918
|
+
MemoizedReactMarkdown,
|
|
919
|
+
{
|
|
920
|
+
components: __spreadValues(__spreadValues({}, defaultComponents), components),
|
|
921
|
+
remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
|
|
922
|
+
rehypePlugins: [import_rehype_raw.default],
|
|
923
|
+
children: content
|
|
924
|
+
}
|
|
925
|
+
) });
|
|
926
|
+
};
|
|
927
|
+
|
|
928
|
+
// src/components/chat/messages/AssistantMessage.tsx
|
|
929
|
+
var import_react4 = require("react");
|
|
930
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
931
|
+
var AssistantMessage = (props) => {
|
|
932
|
+
var _a;
|
|
933
|
+
const { icons, labels } = useChatContext();
|
|
934
|
+
const {
|
|
935
|
+
message,
|
|
936
|
+
isLoading,
|
|
937
|
+
onRegenerate,
|
|
938
|
+
onCopy,
|
|
939
|
+
onThumbsUp,
|
|
940
|
+
onThumbsDown,
|
|
941
|
+
isCurrentMessage,
|
|
942
|
+
markdownTagRenderers
|
|
943
|
+
} = props;
|
|
944
|
+
const [copied, setCopied] = (0, import_react4.useState)(false);
|
|
945
|
+
const handleCopy = () => {
|
|
946
|
+
const content2 = (message == null ? void 0 : message.content) || "";
|
|
947
|
+
if (content2 && onCopy) {
|
|
948
|
+
navigator.clipboard.writeText(content2);
|
|
949
|
+
setCopied(true);
|
|
950
|
+
onCopy(content2);
|
|
951
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
952
|
+
} else if (content2) {
|
|
953
|
+
navigator.clipboard.writeText(content2);
|
|
954
|
+
setCopied(true);
|
|
955
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
const handleRegenerate = () => {
|
|
959
|
+
if (onRegenerate)
|
|
960
|
+
onRegenerate();
|
|
961
|
+
};
|
|
962
|
+
const handleThumbsUp = () => {
|
|
963
|
+
if (onThumbsUp && message)
|
|
964
|
+
onThumbsUp(message);
|
|
965
|
+
};
|
|
966
|
+
const handleThumbsDown = () => {
|
|
967
|
+
if (onThumbsDown && message)
|
|
968
|
+
onThumbsDown(message);
|
|
969
|
+
};
|
|
970
|
+
const LoadingIcon = () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: icons.activityIcon });
|
|
971
|
+
const content = (message == null ? void 0 : message.content) || "";
|
|
972
|
+
const subComponent = (_a = message == null ? void 0 : message.generativeUI) == null ? void 0 : _a.call(message);
|
|
973
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
974
|
+
content && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "copilotKitMessage copilotKitAssistantMessage", children: [
|
|
975
|
+
content && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Markdown, { content, components: markdownTagRenderers }),
|
|
976
|
+
content && !isLoading && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
977
|
+
"div",
|
|
978
|
+
{
|
|
979
|
+
className: `copilotKitMessageControls ${isCurrentMessage ? "currentMessage" : ""}`,
|
|
980
|
+
children: [
|
|
981
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
982
|
+
"button",
|
|
983
|
+
{
|
|
984
|
+
className: "copilotKitMessageControlButton",
|
|
985
|
+
onClick: handleRegenerate,
|
|
986
|
+
"aria-label": labels.regenerateResponse,
|
|
987
|
+
title: labels.regenerateResponse,
|
|
988
|
+
children: icons.regenerateIcon
|
|
989
|
+
}
|
|
990
|
+
),
|
|
991
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
992
|
+
"button",
|
|
993
|
+
{
|
|
994
|
+
className: "copilotKitMessageControlButton",
|
|
995
|
+
onClick: handleCopy,
|
|
996
|
+
"aria-label": labels.copyToClipboard,
|
|
997
|
+
title: labels.copyToClipboard,
|
|
998
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { fontSize: "10px", fontWeight: "bold" }, children: "\u2713" }) : icons.copyIcon
|
|
999
|
+
}
|
|
1000
|
+
),
|
|
1001
|
+
onThumbsUp && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1002
|
+
"button",
|
|
1003
|
+
{
|
|
1004
|
+
className: "copilotKitMessageControlButton",
|
|
1005
|
+
onClick: handleThumbsUp,
|
|
1006
|
+
"aria-label": labels.thumbsUp,
|
|
1007
|
+
title: labels.thumbsUp,
|
|
1008
|
+
children: icons.thumbsUpIcon
|
|
1009
|
+
}
|
|
1010
|
+
),
|
|
1011
|
+
onThumbsDown && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1012
|
+
"button",
|
|
1013
|
+
{
|
|
1014
|
+
className: "copilotKitMessageControlButton",
|
|
1015
|
+
onClick: handleThumbsDown,
|
|
1016
|
+
"aria-label": labels.thumbsDown,
|
|
1017
|
+
title: labels.thumbsDown,
|
|
1018
|
+
children: icons.thumbsDownIcon
|
|
1019
|
+
}
|
|
1020
|
+
)
|
|
1021
|
+
]
|
|
1022
|
+
}
|
|
1023
|
+
)
|
|
1024
|
+
] }),
|
|
1025
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { marginBottom: "0.5rem" }, children: subComponent }),
|
|
1026
|
+
isLoading && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(LoadingIcon, {})
|
|
1027
|
+
] });
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
// src/components/chat/messages/ImageRenderer.tsx
|
|
1031
|
+
var import_react5 = require("react");
|
|
1032
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1033
|
+
var ImageRenderer = ({ image, content, className = "" }) => {
|
|
1034
|
+
const [imageError, setImageError] = (0, import_react5.useState)(false);
|
|
1035
|
+
const imageSrc = `data:image/${image.format};base64,${image.bytes}`;
|
|
1036
|
+
const altText = content || "User uploaded image";
|
|
1037
|
+
const handleImageError = () => {
|
|
1038
|
+
setImageError(true);
|
|
1039
|
+
};
|
|
1040
|
+
if (imageError) {
|
|
1041
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `copilotKitImageRendering copilotKitImageRenderingError ${className}`, children: [
|
|
1042
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "copilotKitImageRenderingErrorMessage", children: "Failed to load image" }),
|
|
1043
|
+
content && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "copilotKitImageRenderingContent", children: content })
|
|
1044
|
+
] });
|
|
1045
|
+
}
|
|
1046
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `copilotKitImageRendering ${className}`, children: [
|
|
1047
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1048
|
+
"img",
|
|
1049
|
+
{
|
|
1050
|
+
src: imageSrc,
|
|
1051
|
+
alt: altText,
|
|
1052
|
+
className: "copilotKitImageRenderingImage",
|
|
1053
|
+
onError: handleImageError
|
|
1054
|
+
}
|
|
1055
|
+
),
|
|
1056
|
+
content && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "copilotKitImageRenderingContent", children: content })
|
|
1057
|
+
] });
|
|
1058
|
+
};
|
|
1059
|
+
|
|
1060
|
+
// src/components/chat/messages/RenderMessage.tsx
|
|
1061
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1062
|
+
function RenderMessage(_a) {
|
|
1063
|
+
var _b = _a, {
|
|
1064
|
+
UserMessage: UserMessage2 = UserMessage,
|
|
1065
|
+
AssistantMessage: AssistantMessage2 = AssistantMessage,
|
|
1066
|
+
ImageRenderer: ImageRenderer2 = ImageRenderer
|
|
1067
|
+
} = _b, props = __objRest(_b, [
|
|
1068
|
+
"UserMessage",
|
|
1069
|
+
"AssistantMessage",
|
|
1070
|
+
"ImageRenderer"
|
|
1071
|
+
]);
|
|
1072
|
+
var _a2;
|
|
1073
|
+
const {
|
|
1074
|
+
message,
|
|
1075
|
+
inProgress,
|
|
1076
|
+
index,
|
|
1077
|
+
isCurrentMessage,
|
|
1078
|
+
onRegenerate,
|
|
1079
|
+
onCopy,
|
|
1080
|
+
onThumbsUp,
|
|
1081
|
+
onThumbsDown,
|
|
1082
|
+
markdownTagRenderers
|
|
1083
|
+
} = props;
|
|
1084
|
+
switch (message.role) {
|
|
1085
|
+
case "user":
|
|
1086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1087
|
+
UserMessage2,
|
|
1088
|
+
{
|
|
1089
|
+
rawData: message,
|
|
1090
|
+
"data-message-role": "user",
|
|
1091
|
+
message,
|
|
1092
|
+
ImageRenderer: ImageRenderer2
|
|
1093
|
+
},
|
|
1094
|
+
index
|
|
1095
|
+
);
|
|
1096
|
+
case "assistant":
|
|
1097
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1098
|
+
AssistantMessage2,
|
|
1099
|
+
{
|
|
1100
|
+
"data-message-role": "assistant",
|
|
1101
|
+
subComponent: (_a2 = message.generativeUI) == null ? void 0 : _a2.call(message),
|
|
1102
|
+
rawData: message,
|
|
1103
|
+
message,
|
|
1104
|
+
isLoading: inProgress && isCurrentMessage && !message.content,
|
|
1105
|
+
isGenerating: inProgress && isCurrentMessage && !!message.content,
|
|
1106
|
+
isCurrentMessage,
|
|
1107
|
+
onRegenerate: () => onRegenerate == null ? void 0 : onRegenerate(message.id),
|
|
1108
|
+
onCopy,
|
|
1109
|
+
onThumbsUp,
|
|
1110
|
+
onThumbsDown,
|
|
1111
|
+
markdownTagRenderers,
|
|
1112
|
+
ImageRenderer: ImageRenderer2
|
|
1113
|
+
},
|
|
1114
|
+
index
|
|
1115
|
+
);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
// src/components/chat/messages/LegacyRenderMessage.tsx
|
|
1120
|
+
var import_runtime_client_gql = require("@copilotkit/runtime-client-gql");
|
|
1121
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1122
|
+
var LegacyRenderMessage = ({
|
|
1123
|
+
message,
|
|
1124
|
+
inProgress,
|
|
1125
|
+
index,
|
|
1126
|
+
isCurrentMessage,
|
|
1127
|
+
actionResult,
|
|
1128
|
+
AssistantMessage: AssistantMessage2,
|
|
1129
|
+
UserMessage: UserMessage2,
|
|
1130
|
+
ImageRenderer: ImageRenderer2,
|
|
1131
|
+
onRegenerate,
|
|
1132
|
+
onCopy,
|
|
1133
|
+
onThumbsUp,
|
|
1134
|
+
onThumbsDown,
|
|
1135
|
+
markdownTagRenderers,
|
|
1136
|
+
legacyProps
|
|
1137
|
+
}) => {
|
|
1138
|
+
var _a;
|
|
1139
|
+
const {
|
|
1140
|
+
RenderTextMessage,
|
|
1141
|
+
RenderActionExecutionMessage,
|
|
1142
|
+
RenderAgentStateMessage,
|
|
1143
|
+
RenderResultMessage,
|
|
1144
|
+
RenderImageMessage
|
|
1145
|
+
} = legacyProps;
|
|
1146
|
+
const deprecatedMessage = (_a = (0, import_runtime_client_gql.aguiToGQL)(message)[0]) != null ? _a : void 0;
|
|
1147
|
+
if (deprecatedMessage.isTextMessage() && RenderTextMessage) {
|
|
1148
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1149
|
+
RenderTextMessage,
|
|
1150
|
+
{
|
|
1151
|
+
message,
|
|
1152
|
+
inProgress,
|
|
1153
|
+
index,
|
|
1154
|
+
isCurrentMessage,
|
|
1155
|
+
AssistantMessage: AssistantMessage2,
|
|
1156
|
+
UserMessage: UserMessage2,
|
|
1157
|
+
onRegenerate,
|
|
1158
|
+
onCopy,
|
|
1159
|
+
onThumbsUp,
|
|
1160
|
+
onThumbsDown,
|
|
1161
|
+
markdownTagRenderers
|
|
1162
|
+
}
|
|
1163
|
+
);
|
|
1164
|
+
}
|
|
1165
|
+
if (deprecatedMessage.isActionExecutionMessage() && RenderActionExecutionMessage) {
|
|
1166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1167
|
+
RenderActionExecutionMessage,
|
|
1168
|
+
{
|
|
1169
|
+
message,
|
|
1170
|
+
inProgress,
|
|
1171
|
+
index,
|
|
1172
|
+
isCurrentMessage,
|
|
1173
|
+
actionResult,
|
|
1174
|
+
AssistantMessage: AssistantMessage2,
|
|
1175
|
+
UserMessage: UserMessage2
|
|
1176
|
+
}
|
|
1177
|
+
);
|
|
1178
|
+
}
|
|
1179
|
+
if (deprecatedMessage.isAgentStateMessage() && RenderAgentStateMessage) {
|
|
1180
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1181
|
+
RenderAgentStateMessage,
|
|
1182
|
+
{
|
|
1183
|
+
message,
|
|
1184
|
+
inProgress,
|
|
1185
|
+
index,
|
|
1186
|
+
isCurrentMessage,
|
|
1187
|
+
AssistantMessage: AssistantMessage2,
|
|
1188
|
+
UserMessage: UserMessage2
|
|
1189
|
+
}
|
|
1190
|
+
);
|
|
1191
|
+
}
|
|
1192
|
+
if (deprecatedMessage.isResultMessage() && RenderResultMessage) {
|
|
1193
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1194
|
+
RenderResultMessage,
|
|
1195
|
+
{
|
|
1196
|
+
message,
|
|
1197
|
+
inProgress,
|
|
1198
|
+
index,
|
|
1199
|
+
isCurrentMessage,
|
|
1200
|
+
AssistantMessage: AssistantMessage2,
|
|
1201
|
+
UserMessage: UserMessage2
|
|
1202
|
+
}
|
|
1203
|
+
);
|
|
1204
|
+
}
|
|
1205
|
+
if (deprecatedMessage.isImageMessage() && RenderImageMessage) {
|
|
1206
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1207
|
+
RenderImageMessage,
|
|
1208
|
+
{
|
|
1209
|
+
message,
|
|
1210
|
+
inProgress,
|
|
1211
|
+
index,
|
|
1212
|
+
isCurrentMessage,
|
|
1213
|
+
AssistantMessage: AssistantMessage2,
|
|
1214
|
+
UserMessage: UserMessage2
|
|
1215
|
+
}
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1219
|
+
RenderMessage,
|
|
1220
|
+
{
|
|
1221
|
+
message,
|
|
1222
|
+
inProgress,
|
|
1223
|
+
index,
|
|
1224
|
+
isCurrentMessage,
|
|
1225
|
+
AssistantMessage: AssistantMessage2,
|
|
1226
|
+
UserMessage: UserMessage2,
|
|
1227
|
+
ImageRenderer: ImageRenderer2,
|
|
1228
|
+
onRegenerate,
|
|
1229
|
+
onCopy,
|
|
1230
|
+
onThumbsUp,
|
|
1231
|
+
onThumbsDown,
|
|
1232
|
+
markdownTagRenderers
|
|
1233
|
+
}
|
|
1234
|
+
);
|
|
1235
|
+
};
|
|
1236
|
+
|
|
1237
|
+
// src/components/chat/Messages.tsx
|
|
1238
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1239
|
+
var Messages = ({
|
|
1240
|
+
inProgress,
|
|
1241
|
+
children,
|
|
1242
|
+
RenderMessage: RenderMessage2,
|
|
1243
|
+
AssistantMessage: AssistantMessage2,
|
|
1244
|
+
UserMessage: UserMessage2,
|
|
1245
|
+
ImageRenderer: ImageRenderer2,
|
|
1246
|
+
onRegenerate,
|
|
1247
|
+
onCopy,
|
|
1248
|
+
onThumbsUp,
|
|
1249
|
+
onThumbsDown,
|
|
1250
|
+
markdownTagRenderers,
|
|
1251
|
+
// Legacy props
|
|
1252
|
+
RenderTextMessage,
|
|
1253
|
+
RenderActionExecutionMessage,
|
|
1254
|
+
RenderAgentStateMessage,
|
|
1255
|
+
RenderResultMessage,
|
|
1256
|
+
RenderImageMessage
|
|
1257
|
+
}) => {
|
|
1258
|
+
const { labels } = useChatContext();
|
|
1259
|
+
const { messages: visibleMessages, interrupt } = (0, import_react_core.useCopilotChatInternal)();
|
|
1260
|
+
const initialMessages = (0, import_react6.useMemo)(() => makeInitialMessages(labels.initial), [labels.initial]);
|
|
1261
|
+
const messages = [...initialMessages, ...visibleMessages];
|
|
1262
|
+
const { messagesContainerRef, messagesEndRef } = useScrollToBottom(messages);
|
|
1263
|
+
const hasLegacyProps = !!(RenderTextMessage || RenderActionExecutionMessage || RenderAgentStateMessage || RenderResultMessage || RenderImageMessage);
|
|
1264
|
+
(0, import_react6.useEffect)(() => {
|
|
1265
|
+
if (hasLegacyProps) {
|
|
1266
|
+
console.warn(
|
|
1267
|
+
"[CopilotKit] Legacy message render props (RenderTextMessage, RenderActionExecutionMessage, etc.) are deprecated. Please use the unified 'RenderMessage' prop instead. See migration guide: https://docs.copilotkit.ai/migration/render-message"
|
|
1268
|
+
);
|
|
1269
|
+
}
|
|
1270
|
+
}, [hasLegacyProps]);
|
|
1271
|
+
const legacyProps = (0, import_react6.useMemo)(
|
|
1272
|
+
() => ({
|
|
1273
|
+
RenderTextMessage,
|
|
1274
|
+
RenderActionExecutionMessage,
|
|
1275
|
+
RenderAgentStateMessage,
|
|
1276
|
+
RenderResultMessage,
|
|
1277
|
+
RenderImageMessage
|
|
1278
|
+
}),
|
|
1279
|
+
[
|
|
1280
|
+
RenderTextMessage,
|
|
1281
|
+
RenderActionExecutionMessage,
|
|
1282
|
+
RenderAgentStateMessage,
|
|
1283
|
+
RenderResultMessage,
|
|
1284
|
+
RenderImageMessage
|
|
1285
|
+
]
|
|
1286
|
+
);
|
|
1287
|
+
const MessageRenderer = hasLegacyProps ? (props) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LegacyRenderMessage, __spreadProps(__spreadValues({}, props), { legacyProps })) : RenderMessage2;
|
|
1288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitMessages", ref: messagesContainerRef, children: [
|
|
1289
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitMessagesContainer", children: [
|
|
1290
|
+
messages.map((message, index) => {
|
|
1291
|
+
const isCurrentMessage = index === messages.length - 1;
|
|
1292
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1293
|
+
MessageRenderer,
|
|
1294
|
+
{
|
|
1295
|
+
message,
|
|
1296
|
+
inProgress,
|
|
1297
|
+
index,
|
|
1298
|
+
isCurrentMessage,
|
|
1299
|
+
AssistantMessage: AssistantMessage2,
|
|
1300
|
+
UserMessage: UserMessage2,
|
|
1301
|
+
ImageRenderer: ImageRenderer2,
|
|
1302
|
+
onRegenerate,
|
|
1303
|
+
onCopy,
|
|
1304
|
+
onThumbsUp,
|
|
1305
|
+
onThumbsDown,
|
|
1306
|
+
markdownTagRenderers
|
|
1307
|
+
},
|
|
1308
|
+
index
|
|
1309
|
+
);
|
|
1310
|
+
}),
|
|
1311
|
+
interrupt
|
|
1312
|
+
] }),
|
|
1313
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("footer", { className: "copilotKitMessagesFooter", ref: messagesEndRef, children })
|
|
1314
|
+
] });
|
|
1315
|
+
};
|
|
1316
|
+
function makeInitialMessages(initial) {
|
|
1317
|
+
if (!initial)
|
|
1318
|
+
return [];
|
|
1319
|
+
if (Array.isArray(initial)) {
|
|
1320
|
+
return initial.map((message) => {
|
|
1321
|
+
return {
|
|
1322
|
+
id: message,
|
|
1323
|
+
role: "assistant",
|
|
1324
|
+
content: message
|
|
1325
|
+
};
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
return [
|
|
1329
|
+
{
|
|
1330
|
+
id: initial,
|
|
1331
|
+
role: "assistant",
|
|
1332
|
+
content: initial
|
|
1333
|
+
}
|
|
1334
|
+
];
|
|
1335
|
+
}
|
|
1336
|
+
function useScrollToBottom(messages) {
|
|
1337
|
+
const messagesEndRef = (0, import_react6.useRef)(null);
|
|
1338
|
+
const messagesContainerRef = (0, import_react6.useRef)(null);
|
|
1339
|
+
const isProgrammaticScrollRef = (0, import_react6.useRef)(false);
|
|
1340
|
+
const isUserScrollUpRef = (0, import_react6.useRef)(false);
|
|
1341
|
+
const scrollToBottom = () => {
|
|
1342
|
+
if (messagesContainerRef.current && messagesEndRef.current) {
|
|
1343
|
+
isProgrammaticScrollRef.current = true;
|
|
1344
|
+
messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight;
|
|
1345
|
+
}
|
|
1346
|
+
};
|
|
1347
|
+
const handleScroll = () => {
|
|
1348
|
+
if (isProgrammaticScrollRef.current) {
|
|
1349
|
+
isProgrammaticScrollRef.current = false;
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
if (messagesContainerRef.current) {
|
|
1353
|
+
const { scrollTop, scrollHeight, clientHeight } = messagesContainerRef.current;
|
|
1354
|
+
isUserScrollUpRef.current = scrollTop + clientHeight < scrollHeight;
|
|
1355
|
+
}
|
|
1356
|
+
};
|
|
1357
|
+
(0, import_react6.useEffect)(() => {
|
|
1358
|
+
const container = messagesContainerRef.current;
|
|
1359
|
+
if (container) {
|
|
1360
|
+
container.addEventListener("scroll", handleScroll);
|
|
1361
|
+
}
|
|
1362
|
+
return () => {
|
|
1363
|
+
if (container) {
|
|
1364
|
+
container.removeEventListener("scroll", handleScroll);
|
|
1365
|
+
}
|
|
1366
|
+
};
|
|
1367
|
+
}, []);
|
|
1368
|
+
(0, import_react6.useEffect)(() => {
|
|
1369
|
+
const container = messagesContainerRef.current;
|
|
1370
|
+
if (!container) {
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
const mutationObserver = new MutationObserver(() => {
|
|
1374
|
+
if (!isUserScrollUpRef.current) {
|
|
1375
|
+
scrollToBottom();
|
|
1376
|
+
}
|
|
1377
|
+
});
|
|
1378
|
+
mutationObserver.observe(container, {
|
|
1379
|
+
childList: true,
|
|
1380
|
+
subtree: true,
|
|
1381
|
+
characterData: true
|
|
1382
|
+
});
|
|
1383
|
+
return () => {
|
|
1384
|
+
mutationObserver.disconnect();
|
|
1385
|
+
};
|
|
1386
|
+
}, []);
|
|
1387
|
+
(0, import_react6.useEffect)(() => {
|
|
1388
|
+
isUserScrollUpRef.current = false;
|
|
1389
|
+
scrollToBottom();
|
|
1390
|
+
}, [messages.filter((m) => m.role === "user").length]);
|
|
1391
|
+
return { messagesEndRef, messagesContainerRef };
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
// src/components/chat/Input.tsx
|
|
1395
|
+
var import_react9 = require("react");
|
|
1396
|
+
|
|
1397
|
+
// src/components/chat/Textarea.tsx
|
|
1398
|
+
var import_react7 = require("react");
|
|
1399
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1400
|
+
var AutoResizingTextarea = (0, import_react7.forwardRef)(
|
|
1401
|
+
({
|
|
1402
|
+
maxRows = 1,
|
|
1403
|
+
placeholder,
|
|
1404
|
+
value,
|
|
1405
|
+
onChange,
|
|
1406
|
+
onKeyDown,
|
|
1407
|
+
onCompositionStart,
|
|
1408
|
+
onCompositionEnd,
|
|
1409
|
+
autoFocus
|
|
1410
|
+
}, ref) => {
|
|
1411
|
+
const internalTextareaRef = (0, import_react7.useRef)(null);
|
|
1412
|
+
const [maxHeight, setMaxHeight] = (0, import_react7.useState)(0);
|
|
1413
|
+
(0, import_react7.useImperativeHandle)(ref, () => internalTextareaRef.current);
|
|
1414
|
+
(0, import_react7.useEffect)(() => {
|
|
1415
|
+
const calculateMaxHeight = () => {
|
|
1416
|
+
const textarea = internalTextareaRef.current;
|
|
1417
|
+
if (textarea) {
|
|
1418
|
+
textarea.style.height = "auto";
|
|
1419
|
+
const singleRowHeight = textarea.scrollHeight;
|
|
1420
|
+
setMaxHeight(singleRowHeight * maxRows);
|
|
1421
|
+
if (autoFocus) {
|
|
1422
|
+
textarea.focus();
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
};
|
|
1426
|
+
calculateMaxHeight();
|
|
1427
|
+
}, [maxRows]);
|
|
1428
|
+
(0, import_react7.useEffect)(() => {
|
|
1429
|
+
const textarea = internalTextareaRef.current;
|
|
1430
|
+
if (textarea) {
|
|
1431
|
+
textarea.style.height = "auto";
|
|
1432
|
+
textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
|
|
1433
|
+
}
|
|
1434
|
+
}, [value, maxHeight]);
|
|
1435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1436
|
+
"textarea",
|
|
1437
|
+
{
|
|
1438
|
+
ref: internalTextareaRef,
|
|
1439
|
+
value,
|
|
1440
|
+
onChange,
|
|
1441
|
+
onKeyDown,
|
|
1442
|
+
onCompositionStart,
|
|
1443
|
+
onCompositionEnd,
|
|
1444
|
+
placeholder,
|
|
1445
|
+
style: {
|
|
1446
|
+
overflow: "auto",
|
|
1447
|
+
resize: "none",
|
|
1448
|
+
maxHeight: `${maxHeight}px`
|
|
1449
|
+
},
|
|
1450
|
+
rows: 1
|
|
1451
|
+
}
|
|
1452
|
+
);
|
|
1453
|
+
}
|
|
1454
|
+
);
|
|
1455
|
+
var Textarea_default = AutoResizingTextarea;
|
|
1236
1456
|
|
|
1237
|
-
// src/
|
|
1238
|
-
var
|
|
1239
|
-
var
|
|
1240
|
-
var
|
|
1241
|
-
var
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1457
|
+
// src/hooks/use-push-to-talk.tsx
|
|
1458
|
+
var import_react_core2 = require("@copilotkit/react-core");
|
|
1459
|
+
var import_runtime_client_gql2 = require("@copilotkit/runtime-client-gql");
|
|
1460
|
+
var import_react8 = require("react");
|
|
1461
|
+
var startRecording = (mediaStreamRef, mediaRecorderRef, audioContextRef, recordedChunks, onStop) => __async(void 0, null, function* () {
|
|
1462
|
+
if (!mediaStreamRef.current || !audioContextRef.current) {
|
|
1463
|
+
mediaStreamRef.current = yield navigator.mediaDevices.getUserMedia({ audio: true });
|
|
1464
|
+
audioContextRef.current = new window.AudioContext();
|
|
1465
|
+
yield audioContextRef.current.resume();
|
|
1466
|
+
}
|
|
1467
|
+
mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current);
|
|
1468
|
+
mediaRecorderRef.current.start(1e3);
|
|
1469
|
+
mediaRecorderRef.current.ondataavailable = (event) => {
|
|
1470
|
+
recordedChunks.push(event.data);
|
|
1471
|
+
};
|
|
1472
|
+
mediaRecorderRef.current.onstop = onStop;
|
|
1473
|
+
});
|
|
1474
|
+
var stopRecording = (mediaRecorderRef) => {
|
|
1475
|
+
if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
|
|
1476
|
+
mediaRecorderRef.current.stop();
|
|
1477
|
+
}
|
|
1478
|
+
};
|
|
1479
|
+
var transcribeAudio = (recordedChunks, transcribeAudioUrl) => __async(void 0, null, function* () {
|
|
1480
|
+
const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
|
|
1481
|
+
const formData = new FormData();
|
|
1482
|
+
formData.append("file", completeBlob, "recording.mp4");
|
|
1483
|
+
const response = yield fetch(transcribeAudioUrl, {
|
|
1484
|
+
method: "POST",
|
|
1485
|
+
body: formData
|
|
1486
|
+
});
|
|
1487
|
+
if (!response.ok) {
|
|
1488
|
+
throw new Error(`Error: ${response.statusText}`);
|
|
1489
|
+
}
|
|
1490
|
+
const transcription = yield response.json();
|
|
1491
|
+
return transcription.text;
|
|
1492
|
+
});
|
|
1493
|
+
var playAudioResponse = (text, textToSpeechUrl, audioContext) => {
|
|
1494
|
+
const encodedText = encodeURIComponent(text);
|
|
1495
|
+
const url = `${textToSpeechUrl}?text=${encodedText}`;
|
|
1496
|
+
fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer)).then((audioBuffer) => {
|
|
1497
|
+
const source = audioContext.createBufferSource();
|
|
1498
|
+
source.buffer = audioBuffer;
|
|
1499
|
+
source.connect(audioContext.destination);
|
|
1500
|
+
source.start(0);
|
|
1501
|
+
}).catch((error) => {
|
|
1502
|
+
console.error("Error with decoding audio data", error);
|
|
1503
|
+
});
|
|
1504
|
+
};
|
|
1505
|
+
var usePushToTalk = ({
|
|
1506
|
+
sendFunction,
|
|
1507
|
+
inProgress
|
|
1508
|
+
}) => {
|
|
1509
|
+
const [pushToTalkState, setPushToTalkState] = (0, import_react8.useState)("idle");
|
|
1510
|
+
const mediaStreamRef = (0, import_react8.useRef)(null);
|
|
1511
|
+
const audioContextRef = (0, import_react8.useRef)(null);
|
|
1512
|
+
const mediaRecorderRef = (0, import_react8.useRef)(null);
|
|
1513
|
+
const recordedChunks = (0, import_react8.useRef)([]);
|
|
1514
|
+
const generalContext = (0, import_react_core2.useCopilotContext)();
|
|
1515
|
+
const messagesContext = (0, import_react_core2.useCopilotMessagesContext)();
|
|
1516
|
+
const context = __spreadValues(__spreadValues({}, generalContext), messagesContext);
|
|
1517
|
+
const [startReadingFromMessageId, setStartReadingFromMessageId] = (0, import_react8.useState)(null);
|
|
1518
|
+
(0, import_react8.useEffect)(() => {
|
|
1519
|
+
if (pushToTalkState === "recording") {
|
|
1520
|
+
startRecording(
|
|
1521
|
+
mediaStreamRef,
|
|
1522
|
+
mediaRecorderRef,
|
|
1523
|
+
audioContextRef,
|
|
1524
|
+
recordedChunks.current,
|
|
1525
|
+
() => {
|
|
1526
|
+
setPushToTalkState("transcribing");
|
|
1527
|
+
}
|
|
1528
|
+
);
|
|
1529
|
+
} else {
|
|
1530
|
+
stopRecording(mediaRecorderRef);
|
|
1531
|
+
if (pushToTalkState === "transcribing") {
|
|
1532
|
+
transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl).then(
|
|
1533
|
+
(transcription) => __async(void 0, null, function* () {
|
|
1534
|
+
recordedChunks.current = [];
|
|
1535
|
+
setPushToTalkState("idle");
|
|
1536
|
+
const message = yield sendFunction(transcription);
|
|
1537
|
+
setStartReadingFromMessageId(message.id);
|
|
1538
|
+
})
|
|
1261
1539
|
);
|
|
1262
1540
|
}
|
|
1263
|
-
children[0] = (children == null ? void 0 : children[0]).replace("`\u258D`", "\u258D");
|
|
1264
1541
|
}
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
if (
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
__spreadProps(__spreadValues({
|
|
1274
|
-
className: `copilotKitMarkdownElement copilotKitInlineCode ${className || ""}`
|
|
1275
|
-
}, props), {
|
|
1276
|
-
children
|
|
1277
|
-
})
|
|
1542
|
+
return () => {
|
|
1543
|
+
stopRecording(mediaRecorderRef);
|
|
1544
|
+
};
|
|
1545
|
+
}, [pushToTalkState]);
|
|
1546
|
+
(0, import_react8.useEffect)(() => {
|
|
1547
|
+
if (inProgress === false && startReadingFromMessageId) {
|
|
1548
|
+
const lastMessageIndex = context.messages.findIndex(
|
|
1549
|
+
(message) => message.id === startReadingFromMessageId
|
|
1278
1550
|
);
|
|
1551
|
+
const aguiMessages = (0, import_runtime_client_gql2.gqlToAGUI)(context.messages);
|
|
1552
|
+
const messagesAfterLast = aguiMessages.slice(lastMessageIndex + 1).filter((message) => message.role === "assistant");
|
|
1553
|
+
const text = messagesAfterLast.map((message) => message.content).join("\n");
|
|
1554
|
+
playAudioResponse(text, context.copilotApiConfig.textToSpeechUrl, audioContextRef.current);
|
|
1555
|
+
setStartReadingFromMessageId(null);
|
|
1279
1556
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
__spreadValues({
|
|
1283
|
-
language: match && match[1] || "",
|
|
1284
|
-
value: String(children).replace(/\n$/, "")
|
|
1285
|
-
}, props),
|
|
1286
|
-
Math.random()
|
|
1287
|
-
);
|
|
1288
|
-
},
|
|
1289
|
-
h1: (_e) => {
|
|
1290
|
-
var _f = _e, { children } = _f, props = __objRest(_f, ["children"]);
|
|
1291
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h1", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1292
|
-
},
|
|
1293
|
-
h2: (_g) => {
|
|
1294
|
-
var _h = _g, { children } = _h, props = __objRest(_h, ["children"]);
|
|
1295
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h2", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1296
|
-
},
|
|
1297
|
-
h3: (_i) => {
|
|
1298
|
-
var _j = _i, { children } = _j, props = __objRest(_j, ["children"]);
|
|
1299
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1300
|
-
},
|
|
1301
|
-
h4: (_k) => {
|
|
1302
|
-
var _l = _k, { children } = _l, props = __objRest(_l, ["children"]);
|
|
1303
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h4", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1304
|
-
},
|
|
1305
|
-
h5: (_m) => {
|
|
1306
|
-
var _n = _m, { children } = _n, props = __objRest(_n, ["children"]);
|
|
1307
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h5", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1308
|
-
},
|
|
1309
|
-
h6: (_o) => {
|
|
1310
|
-
var _p = _o, { children } = _p, props = __objRest(_p, ["children"]);
|
|
1311
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h6", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1312
|
-
},
|
|
1313
|
-
p: (_q) => {
|
|
1314
|
-
var _r = _q, { children } = _r, props = __objRest(_r, ["children"]);
|
|
1315
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1316
|
-
},
|
|
1317
|
-
pre: (_s) => {
|
|
1318
|
-
var _t = _s, { children } = _t, props = __objRest(_t, ["children"]);
|
|
1319
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("pre", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1320
|
-
},
|
|
1321
|
-
blockquote: (_u) => {
|
|
1322
|
-
var _v = _u, { children } = _v, props = __objRest(_v, ["children"]);
|
|
1323
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("blockquote", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1324
|
-
},
|
|
1325
|
-
ul: (_w) => {
|
|
1326
|
-
var _x = _w, { children } = _x, props = __objRest(_x, ["children"]);
|
|
1327
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1328
|
-
},
|
|
1329
|
-
li: (_y) => {
|
|
1330
|
-
var _z = _y, { children } = _z, props = __objRest(_z, ["children"]);
|
|
1331
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("li", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1332
|
-
}
|
|
1333
|
-
};
|
|
1334
|
-
var MemoizedReactMarkdown = (0, import_react7.memo)(
|
|
1335
|
-
import_react_markdown.default,
|
|
1336
|
-
(prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.components === nextProps.components
|
|
1337
|
-
);
|
|
1338
|
-
var Markdown = ({ content, components }) => {
|
|
1339
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "copilotKitMarkdown", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1340
|
-
MemoizedReactMarkdown,
|
|
1341
|
-
{
|
|
1342
|
-
components: __spreadValues(__spreadValues({}, defaultComponents), components),
|
|
1343
|
-
remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
|
|
1344
|
-
rehypePlugins: [import_rehype_raw.default],
|
|
1345
|
-
children: content
|
|
1346
|
-
}
|
|
1347
|
-
) });
|
|
1557
|
+
}, [startReadingFromMessageId, inProgress]);
|
|
1558
|
+
return { pushToTalkState, setPushToTalkState };
|
|
1348
1559
|
};
|
|
1349
1560
|
|
|
1350
|
-
// src/components/chat/
|
|
1351
|
-
var
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
const
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
navigator.clipboard.writeText(content2);
|
|
1376
|
-
setCopied(true);
|
|
1377
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
1378
|
-
}
|
|
1379
|
-
};
|
|
1380
|
-
const handleRegenerate = () => {
|
|
1381
|
-
if (onRegenerate)
|
|
1382
|
-
onRegenerate();
|
|
1561
|
+
// src/components/chat/Input.tsx
|
|
1562
|
+
var import_react_core3 = require("@copilotkit/react-core");
|
|
1563
|
+
|
|
1564
|
+
// src/hooks/use-dark-mode.ts
|
|
1565
|
+
var useDarkMode = () => {
|
|
1566
|
+
if (typeof window === "undefined")
|
|
1567
|
+
return false;
|
|
1568
|
+
return document.documentElement.classList.contains("dark") || document.body.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark" || document.body.getAttribute("data-theme") === "dark" || window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
1569
|
+
};
|
|
1570
|
+
|
|
1571
|
+
// src/components/chat/PoweredByTag.tsx
|
|
1572
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1573
|
+
function PoweredByTag({ showPoweredBy = true }) {
|
|
1574
|
+
const isDark = useDarkMode();
|
|
1575
|
+
if (!showPoweredBy) {
|
|
1576
|
+
return null;
|
|
1577
|
+
}
|
|
1578
|
+
const poweredByStyle = {
|
|
1579
|
+
visibility: "visible",
|
|
1580
|
+
display: "block",
|
|
1581
|
+
position: "static",
|
|
1582
|
+
textAlign: "center",
|
|
1583
|
+
fontSize: "12px",
|
|
1584
|
+
padding: "3px 0",
|
|
1585
|
+
color: isDark ? "rgb(69, 69, 69)" : "rgb(214, 214, 214)"
|
|
1383
1586
|
};
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1587
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "poweredBy", style: poweredByStyle, children: "Powered by CopilotKit" }) });
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
// src/components/chat/Input.tsx
|
|
1591
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1592
|
+
var MAX_NEWLINES = 6;
|
|
1593
|
+
var Input = ({
|
|
1594
|
+
inProgress,
|
|
1595
|
+
onSend,
|
|
1596
|
+
isVisible = false,
|
|
1597
|
+
onStop,
|
|
1598
|
+
onUpload,
|
|
1599
|
+
hideStopButton = false
|
|
1600
|
+
}) => {
|
|
1601
|
+
var _a, _b;
|
|
1602
|
+
const context = useChatContext();
|
|
1603
|
+
const copilotContext = (0, import_react_core3.useCopilotContext)();
|
|
1604
|
+
const showPoweredBy = !((_a = copilotContext.copilotApiConfig) == null ? void 0 : _a.publicApiKey);
|
|
1605
|
+
const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0;
|
|
1606
|
+
const textareaRef = (0, import_react9.useRef)(null);
|
|
1607
|
+
const [isComposing, setIsComposing] = (0, import_react9.useState)(false);
|
|
1608
|
+
const handleDivClick = (event) => {
|
|
1609
|
+
var _a2;
|
|
1610
|
+
const target = event.target;
|
|
1611
|
+
if (target.closest("button"))
|
|
1612
|
+
return;
|
|
1613
|
+
if (target.tagName === "TEXTAREA")
|
|
1614
|
+
return;
|
|
1615
|
+
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
1387
1616
|
};
|
|
1388
|
-
const
|
|
1389
|
-
|
|
1390
|
-
|
|
1617
|
+
const [text, setText] = (0, import_react9.useState)("");
|
|
1618
|
+
const send = () => {
|
|
1619
|
+
var _a2;
|
|
1620
|
+
if (inProgress)
|
|
1621
|
+
return;
|
|
1622
|
+
onSend(text);
|
|
1623
|
+
setText("");
|
|
1624
|
+
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
1391
1625
|
};
|
|
1392
|
-
const
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1626
|
+
const { pushToTalkState, setPushToTalkState } = usePushToTalk({
|
|
1627
|
+
sendFunction: onSend,
|
|
1628
|
+
inProgress
|
|
1629
|
+
});
|
|
1630
|
+
const isInProgress = inProgress || pushToTalkState === "transcribing";
|
|
1631
|
+
const buttonIcon = isInProgress && !hideStopButton ? context.icons.stopIcon : context.icons.sendIcon;
|
|
1632
|
+
const showPushToTalk = pushToTalkConfigured && (pushToTalkState === "idle" || pushToTalkState === "recording") && !inProgress;
|
|
1633
|
+
const canSend = (0, import_react9.useMemo)(() => {
|
|
1634
|
+
var _a2;
|
|
1635
|
+
const interruptEvent = (_a2 = copilotContext.langGraphInterruptAction) == null ? void 0 : _a2.event;
|
|
1636
|
+
const interruptInProgress = (interruptEvent == null ? void 0 : interruptEvent.name) === "LangGraphInterruptEvent" && !(interruptEvent == null ? void 0 : interruptEvent.response);
|
|
1637
|
+
return !isInProgress && text.trim().length > 0 && pushToTalkState === "idle" && !interruptInProgress;
|
|
1638
|
+
}, [(_b = copilotContext.langGraphInterruptAction) == null ? void 0 : _b.event, isInProgress, text, pushToTalkState]);
|
|
1639
|
+
const canStop = (0, import_react9.useMemo)(() => {
|
|
1640
|
+
return isInProgress && !hideStopButton;
|
|
1641
|
+
}, [isInProgress, hideStopButton]);
|
|
1642
|
+
const sendDisabled = !canSend && !canStop;
|
|
1643
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `copilotKitInputContainer ${showPoweredBy ? "poweredByContainer" : ""}`, children: [
|
|
1644
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
|
|
1645
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1646
|
+
Textarea_default,
|
|
1400
1647
|
{
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
"button",
|
|
1415
|
-
{
|
|
1416
|
-
className: "copilotKitMessageControlButton",
|
|
1417
|
-
onClick: handleCopy,
|
|
1418
|
-
"aria-label": labels.copyToClipboard,
|
|
1419
|
-
title: labels.copyToClipboard,
|
|
1420
|
-
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { fontSize: "10px", fontWeight: "bold" }, children: "\u2713" }) : icons.copyIcon
|
|
1421
|
-
}
|
|
1422
|
-
),
|
|
1423
|
-
onThumbsUp && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1424
|
-
"button",
|
|
1425
|
-
{
|
|
1426
|
-
className: "copilotKitMessageControlButton",
|
|
1427
|
-
onClick: handleThumbsUp,
|
|
1428
|
-
"aria-label": labels.thumbsUp,
|
|
1429
|
-
title: labels.thumbsUp,
|
|
1430
|
-
children: icons.thumbsUpIcon
|
|
1431
|
-
}
|
|
1432
|
-
),
|
|
1433
|
-
onThumbsDown && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1434
|
-
"button",
|
|
1435
|
-
{
|
|
1436
|
-
className: "copilotKitMessageControlButton",
|
|
1437
|
-
onClick: handleThumbsDown,
|
|
1438
|
-
"aria-label": labels.thumbsDown,
|
|
1439
|
-
title: labels.thumbsDown,
|
|
1440
|
-
children: icons.thumbsDownIcon
|
|
1648
|
+
ref: textareaRef,
|
|
1649
|
+
placeholder: context.labels.placeholder,
|
|
1650
|
+
autoFocus: false,
|
|
1651
|
+
maxRows: MAX_NEWLINES,
|
|
1652
|
+
value: text,
|
|
1653
|
+
onChange: (event) => setText(event.target.value),
|
|
1654
|
+
onCompositionStart: () => setIsComposing(true),
|
|
1655
|
+
onCompositionEnd: () => setIsComposing(false),
|
|
1656
|
+
onKeyDown: (event) => {
|
|
1657
|
+
if (event.key === "Enter" && !event.shiftKey && !isComposing) {
|
|
1658
|
+
event.preventDefault();
|
|
1659
|
+
if (canSend) {
|
|
1660
|
+
send();
|
|
1441
1661
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1444
1664
|
}
|
|
1445
|
-
)
|
|
1665
|
+
),
|
|
1666
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "copilotKitInputControls", children: [
|
|
1667
|
+
onUpload && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { onClick: onUpload, className: "copilotKitInputControlButton", children: context.icons.uploadIcon }),
|
|
1668
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { flexGrow: 1 } }),
|
|
1669
|
+
showPushToTalk && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1670
|
+
"button",
|
|
1671
|
+
{
|
|
1672
|
+
onClick: () => setPushToTalkState(pushToTalkState === "idle" ? "recording" : "transcribing"),
|
|
1673
|
+
className: pushToTalkState === "recording" ? "copilotKitInputControlButton copilotKitPushToTalkRecording" : "copilotKitInputControlButton",
|
|
1674
|
+
children: context.icons.pushToTalkIcon
|
|
1675
|
+
}
|
|
1676
|
+
),
|
|
1677
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1678
|
+
"button",
|
|
1679
|
+
{
|
|
1680
|
+
disabled: sendDisabled,
|
|
1681
|
+
onClick: isInProgress && !hideStopButton ? onStop : send,
|
|
1682
|
+
"data-copilotkit-in-progress": inProgress,
|
|
1683
|
+
"data-test-id": inProgress ? "copilot-chat-request-in-progress" : "copilot-chat-ready",
|
|
1684
|
+
className: "copilotKitInputControlButton",
|
|
1685
|
+
children: buttonIcon
|
|
1686
|
+
}
|
|
1687
|
+
)
|
|
1688
|
+
] })
|
|
1446
1689
|
] }),
|
|
1447
|
-
/* @__PURE__ */ (0,
|
|
1448
|
-
isLoading && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LoadingIcon, {})
|
|
1449
|
-
] });
|
|
1450
|
-
};
|
|
1451
|
-
|
|
1452
|
-
// src/components/chat/messages/ImageRenderer.tsx
|
|
1453
|
-
var import_react9 = require("react");
|
|
1454
|
-
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1455
|
-
var ImageRenderer = ({ image, content, className = "" }) => {
|
|
1456
|
-
const [imageError, setImageError] = (0, import_react9.useState)(false);
|
|
1457
|
-
const imageSrc = `data:image/${image.format};base64,${image.bytes}`;
|
|
1458
|
-
const altText = content || "User uploaded image";
|
|
1459
|
-
const handleImageError = () => {
|
|
1460
|
-
setImageError(true);
|
|
1461
|
-
};
|
|
1462
|
-
if (imageError) {
|
|
1463
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `copilotKitImageRendering copilotKitImageRenderingError ${className}`, children: [
|
|
1464
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "copilotKitImageRenderingErrorMessage", children: "Failed to load image" }),
|
|
1465
|
-
content && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "copilotKitImageRenderingContent", children: content })
|
|
1466
|
-
] });
|
|
1467
|
-
}
|
|
1468
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `copilotKitImageRendering ${className}`, children: [
|
|
1469
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1470
|
-
"img",
|
|
1471
|
-
{
|
|
1472
|
-
src: imageSrc,
|
|
1473
|
-
alt: altText,
|
|
1474
|
-
className: "copilotKitImageRenderingImage",
|
|
1475
|
-
onError: handleImageError
|
|
1476
|
-
}
|
|
1477
|
-
),
|
|
1478
|
-
content && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "copilotKitImageRenderingContent", children: content })
|
|
1690
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PoweredByTag, { showPoweredBy })
|
|
1479
1691
|
] });
|
|
1480
1692
|
};
|
|
1481
1693
|
|
|
1482
|
-
// src/components/chat/messages/RenderMessage.tsx
|
|
1483
|
-
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1484
|
-
function RenderMessage(_a) {
|
|
1485
|
-
var _b = _a, {
|
|
1486
|
-
UserMessage: UserMessage2 = UserMessage,
|
|
1487
|
-
AssistantMessage: AssistantMessage2 = AssistantMessage,
|
|
1488
|
-
ImageRenderer: ImageRenderer2 = ImageRenderer
|
|
1489
|
-
} = _b, props = __objRest(_b, [
|
|
1490
|
-
"UserMessage",
|
|
1491
|
-
"AssistantMessage",
|
|
1492
|
-
"ImageRenderer"
|
|
1493
|
-
]);
|
|
1494
|
-
const {
|
|
1495
|
-
message,
|
|
1496
|
-
inProgress,
|
|
1497
|
-
index,
|
|
1498
|
-
isCurrentMessage,
|
|
1499
|
-
onRegenerate,
|
|
1500
|
-
onCopy,
|
|
1501
|
-
onThumbsUp,
|
|
1502
|
-
onThumbsDown,
|
|
1503
|
-
markdownTagRenderers
|
|
1504
|
-
} = props;
|
|
1505
|
-
switch (message.role) {
|
|
1506
|
-
case "user":
|
|
1507
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1508
|
-
UserMessage2,
|
|
1509
|
-
{
|
|
1510
|
-
"data-message-role": "user",
|
|
1511
|
-
message,
|
|
1512
|
-
ImageRenderer: ImageRenderer2
|
|
1513
|
-
},
|
|
1514
|
-
index
|
|
1515
|
-
);
|
|
1516
|
-
case "assistant":
|
|
1517
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1518
|
-
AssistantMessage2,
|
|
1519
|
-
{
|
|
1520
|
-
"data-message-role": "assistant",
|
|
1521
|
-
message,
|
|
1522
|
-
isLoading: inProgress && isCurrentMessage && !message.content,
|
|
1523
|
-
isGenerating: inProgress && isCurrentMessage && !!message.content,
|
|
1524
|
-
isCurrentMessage,
|
|
1525
|
-
onRegenerate: () => onRegenerate == null ? void 0 : onRegenerate(message.id),
|
|
1526
|
-
onCopy,
|
|
1527
|
-
onThumbsUp,
|
|
1528
|
-
onThumbsDown,
|
|
1529
|
-
markdownTagRenderers,
|
|
1530
|
-
ImageRenderer: ImageRenderer2
|
|
1531
|
-
},
|
|
1532
|
-
index
|
|
1533
|
-
);
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
|
|
1537
1694
|
// src/components/chat/Chat.tsx
|
|
1538
1695
|
var import_react10 = __toESM(require("react"));
|
|
1539
1696
|
var import_react_core5 = require("@copilotkit/react-core");
|
|
@@ -1542,7 +1699,7 @@ var import_shared2 = require("@copilotkit/shared");
|
|
|
1542
1699
|
var import_react_core6 = require("@copilotkit/react-core");
|
|
1543
1700
|
|
|
1544
1701
|
// src/components/chat/ImageUploadQueue.tsx
|
|
1545
|
-
var
|
|
1702
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1546
1703
|
var ImageUploadQueue = ({
|
|
1547
1704
|
images,
|
|
1548
1705
|
onRemoveImage,
|
|
@@ -1550,7 +1707,7 @@ var ImageUploadQueue = ({
|
|
|
1550
1707
|
}) => {
|
|
1551
1708
|
if (images.length === 0)
|
|
1552
1709
|
return null;
|
|
1553
|
-
return /* @__PURE__ */ (0,
|
|
1710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1554
1711
|
"div",
|
|
1555
1712
|
{
|
|
1556
1713
|
className: `copilotKitImageUploadQueue ${className}`,
|
|
@@ -1561,7 +1718,7 @@ var ImageUploadQueue = ({
|
|
|
1561
1718
|
margin: "8px",
|
|
1562
1719
|
padding: "8px"
|
|
1563
1720
|
},
|
|
1564
|
-
children: images.map((image, index) => /* @__PURE__ */ (0,
|
|
1721
|
+
children: images.map((image, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1565
1722
|
"div",
|
|
1566
1723
|
{
|
|
1567
1724
|
className: "copilotKitImageUploadQueueItem",
|
|
@@ -1574,7 +1731,7 @@ var ImageUploadQueue = ({
|
|
|
1574
1731
|
overflow: "hidden"
|
|
1575
1732
|
},
|
|
1576
1733
|
children: [
|
|
1577
|
-
/* @__PURE__ */ (0,
|
|
1734
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1578
1735
|
"img",
|
|
1579
1736
|
{
|
|
1580
1737
|
src: `data:${image.contentType};base64,${image.bytes}`,
|
|
@@ -1586,7 +1743,7 @@ var ImageUploadQueue = ({
|
|
|
1586
1743
|
}
|
|
1587
1744
|
}
|
|
1588
1745
|
),
|
|
1589
|
-
/* @__PURE__ */ (0,
|
|
1746
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1590
1747
|
"button",
|
|
1591
1748
|
{
|
|
1592
1749
|
onClick: () => onRemoveImage(index),
|
|
@@ -1621,12 +1778,12 @@ var ImageUploadQueue = ({
|
|
|
1621
1778
|
|
|
1622
1779
|
// src/components/chat/Suggestion.tsx
|
|
1623
1780
|
var import_react_core4 = require("@copilotkit/react-core");
|
|
1624
|
-
var
|
|
1781
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1625
1782
|
function Suggestion({ title, onClick, partial, className }) {
|
|
1626
1783
|
if (!title)
|
|
1627
1784
|
return null;
|
|
1628
1785
|
const { isLoading } = (0, import_react_core4.useCopilotChatInternal)();
|
|
1629
|
-
return /* @__PURE__ */ (0,
|
|
1786
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1630
1787
|
"button",
|
|
1631
1788
|
{
|
|
1632
1789
|
disabled: partial || isLoading,
|
|
@@ -1636,15 +1793,15 @@ function Suggestion({ title, onClick, partial, className }) {
|
|
|
1636
1793
|
},
|
|
1637
1794
|
className: className || (partial ? "suggestion loading" : "suggestion"),
|
|
1638
1795
|
"data-test-id": "suggestion",
|
|
1639
|
-
children: partial ? SmallSpinnerIcon : /* @__PURE__ */ (0,
|
|
1796
|
+
children: partial ? SmallSpinnerIcon : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: title })
|
|
1640
1797
|
}
|
|
1641
1798
|
);
|
|
1642
1799
|
}
|
|
1643
1800
|
|
|
1644
1801
|
// src/components/chat/Suggestions.tsx
|
|
1645
|
-
var
|
|
1802
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1646
1803
|
function Suggestions({ suggestions, onSuggestionClick }) {
|
|
1647
|
-
return /* @__PURE__ */ (0,
|
|
1804
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "suggestions", children: suggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1648
1805
|
Suggestion,
|
|
1649
1806
|
{
|
|
1650
1807
|
title: suggestion.title,
|
|
@@ -1658,7 +1815,7 @@ function Suggestions({ suggestions, onSuggestionClick }) {
|
|
|
1658
1815
|
}
|
|
1659
1816
|
|
|
1660
1817
|
// src/components/chat/Chat.tsx
|
|
1661
|
-
var
|
|
1818
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1662
1819
|
function CopilotChat({
|
|
1663
1820
|
instructions,
|
|
1664
1821
|
suggestions = "auto",
|
|
@@ -1685,17 +1842,26 @@ function CopilotChat({
|
|
|
1685
1842
|
imageUploadsEnabled,
|
|
1686
1843
|
inputFileAccept = "image/*",
|
|
1687
1844
|
hideStopButton,
|
|
1688
|
-
observabilityHooks
|
|
1845
|
+
observabilityHooks,
|
|
1846
|
+
renderError,
|
|
1847
|
+
// Legacy props - deprecated
|
|
1848
|
+
RenderTextMessage,
|
|
1849
|
+
RenderActionExecutionMessage,
|
|
1850
|
+
RenderAgentStateMessage,
|
|
1851
|
+
RenderResultMessage,
|
|
1852
|
+
RenderImageMessage
|
|
1689
1853
|
}) {
|
|
1690
1854
|
const { additionalInstructions, setChatInstructions, copilotApiConfig, setBannerError } = (0, import_react_core5.useCopilotContext)();
|
|
1855
|
+
const { publicApiKey, chatApiEndpoint } = copilotApiConfig;
|
|
1691
1856
|
const [selectedImages, setSelectedImages] = (0, import_react10.useState)([]);
|
|
1857
|
+
const [chatError, setChatError] = (0, import_react10.useState)(null);
|
|
1692
1858
|
const fileInputRef = (0, import_react10.useRef)(null);
|
|
1693
1859
|
const triggerObservabilityHook = (0, import_react10.useCallback)(
|
|
1694
1860
|
(hookName, ...args) => {
|
|
1695
|
-
if (
|
|
1861
|
+
if (publicApiKey && (observabilityHooks == null ? void 0 : observabilityHooks[hookName])) {
|
|
1696
1862
|
observabilityHooks[hookName](...args);
|
|
1697
1863
|
}
|
|
1698
|
-
if ((observabilityHooks == null ? void 0 : observabilityHooks[hookName]) && !
|
|
1864
|
+
if ((observabilityHooks == null ? void 0 : observabilityHooks[hookName]) && !publicApiKey) {
|
|
1699
1865
|
setBannerError(
|
|
1700
1866
|
new import_shared.CopilotKitError({
|
|
1701
1867
|
message: "observabilityHooks requires a publicApiKey to function.",
|
|
@@ -1707,7 +1873,50 @@ function CopilotChat({
|
|
|
1707
1873
|
import_shared.styledConsole.publicApiKeyRequired("observabilityHooks");
|
|
1708
1874
|
}
|
|
1709
1875
|
},
|
|
1710
|
-
[
|
|
1876
|
+
[publicApiKey, observabilityHooks, setBannerError]
|
|
1877
|
+
);
|
|
1878
|
+
const triggerChatError = (0, import_react10.useCallback)(
|
|
1879
|
+
(error, operation, originalError) => {
|
|
1880
|
+
const errorMessage = (error == null ? void 0 : error.message) || (error == null ? void 0 : error.toString()) || "An error occurred";
|
|
1881
|
+
setChatError({
|
|
1882
|
+
message: errorMessage,
|
|
1883
|
+
operation,
|
|
1884
|
+
timestamp: Date.now()
|
|
1885
|
+
});
|
|
1886
|
+
if (publicApiKey && (observabilityHooks == null ? void 0 : observabilityHooks.onError)) {
|
|
1887
|
+
const errorEvent = {
|
|
1888
|
+
type: "error",
|
|
1889
|
+
timestamp: Date.now(),
|
|
1890
|
+
context: {
|
|
1891
|
+
source: "ui",
|
|
1892
|
+
request: {
|
|
1893
|
+
operation,
|
|
1894
|
+
url: chatApiEndpoint,
|
|
1895
|
+
startTime: Date.now()
|
|
1896
|
+
},
|
|
1897
|
+
technical: {
|
|
1898
|
+
environment: "browser",
|
|
1899
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0,
|
|
1900
|
+
stackTrace: originalError instanceof Error ? originalError.stack : void 0
|
|
1901
|
+
}
|
|
1902
|
+
},
|
|
1903
|
+
error
|
|
1904
|
+
};
|
|
1905
|
+
observabilityHooks.onError(errorEvent);
|
|
1906
|
+
}
|
|
1907
|
+
if ((observabilityHooks == null ? void 0 : observabilityHooks.onError) && !publicApiKey) {
|
|
1908
|
+
setBannerError(
|
|
1909
|
+
new import_shared.CopilotKitError({
|
|
1910
|
+
message: "observabilityHooks.onError requires a publicApiKey to function.",
|
|
1911
|
+
code: import_shared.CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR,
|
|
1912
|
+
severity: import_shared.Severity.CRITICAL,
|
|
1913
|
+
visibility: import_shared.ErrorVisibility.BANNER
|
|
1914
|
+
})
|
|
1915
|
+
);
|
|
1916
|
+
import_shared.styledConsole.publicApiKeyRequired("observabilityHooks.onError");
|
|
1917
|
+
}
|
|
1918
|
+
},
|
|
1919
|
+
[publicApiKey, chatApiEndpoint, observabilityHooks, setBannerError]
|
|
1711
1920
|
);
|
|
1712
1921
|
(0, import_react10.useEffect)(() => {
|
|
1713
1922
|
if (!imageUploadsEnabled)
|
|
@@ -1748,12 +1957,13 @@ function CopilotChat({
|
|
|
1748
1957
|
const loadedImages = (yield Promise.all(imagePromises)).filter((img) => img !== null);
|
|
1749
1958
|
setSelectedImages((prev) => [...prev, ...loadedImages]);
|
|
1750
1959
|
} catch (error) {
|
|
1960
|
+
triggerChatError(error, "processClipboardImages", error);
|
|
1751
1961
|
console.error("Error processing pasted images:", error);
|
|
1752
1962
|
}
|
|
1753
1963
|
});
|
|
1754
1964
|
document.addEventListener("paste", handlePaste);
|
|
1755
1965
|
return () => document.removeEventListener("paste", handlePaste);
|
|
1756
|
-
}, [imageUploadsEnabled]);
|
|
1966
|
+
}, [imageUploadsEnabled, triggerChatError]);
|
|
1757
1967
|
(0, import_react10.useEffect)(() => {
|
|
1758
1968
|
if (!(additionalInstructions == null ? void 0 : additionalInstructions.length)) {
|
|
1759
1969
|
setChatInstructions(instructions || "");
|
|
@@ -1767,7 +1977,7 @@ function CopilotChat({
|
|
|
1767
1977
|
setChatInstructions(combinedAdditionalInstructions.join("\n") || "");
|
|
1768
1978
|
}, [instructions, additionalInstructions]);
|
|
1769
1979
|
const {
|
|
1770
|
-
|
|
1980
|
+
messages,
|
|
1771
1981
|
isLoading,
|
|
1772
1982
|
sendMessage,
|
|
1773
1983
|
stopGeneration,
|
|
@@ -1844,6 +2054,7 @@ function CopilotChat({
|
|
|
1844
2054
|
const loadedImages = yield Promise.all(fileReadPromises);
|
|
1845
2055
|
setSelectedImages((prev) => [...prev, ...loadedImages]);
|
|
1846
2056
|
} catch (error) {
|
|
2057
|
+
triggerChatError(error, "processUploadedImages", error);
|
|
1847
2058
|
console.error("Error reading files:", error);
|
|
1848
2059
|
}
|
|
1849
2060
|
});
|
|
@@ -1862,14 +2073,20 @@ function CopilotChat({
|
|
|
1862
2073
|
}
|
|
1863
2074
|
triggerObservabilityHook("onFeedbackGiven", message.id, "thumbsDown");
|
|
1864
2075
|
};
|
|
1865
|
-
return /* @__PURE__ */ (0,
|
|
1866
|
-
|
|
2076
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(WrappedCopilotChat, { icons, labels, className, children: [
|
|
2077
|
+
chatError && renderError && renderError(__spreadProps(__spreadValues({}, chatError), {
|
|
2078
|
+
onDismiss: () => setChatError(null),
|
|
2079
|
+
onRetry: () => {
|
|
2080
|
+
setChatError(null);
|
|
2081
|
+
}
|
|
2082
|
+
})),
|
|
2083
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1867
2084
|
Messages2,
|
|
1868
2085
|
{
|
|
1869
2086
|
AssistantMessage: AssistantMessage2,
|
|
1870
2087
|
UserMessage: UserMessage2,
|
|
1871
2088
|
RenderMessage: RenderMessage2,
|
|
1872
|
-
messages
|
|
2089
|
+
messages,
|
|
1873
2090
|
inProgress: isLoading,
|
|
1874
2091
|
onRegenerate: handleRegenerate,
|
|
1875
2092
|
onCopy: handleCopy,
|
|
@@ -1877,7 +2094,12 @@ function CopilotChat({
|
|
|
1877
2094
|
onThumbsDown: handleThumbsDown,
|
|
1878
2095
|
markdownTagRenderers,
|
|
1879
2096
|
ImageRenderer: ImageRenderer2,
|
|
1880
|
-
|
|
2097
|
+
RenderTextMessage,
|
|
2098
|
+
RenderActionExecutionMessage,
|
|
2099
|
+
RenderAgentStateMessage,
|
|
2100
|
+
RenderResultMessage,
|
|
2101
|
+
RenderImageMessage,
|
|
2102
|
+
children: currentSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1881
2103
|
RenderSuggestionsList,
|
|
1882
2104
|
{
|
|
1883
2105
|
onSuggestionClick: handleSendMessage,
|
|
@@ -1886,9 +2108,9 @@ function CopilotChat({
|
|
|
1886
2108
|
)
|
|
1887
2109
|
}
|
|
1888
2110
|
),
|
|
1889
|
-
imageUploadsEnabled && /* @__PURE__ */ (0,
|
|
1890
|
-
/* @__PURE__ */ (0,
|
|
1891
|
-
/* @__PURE__ */ (0,
|
|
2111
|
+
imageUploadsEnabled && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
2112
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ImageUploadQueue, { images: selectedImages, onRemoveImage: removeSelectedImage }),
|
|
2113
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1892
2114
|
"input",
|
|
1893
2115
|
{
|
|
1894
2116
|
type: "file",
|
|
@@ -1900,7 +2122,7 @@ function CopilotChat({
|
|
|
1900
2122
|
}
|
|
1901
2123
|
)
|
|
1902
2124
|
] }),
|
|
1903
|
-
/* @__PURE__ */ (0,
|
|
2125
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1904
2126
|
Input2,
|
|
1905
2127
|
{
|
|
1906
2128
|
inProgress: isLoading,
|
|
@@ -1924,16 +2146,16 @@ function WrappedCopilotChat({
|
|
|
1924
2146
|
}) {
|
|
1925
2147
|
const chatContext = import_react10.default.useContext(ChatContext);
|
|
1926
2148
|
if (!chatContext) {
|
|
1927
|
-
return /* @__PURE__ */ (0,
|
|
1928
|
-
}, children: /* @__PURE__ */ (0,
|
|
2149
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChatContextProvider, { icons, labels, open: true, setOpen: () => {
|
|
2150
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: `copilotKitChat ${className != null ? className : ""}`, children }) });
|
|
1929
2151
|
}
|
|
1930
|
-
return /* @__PURE__ */ (0,
|
|
2152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children });
|
|
1931
2153
|
}
|
|
1932
2154
|
var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onSubmitMessage, onStopGeneration, onReloadMessages) => {
|
|
1933
2155
|
var _a;
|
|
1934
2156
|
const {
|
|
1935
|
-
|
|
1936
|
-
|
|
2157
|
+
messages,
|
|
2158
|
+
sendMessage,
|
|
1937
2159
|
setMessages,
|
|
1938
2160
|
reloadMessages: defaultReloadMessages,
|
|
1939
2161
|
stopGeneration: defaultStopGeneration,
|
|
@@ -1979,12 +2201,12 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
1979
2201
|
if (Object.keys(generalContext.chatSuggestionConfiguration).length === 0) {
|
|
1980
2202
|
return;
|
|
1981
2203
|
}
|
|
1982
|
-
if (
|
|
2204
|
+
if (messages.length === 0 && !hasGeneratedInitialSuggestions.current) {
|
|
1983
2205
|
hasGeneratedInitialSuggestions.current = true;
|
|
1984
2206
|
generateSuggestionsWithErrorHandling("initial");
|
|
1985
2207
|
return;
|
|
1986
2208
|
}
|
|
1987
|
-
if (
|
|
2209
|
+
if (messages.length > 0 && suggestions.length === 0) {
|
|
1988
2210
|
generateSuggestionsWithErrorHandling("post-message");
|
|
1989
2211
|
return;
|
|
1990
2212
|
}
|
|
@@ -1992,7 +2214,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
1992
2214
|
chatSuggestions,
|
|
1993
2215
|
isLoadingSuggestions,
|
|
1994
2216
|
suggestionsFailed,
|
|
1995
|
-
|
|
2217
|
+
messages.length,
|
|
1996
2218
|
isLoading,
|
|
1997
2219
|
suggestions.length,
|
|
1998
2220
|
Object.keys(generalContext.chatSuggestionConfiguration).join(","),
|
|
@@ -2022,7 +2244,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2022
2244
|
(0, import_react10.useEffect)(() => {
|
|
2023
2245
|
onInProgress == null ? void 0 : onInProgress(isLoading);
|
|
2024
2246
|
}, [onInProgress, isLoading]);
|
|
2025
|
-
const
|
|
2247
|
+
const safelySendMessage = (messageContent, imagesToUse) => __async(void 0, null, function* () {
|
|
2026
2248
|
const images = imagesToUse || [];
|
|
2027
2249
|
if (chatSuggestions === "auto" || chatSuggestions === "manual") {
|
|
2028
2250
|
setSuggestions([]);
|
|
@@ -2041,7 +2263,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2041
2263
|
console.error("Error in onSubmitMessage:", error);
|
|
2042
2264
|
}
|
|
2043
2265
|
}
|
|
2044
|
-
yield
|
|
2266
|
+
yield sendMessage(textMessage, {
|
|
2045
2267
|
followUp: images.length === 0,
|
|
2046
2268
|
clearSuggestions: chatSuggestions === "auto" || chatSuggestions === "manual"
|
|
2047
2269
|
});
|
|
@@ -2059,7 +2281,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2059
2281
|
bytes: images[i].bytes
|
|
2060
2282
|
}
|
|
2061
2283
|
};
|
|
2062
|
-
yield
|
|
2284
|
+
yield sendMessage(imageMessage, { followUp: i === images.length - 1 });
|
|
2063
2285
|
if (!firstMessage) {
|
|
2064
2286
|
firstMessage = imageMessage;
|
|
2065
2287
|
}
|
|
@@ -2070,7 +2292,6 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2070
2292
|
}
|
|
2071
2293
|
return firstMessage;
|
|
2072
2294
|
});
|
|
2073
|
-
const messages = visibleMessages;
|
|
2074
2295
|
const currentAgentName = (_a = generalContext.agentSession) == null ? void 0 : _a.agentName;
|
|
2075
2296
|
const restartCurrentAgent = (hint) => __async(void 0, null, function* () {
|
|
2076
2297
|
if (generalContext.agentSession) {
|
|
@@ -2095,9 +2316,8 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2095
2316
|
generalContext.agentSession.agentName,
|
|
2096
2317
|
stableContext,
|
|
2097
2318
|
messagesContext.messages,
|
|
2098
|
-
|
|
2099
|
-
runChatCompletion
|
|
2100
|
-
hint
|
|
2319
|
+
sendMessage,
|
|
2320
|
+
runChatCompletion
|
|
2101
2321
|
);
|
|
2102
2322
|
}
|
|
2103
2323
|
});
|
|
@@ -2153,10 +2373,9 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2153
2373
|
}
|
|
2154
2374
|
return {
|
|
2155
2375
|
messages,
|
|
2156
|
-
visibleMessages,
|
|
2157
2376
|
isLoading,
|
|
2158
2377
|
suggestions,
|
|
2159
|
-
sendMessage,
|
|
2378
|
+
sendMessage: safelySendMessage,
|
|
2160
2379
|
stopGeneration,
|
|
2161
2380
|
reloadMessages,
|
|
2162
2381
|
resetSuggestions,
|