@copilotkit/react-ui 1.10.0-next.9 → 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.
Files changed (60) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/dist/{chunk-U5ATIGWH.mjs → chunk-BJHJBS5M.mjs} +45 -5
  3. package/dist/chunk-BJHJBS5M.mjs.map +1 -0
  4. package/dist/{chunk-TW4LLLTE.mjs → chunk-GBP47ONN.mjs} +2 -2
  5. package/dist/{chunk-2KG77MAY.mjs → chunk-GJ4SX4JE.mjs} +38 -29
  6. package/dist/chunk-GJ4SX4JE.mjs.map +1 -0
  7. package/dist/{chunk-6C3YVF5W.mjs → chunk-J5ZZR6YB.mjs} +2 -2
  8. package/dist/chunk-MIVUCSGO.mjs +126 -0
  9. package/dist/chunk-MIVUCSGO.mjs.map +1 -0
  10. package/dist/{chunk-JHUTTP5C.mjs → chunk-T5QU6KSB.mjs} +5 -1
  11. package/dist/chunk-T5QU6KSB.mjs.map +1 -0
  12. package/dist/{chunk-7K2X77PW.mjs → chunk-Y44VLEUH.mjs} +8 -8
  13. package/dist/components/chat/Chat.d.ts +21 -2
  14. package/dist/components/chat/Chat.js +1022 -856
  15. package/dist/components/chat/Chat.js.map +1 -1
  16. package/dist/components/chat/Chat.mjs +7 -6
  17. package/dist/components/chat/Messages.d.ts +1 -1
  18. package/dist/components/chat/Messages.js +984 -23
  19. package/dist/components/chat/Messages.js.map +1 -1
  20. package/dist/components/chat/Messages.mjs +9 -1
  21. package/dist/components/chat/Modal.js +1030 -864
  22. package/dist/components/chat/Modal.js.map +1 -1
  23. package/dist/components/chat/Modal.mjs +8 -7
  24. package/dist/components/chat/Popup.js +1032 -866
  25. package/dist/components/chat/Popup.js.map +1 -1
  26. package/dist/components/chat/Popup.mjs +9 -8
  27. package/dist/components/chat/Sidebar.js +1032 -866
  28. package/dist/components/chat/Sidebar.js.map +1 -1
  29. package/dist/components/chat/Sidebar.mjs +9 -8
  30. package/dist/components/chat/index.js +1034 -868
  31. package/dist/components/chat/index.js.map +1 -1
  32. package/dist/components/chat/index.mjs +16 -15
  33. package/dist/components/chat/messages/LegacyRenderMessage.d.ts +28 -0
  34. package/dist/components/chat/messages/LegacyRenderMessage.js +980 -0
  35. package/dist/components/chat/messages/LegacyRenderMessage.js.map +1 -0
  36. package/dist/components/chat/messages/LegacyRenderMessage.mjs +17 -0
  37. package/dist/components/chat/messages/LegacyRenderMessage.mjs.map +1 -0
  38. package/dist/components/chat/messages/RenderMessage.js +4 -0
  39. package/dist/components/chat/messages/RenderMessage.js.map +1 -1
  40. package/dist/components/chat/messages/RenderMessage.mjs +1 -1
  41. package/dist/components/chat/props.d.ts +49 -0
  42. package/dist/components/chat/props.js.map +1 -1
  43. package/dist/components/index.js +1034 -868
  44. package/dist/components/index.js.map +1 -1
  45. package/dist/components/index.mjs +16 -15
  46. package/dist/index.js +1034 -868
  47. package/dist/index.js.map +1 -1
  48. package/dist/index.mjs +16 -15
  49. package/package.json +4 -4
  50. package/src/components/chat/Chat.tsx +50 -14
  51. package/src/components/chat/Messages.tsx +56 -3
  52. package/src/components/chat/messages/LegacyRenderMessage.tsx +143 -0
  53. package/src/components/chat/messages/RenderMessage.tsx +3 -0
  54. package/src/components/chat/props.ts +57 -0
  55. package/dist/chunk-2KG77MAY.mjs.map +0 -1
  56. package/dist/chunk-JHUTTP5C.mjs.map +0 -1
  57. package/dist/chunk-U5ATIGWH.mjs.map +0 -1
  58. /package/dist/{chunk-TW4LLLTE.mjs.map → chunk-GBP47ONN.mjs.map} +0 -0
  59. /package/dist/{chunk-6C3YVF5W.mjs.map → chunk-J5ZZR6YB.mjs.map} +0 -0
  60. /package/dist/{chunk-7K2X77PW.mjs.map → chunk-Y44VLEUH.mjs.map} +0 -0
@@ -395,557 +395,135 @@ var ChatContextProvider = ({
395
395
  };
396
396
 
397
397
  // src/components/chat/Messages.tsx
398
- var import_react2 = require("react");
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 Messages = ({
402
- inProgress,
403
- children,
404
- RenderMessage: RenderMessage2,
405
- AssistantMessage: AssistantMessage2,
406
- UserMessage: UserMessage2,
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
- id: initial,
460
- role: "system",
461
- content: initial
462
- }
463
- ];
464
- }
465
- function useScrollToBottom(messages) {
466
- const messagesEndRef = (0, import_react2.useRef)(null);
467
- const messagesContainerRef = (0, import_react2.useRef)(null);
468
- const isProgrammaticScrollRef = (0, import_react2.useRef)(false);
469
- const isUserScrollUpRef = (0, import_react2.useRef)(false);
470
- const scrollToBottom = () => {
471
- if (messagesContainerRef.current && messagesEndRef.current) {
472
- isProgrammaticScrollRef.current = true;
473
- messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight;
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 (messagesContainerRef.current) {
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
- const mutationObserver = new MutationObserver(() => {
503
- if (!isUserScrollUpRef.current) {
504
- scrollToBottom();
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
- return () => {
513
- mutationObserver.disconnect();
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/Input.tsx
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 AutoResizingTextarea = (0, import_react3.forwardRef)(
530
- ({
531
- maxRows = 1,
532
- placeholder,
533
- value,
534
- onChange,
535
- onKeyDown,
536
- onCompositionStart,
537
- onCompositionEnd,
538
- autoFocus
539
- }, ref) => {
540
- const internalTextareaRef = (0, import_react3.useRef)(null);
541
- const [maxHeight, setMaxHeight] = (0, import_react3.useState)(0);
542
- (0, import_react3.useImperativeHandle)(ref, () => internalTextareaRef.current);
543
- (0, import_react3.useEffect)(() => {
544
- const calculateMaxHeight = () => {
545
- const textarea = internalTextareaRef.current;
546
- if (textarea) {
547
- textarea.style.height = "auto";
548
- const singleRowHeight = textarea.scrollHeight;
549
- setMaxHeight(singleRowHeight * maxRows);
550
- if (autoFocus) {
551
- textarea.focus();
552
- }
553
- }
554
- };
555
- calculateMaxHeight();
556
- }, [maxRows]);
557
- (0, import_react3.useEffect)(() => {
558
- const textarea = internalTextareaRef.current;
559
- if (textarea) {
560
- textarea.style.height = "auto";
561
- textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
562
- }
563
- }, [value, maxHeight]);
564
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
565
- "textarea",
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
- ref: internalTextareaRef,
568
- value,
569
- onChange,
570
- onKeyDown,
571
- onCompositionStart,
572
- onCompositionEnd,
573
- placeholder,
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
- rows: 1
580
- }
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
526
+ children: value
949
527
  }
950
528
  )
951
529
  ] });
@@ -1234,306 +812,885 @@ var highlightStyle = {
1234
812
  }
1235
813
  };
1236
814
 
1237
- // src/components/chat/Markdown.tsx
1238
- var import_remark_gfm = __toESM(require("remark-gfm"));
1239
- var import_remark_math = __toESM(require("remark-math"));
1240
- var import_rehype_raw = __toESM(require("rehype-raw"));
1241
- var import_jsx_runtime9 = require("react/jsx-runtime");
1242
- var defaultComponents = {
1243
- a(_a) {
1244
- var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
1245
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("a", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { target: "_blank", rel: "noopener noreferrer", children }));
1246
- },
1247
- // @ts-expect-error -- inline
1248
- code(_c) {
1249
- var _d = _c, { children, className, inline } = _d, props = __objRest(_d, ["children", "className", "inline"]);
1250
- if (Array.isArray(children) && children.length) {
1251
- if (children[0] == "\u258D") {
1252
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1253
- "span",
1254
- {
1255
- style: {
1256
- animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
1257
- marginTop: "0.25rem"
1258
- },
1259
- children: "\u258D"
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();
1260
1423
  }
1261
- );
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
1262
1451
  }
1263
- children[0] = (children == null ? void 0 : children[0]).replace("`\u258D`", "\u258D");
1264
- }
1265
- const match = /language-(\w+)/.exec(className || "");
1266
- const hasLanguage = match && match[1];
1267
- const content = String(children);
1268
- const hasNewlines = content.includes("\n");
1269
- const isInline = !hasLanguage && !hasNewlines;
1270
- if (isInline) {
1271
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1272
- "code",
1273
- __spreadProps(__spreadValues({
1274
- className: `copilotKitMarkdownElement copilotKitInlineCode ${className || ""}`
1275
- }, props), {
1276
- children
1277
- })
1278
- );
1279
- }
1280
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1281
- CodeBlock,
1282
- __spreadValues({
1283
- language: match && match[1] || "",
1284
- value: String(children).replace(/\n$/, "")
1285
- }, props),
1286
- Math.random()
1287
1452
  );
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
1453
  }
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
1454
  );
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
- ) });
1348
- };
1455
+ var Textarea_default = AutoResizingTextarea;
1349
1456
 
1350
- // src/components/chat/messages/AssistantMessage.tsx
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");
1351
1460
  var import_react8 = require("react");
1352
- var import_jsx_runtime10 = require("react/jsx-runtime");
1353
- var AssistantMessage = (props) => {
1354
- var _a;
1355
- const { icons, labels } = useChatContext();
1356
- const {
1357
- message,
1358
- isLoading,
1359
- onRegenerate,
1360
- onCopy,
1361
- onThumbsUp,
1362
- onThumbsDown,
1363
- isCurrentMessage,
1364
- markdownTagRenderers
1365
- } = props;
1366
- const [copied, setCopied] = (0, import_react8.useState)(false);
1367
- const handleCopy = () => {
1368
- const content2 = (message == null ? void 0 : message.content) || "";
1369
- if (content2 && onCopy) {
1370
- navigator.clipboard.writeText(content2);
1371
- setCopied(true);
1372
- onCopy(content2);
1373
- setTimeout(() => setCopied(false), 2e3);
1374
- } else if (content2) {
1375
- navigator.clipboard.writeText(content2);
1376
- setCopied(true);
1377
- setTimeout(() => setCopied(false), 2e3);
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
+ })
1539
+ );
1540
+ }
1541
+ }
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
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);
1378
1556
  }
1557
+ }, [startReadingFromMessageId, inProgress]);
1558
+ return { pushToTalkState, setPushToTalkState };
1559
+ };
1560
+
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)"
1379
1586
  };
1380
- const handleRegenerate = () => {
1381
- if (onRegenerate)
1382
- onRegenerate();
1383
- };
1384
- const handleThumbsUp = () => {
1385
- if (onThumbsUp && message)
1386
- onThumbsUp(message);
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 handleThumbsDown = () => {
1389
- if (onThumbsDown && message)
1390
- onThumbsDown(message);
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 LoadingIcon = () => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: icons.activityIcon });
1393
- const content = (message == null ? void 0 : message.content) || "";
1394
- const subComponent = (_a = message == null ? void 0 : message.generativeUI) == null ? void 0 : _a.call(message);
1395
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1396
- content && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitMessage copilotKitAssistantMessage", children: [
1397
- content && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Markdown, { content, components: markdownTagRenderers }),
1398
- content && !isLoading && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1399
- "div",
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
- className: `copilotKitMessageControls ${isCurrentMessage ? "currentMessage" : ""}`,
1402
- children: [
1403
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1404
- "button",
1405
- {
1406
- className: "copilotKitMessageControlButton",
1407
- onClick: handleRegenerate,
1408
- "aria-label": labels.regenerateResponse,
1409
- title: labels.regenerateResponse,
1410
- children: icons.regenerateIcon
1411
- }
1412
- ),
1413
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
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, import_jsx_runtime10.jsx)("div", { style: { marginBottom: "0.5rem" }, children: subComponent }),
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 import_jsx_runtime13 = require("react/jsx-runtime");
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, import_jsx_runtime13.jsx)(
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, import_jsx_runtime13.jsxs)(
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, import_jsx_runtime13.jsx)(
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, import_jsx_runtime13.jsx)(
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 import_jsx_runtime14 = require("react/jsx-runtime");
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, import_jsx_runtime14.jsx)(
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, import_jsx_runtime14.jsx)("span", { children: title })
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 import_jsx_runtime15 = require("react/jsx-runtime");
1802
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1646
1803
  function Suggestions({ suggestions, onSuggestionClick }) {
1647
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "suggestions", children: suggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
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 import_jsx_runtime16 = require("react/jsx-runtime");
1818
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1662
1819
  function CopilotChat({
1663
1820
  instructions,
1664
1821
  suggestions = "auto",
@@ -1686,7 +1843,13 @@ function CopilotChat({
1686
1843
  inputFileAccept = "image/*",
1687
1844
  hideStopButton,
1688
1845
  observabilityHooks,
1689
- renderError
1846
+ renderError,
1847
+ // Legacy props - deprecated
1848
+ RenderTextMessage,
1849
+ RenderActionExecutionMessage,
1850
+ RenderAgentStateMessage,
1851
+ RenderResultMessage,
1852
+ RenderImageMessage
1690
1853
  }) {
1691
1854
  const { additionalInstructions, setChatInstructions, copilotApiConfig, setBannerError } = (0, import_react_core5.useCopilotContext)();
1692
1855
  const { publicApiKey, chatApiEndpoint } = copilotApiConfig;
@@ -1814,7 +1977,7 @@ function CopilotChat({
1814
1977
  setChatInstructions(combinedAdditionalInstructions.join("\n") || "");
1815
1978
  }, [instructions, additionalInstructions]);
1816
1979
  const {
1817
- visibleMessages,
1980
+ messages,
1818
1981
  isLoading,
1819
1982
  sendMessage,
1820
1983
  stopGeneration,
@@ -1910,20 +2073,20 @@ function CopilotChat({
1910
2073
  }
1911
2074
  triggerObservabilityHook("onFeedbackGiven", message.id, "thumbsDown");
1912
2075
  };
1913
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(WrappedCopilotChat, { icons, labels, className, children: [
2076
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(WrappedCopilotChat, { icons, labels, className, children: [
1914
2077
  chatError && renderError && renderError(__spreadProps(__spreadValues({}, chatError), {
1915
2078
  onDismiss: () => setChatError(null),
1916
2079
  onRetry: () => {
1917
2080
  setChatError(null);
1918
2081
  }
1919
2082
  })),
1920
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2083
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1921
2084
  Messages2,
1922
2085
  {
1923
2086
  AssistantMessage: AssistantMessage2,
1924
2087
  UserMessage: UserMessage2,
1925
2088
  RenderMessage: RenderMessage2,
1926
- messages: visibleMessages,
2089
+ messages,
1927
2090
  inProgress: isLoading,
1928
2091
  onRegenerate: handleRegenerate,
1929
2092
  onCopy: handleCopy,
@@ -1931,7 +2094,12 @@ function CopilotChat({
1931
2094
  onThumbsDown: handleThumbsDown,
1932
2095
  markdownTagRenderers,
1933
2096
  ImageRenderer: ImageRenderer2,
1934
- children: currentSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2097
+ RenderTextMessage,
2098
+ RenderActionExecutionMessage,
2099
+ RenderAgentStateMessage,
2100
+ RenderResultMessage,
2101
+ RenderImageMessage,
2102
+ children: currentSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1935
2103
  RenderSuggestionsList,
1936
2104
  {
1937
2105
  onSuggestionClick: handleSendMessage,
@@ -1940,9 +2108,9 @@ function CopilotChat({
1940
2108
  )
1941
2109
  }
1942
2110
  ),
1943
- imageUploadsEnabled && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
1944
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ImageUploadQueue, { images: selectedImages, onRemoveImage: removeSelectedImage }),
1945
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
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)(
1946
2114
  "input",
1947
2115
  {
1948
2116
  type: "file",
@@ -1954,7 +2122,7 @@ function CopilotChat({
1954
2122
  }
1955
2123
  )
1956
2124
  ] }),
1957
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2125
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1958
2126
  Input2,
1959
2127
  {
1960
2128
  inProgress: isLoading,
@@ -1978,16 +2146,16 @@ function WrappedCopilotChat({
1978
2146
  }) {
1979
2147
  const chatContext = import_react10.default.useContext(ChatContext);
1980
2148
  if (!chatContext) {
1981
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChatContextProvider, { icons, labels, open: true, setOpen: () => {
1982
- }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: `copilotKitChat ${className != null ? className : ""}`, children }) });
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 }) });
1983
2151
  }
1984
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children });
2152
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children });
1985
2153
  }
1986
2154
  var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onSubmitMessage, onStopGeneration, onReloadMessages) => {
1987
2155
  var _a;
1988
2156
  const {
1989
- visibleMessages,
1990
- appendMessage,
2157
+ messages,
2158
+ sendMessage,
1991
2159
  setMessages,
1992
2160
  reloadMessages: defaultReloadMessages,
1993
2161
  stopGeneration: defaultStopGeneration,
@@ -2033,12 +2201,12 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
2033
2201
  if (Object.keys(generalContext.chatSuggestionConfiguration).length === 0) {
2034
2202
  return;
2035
2203
  }
2036
- if (visibleMessages.length === 0 && !hasGeneratedInitialSuggestions.current) {
2204
+ if (messages.length === 0 && !hasGeneratedInitialSuggestions.current) {
2037
2205
  hasGeneratedInitialSuggestions.current = true;
2038
2206
  generateSuggestionsWithErrorHandling("initial");
2039
2207
  return;
2040
2208
  }
2041
- if (visibleMessages.length > 0 && suggestions.length === 0) {
2209
+ if (messages.length > 0 && suggestions.length === 0) {
2042
2210
  generateSuggestionsWithErrorHandling("post-message");
2043
2211
  return;
2044
2212
  }
@@ -2046,7 +2214,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
2046
2214
  chatSuggestions,
2047
2215
  isLoadingSuggestions,
2048
2216
  suggestionsFailed,
2049
- visibleMessages.length,
2217
+ messages.length,
2050
2218
  isLoading,
2051
2219
  suggestions.length,
2052
2220
  Object.keys(generalContext.chatSuggestionConfiguration).join(","),
@@ -2076,7 +2244,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
2076
2244
  (0, import_react10.useEffect)(() => {
2077
2245
  onInProgress == null ? void 0 : onInProgress(isLoading);
2078
2246
  }, [onInProgress, isLoading]);
2079
- const sendMessage = (messageContent, imagesToUse) => __async(void 0, null, function* () {
2247
+ const safelySendMessage = (messageContent, imagesToUse) => __async(void 0, null, function* () {
2080
2248
  const images = imagesToUse || [];
2081
2249
  if (chatSuggestions === "auto" || chatSuggestions === "manual") {
2082
2250
  setSuggestions([]);
@@ -2095,7 +2263,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
2095
2263
  console.error("Error in onSubmitMessage:", error);
2096
2264
  }
2097
2265
  }
2098
- yield appendMessage(textMessage, {
2266
+ yield sendMessage(textMessage, {
2099
2267
  followUp: images.length === 0,
2100
2268
  clearSuggestions: chatSuggestions === "auto" || chatSuggestions === "manual"
2101
2269
  });
@@ -2113,7 +2281,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
2113
2281
  bytes: images[i].bytes
2114
2282
  }
2115
2283
  };
2116
- yield appendMessage(imageMessage, { followUp: i === images.length - 1 });
2284
+ yield sendMessage(imageMessage, { followUp: i === images.length - 1 });
2117
2285
  if (!firstMessage) {
2118
2286
  firstMessage = imageMessage;
2119
2287
  }
@@ -2124,7 +2292,6 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
2124
2292
  }
2125
2293
  return firstMessage;
2126
2294
  });
2127
- const messages = visibleMessages;
2128
2295
  const currentAgentName = (_a = generalContext.agentSession) == null ? void 0 : _a.agentName;
2129
2296
  const restartCurrentAgent = (hint) => __async(void 0, null, function* () {
2130
2297
  if (generalContext.agentSession) {
@@ -2149,7 +2316,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
2149
2316
  generalContext.agentSession.agentName,
2150
2317
  stableContext,
2151
2318
  messagesContext.messages,
2152
- appendMessage,
2319
+ sendMessage,
2153
2320
  runChatCompletion
2154
2321
  );
2155
2322
  }
@@ -2206,10 +2373,9 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
2206
2373
  }
2207
2374
  return {
2208
2375
  messages,
2209
- visibleMessages,
2210
2376
  isLoading,
2211
2377
  suggestions,
2212
- sendMessage,
2378
+ sendMessage: safelySendMessage,
2213
2379
  stopGeneration,
2214
2380
  reloadMessages,
2215
2381
  resetSuggestions,