UNPKG

@copilotkit/react-ui

Version:

<div align="center"> <a href="https://copilotkit.ai" target="_blank"> <img src="https://github.com/copilotkit/copilotkit/raw/main/assets/banner.png" alt="CopilotKit Logo"> </a>

1,521 lines (1,503 loc) • 68 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __objRest = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols) for (var prop of __getOwnPropSymbols(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop]; } return target; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/components/chat/Chat.tsx var Chat_exports = {}; __export(Chat_exports, { CopilotChat: () => CopilotChat, WrappedCopilotChat: () => WrappedCopilotChat, useCopilotChatLogic: () => useCopilotChatLogic }); module.exports = __toCommonJS(Chat_exports); // src/components/chat/ChatContext.tsx var import_react = __toESM(require("react")); // src/components/chat/Icons.tsx var import_jsx_runtime = require("react/jsx-runtime"); var OpenIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", width: "24", height: "24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: "translate(24, 0) scale(-1, 1)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { fillRule: "evenodd", d: "M5.337 21.718a6.707 6.707 0 01-.533-.074.75.75 0 01-.44-1.223 3.73 3.73 0 00.814-1.686c.023-.115-.022-.317-.254-.543C3.274 16.587 2.25 14.41 2.25 12c0-5.03 4.428-9 9.75-9s9.75 3.97 9.75 9c0 5.03-4.428 9-9.75 9-.833 0-1.643-.097-2.417-.279a6.721 6.721 0 01-4.246.997z", clipRule: "evenodd" } ) }) } ); var CloseIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: "1.5", stroke: "currentColor", width: "24", height: "24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19.5 8.25l-7.5 7.5-7.5-7.5" }) } ); var HeaderCloseIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: "1.5", stroke: "currentColor", width: "24", height: "24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) } ); var SendIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: "1.5", stroke: "currentColor", width: "24", height: "24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 19V5m0 0l-7 7m7-7l7 7" }) } ); var MicrophoneIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: "1.5", stroke: "currentColor", width: "24", height: "24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 18.75a6 6 0 006-6v-1.5m-6 7.5a6 6 0 01-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 01-3-3V4.5a3 3 0 116 0v8.25a3 3 0 01-3 3z" } ) } ); var StopIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: "1.5", stroke: "currentColor", width: "24", height: "24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5.25 7.5A2.25 2.25 0 017.5 5.25h9a2.25 2.25 0 012.25 2.25v9a2.25 2.25 0 01-2.25 2.25h-9a2.25 2.25 0 01-2.25-2.25v-9z" } ) } ); var RegenerateIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: "2", stroke: "currentColor", width: "16", height: "16", style: { minWidth: "16px", minHeight: "16px" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99" } ) } ); var CopyIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: "2", stroke: "currentColor", width: "16", height: "16", style: { minWidth: "16px", minHeight: "16px" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75" } ) } ); var SmallSpinnerIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "copilotKitSpinner", style: { width: "13px", height: "13px" } }); var SpinnerIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "copilotKitSpinner", style: { width: "24px", height: "24px" } }); var ActivityIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "copilotKitActivityDot", style: { animationDelay: "0s" } }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "copilotKitActivityDot", style: { animationDelay: "0.2s" } }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "copilotKitActivityDot", style: { animationDelay: "0.4s" } }) ] }); var ThumbsUpIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: "2", stroke: "currentColor", width: "16", height: "16", style: { minWidth: "16px", minHeight: "16px" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6.633 10.5c.806 0 1.533-.446 2.031-1.08a9.041 9.041 0 012.861-2.4c.723-.384 1.35-.956 1.653-1.715a4.498 4.498 0 00.322-1.672V3a.75.75 0 01.75-.75A2.25 2.25 0 0116.5 4.5c0 1.152-.26 2.243-.723 3.218-.266.558.107 1.282.725 1.282h3.126c1.026 0 1.945.694 2.054 1.715.045.422.068.85.068 1.285a11.95 11.95 0 01-2.649 7.521c-.388.482-.987.729-1.605.729H13.48c-.483 0-.964-.078-1.423-.23l-3.114-1.04a4.501 4.501 0 00-1.423-.23H5.904M14.25 9h2.25M5.904 18.75c.083.205.173.405.27.602.197.4-.078.898-.523.898h-.908c-.889 0-1.713-.518-1.972-1.368a12 12 0 01-.521-3.507c0-1.553.295-3.036.831-4.398C3.387 10.203 4.167 9.75 5 9.75h1.053c.472 0 .745.556.5.96a8.958 8.958 0 00-1.302 4.665c0 1.194.232 2.333.654 3.375z" } ) } ); var ThumbsDownIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: "2", stroke: "currentColor", width: "16", height: "16", style: { minWidth: "16px", minHeight: "16px" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7.5 15h2.25m8.024-9.75c.011.05.028.1.052.148.591 1.2.924 2.55.924 3.977a8.96 8.96 0 01-.999 4.125m.023-8.25c-.076-.365.183-.75.575-.75h.908c.889 0 1.713.518 1.972 1.368.339 1.11.521 2.287.521 3.507 0 1.553-.295 3.036-.831 4.398C20.613 14.547 19.833 15 19 15h-1.053c-.472 0-.745-.556-.5-.96a8.95 8.95 0 00.303-.54m.023-8.25H16.48a4.5 4.5 0 01-1.423-.23l-3.114-1.04a4.5 4.5 0 00-1.423-.23H6.504c-.618 0-1.217.247-1.605.729A11.95 11.95 0 002.25 12c0 .434.023.863.068 1.285C2.427 14.306 3.346 15 4.372 15h3.126c.618 0 .991.724.725 1.282A7.471 7.471 0 007.5 19.5a2.25 2.25 0 002.25 2.25.75.75 0 00.75-.75v-.633c0-.573.11-1.14.322-1.672.304-.76.93-1.33 1.653-1.715a9.04 9.04 0 002.86-2.4c.498-.634 1.226-1.08 2.032-1.08h.384" } ) } ); var DownloadIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: "2", stroke: "currentColor", width: "16", height: "16", style: { minWidth: "16px", minHeight: "16px" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3" } ) } ); var CheckIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: "2", stroke: "currentColor", width: "16", height: "16", style: { minWidth: "16px", minHeight: "16px" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4.5 12.75l6 6 9-13.5" }) } ); // src/components/chat/ChatContext.tsx var import_jsx_runtime2 = require("react/jsx-runtime"); var ChatContext = import_react.default.createContext(void 0); function useChatContext() { const context = import_react.default.useContext(ChatContext); if (context === void 0) { throw new Error( "Context not found. Did you forget to wrap your app in a <ChatContextProvider> component?" ); } return context; } var ChatContextProvider = ({ // temperature, // instructions, // maxFeedback, labels, icons, children, open, setOpen }) => { const memoizedLabels = (0, import_react.useMemo)( () => __spreadValues(__spreadValues({}, { initial: "", title: "CopilotKit", placeholder: "Type a message...", error: "\u274C An error occurred. Please try again.", stopGenerating: "Stop generating", regenerateResponse: "Regenerate response", copyToClipboard: "Copy to clipboard", thumbsUp: "Thumbs up", thumbsDown: "Thumbs down", copied: "Copied!" }), labels), [labels] ); const memoizedIcons = (0, import_react.useMemo)( () => __spreadValues(__spreadValues({}, { openIcon: OpenIcon, closeIcon: CloseIcon, headerCloseIcon: HeaderCloseIcon, sendIcon: SendIcon, activityIcon: ActivityIcon, spinnerIcon: SpinnerIcon, stopIcon: StopIcon, regenerateIcon: RegenerateIcon, pushToTalkIcon: MicrophoneIcon, copyIcon: CopyIcon, thumbsUpIcon: ThumbsUpIcon, thumbsDownIcon: ThumbsDownIcon }), icons), [icons] ); const context = (0, import_react.useMemo)( () => ({ labels: memoizedLabels, icons: memoizedIcons, open, setOpen }), [memoizedLabels, memoizedIcons, open, setOpen] ); return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatContext.Provider, { value: context, children }); }; // src/components/chat/Messages.tsx var import_react2 = require("react"); var import_runtime_client_gql = require("@copilotkit/runtime-client-gql"); var import_react_core = require("@copilotkit/react-core"); var import_jsx_runtime3 = require("react/jsx-runtime"); var Messages = ({ messages, inProgress, children, RenderTextMessage: RenderTextMessage2, RenderActionExecutionMessage: RenderActionExecutionMessage2, RenderAgentStateMessage: RenderAgentStateMessage2, RenderResultMessage: RenderResultMessage2, AssistantMessage: AssistantMessage2, UserMessage: UserMessage2, onRegenerate, onCopy, onThumbsUp, onThumbsDown }) => { const context = useChatContext(); const initialMessages = (0, import_react2.useMemo)( () => makeInitialMessages(context.labels.initial), [context.labels.initial] ); messages = [...initialMessages, ...messages]; const actionResults = {}; for (let i = 0; i < messages.length; i++) { if (messages[i].isActionExecutionMessage()) { const id = messages[i].id; const resultMessage = messages.find( (message) => message.isResultMessage() && message.actionExecutionId === id ); if (resultMessage) { actionResults[id] = import_runtime_client_gql.ResultMessage.decodeResult(resultMessage.result || ""); } } } const { messagesEndRef, messagesContainerRef } = useScrollToBottom(messages); const interrupt = (0, import_react_core.useLangGraphInterruptRender)(); return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "copilotKitMessages", ref: messagesContainerRef, children: [ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "copilotKitMessagesContainer", children: [ messages.map((message, index) => { const isCurrentMessage = index === messages.length - 1; if (message.isTextMessage()) { return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)( RenderTextMessage2, { message, inProgress, index, isCurrentMessage, AssistantMessage: AssistantMessage2, UserMessage: UserMessage2, onRegenerate, onCopy, onThumbsUp, onThumbsDown }, index ); } else if (message.isActionExecutionMessage()) { return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)( RenderActionExecutionMessage2, { message, inProgress, index, isCurrentMessage, actionResult: actionResults[message.id], AssistantMessage: AssistantMessage2, UserMessage: UserMessage2 }, index ); } else if (message.isAgentStateMessage()) { return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)( RenderAgentStateMessage2, { message, inProgress, index, isCurrentMessage, AssistantMessage: AssistantMessage2, UserMessage: UserMessage2 }, index ); } else if (message.isResultMessage()) { return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)( RenderResultMessage2, { message, inProgress, index, isCurrentMessage, AssistantMessage: AssistantMessage2, UserMessage: UserMessage2 }, index ); } }), interrupt ] }), /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("footer", { className: "copilotKitMessagesFooter", ref: messagesEndRef, children }) ] }); }; function makeInitialMessages(initial) { let initialArray = []; if (initial) { if (Array.isArray(initial)) { initialArray.push(...initial); } else { initialArray.push(initial); } } return initialArray.map( (message) => new import_runtime_client_gql.TextMessage({ role: import_runtime_client_gql.Role.Assistant, content: message }) ); } function useScrollToBottom(messages) { const messagesEndRef = (0, import_react2.useRef)(null); const messagesContainerRef = (0, import_react2.useRef)(null); const isProgrammaticScrollRef = (0, import_react2.useRef)(false); const isUserScrollUpRef = (0, import_react2.useRef)(false); const scrollToBottom = () => { if (messagesEndRef.current) { isProgrammaticScrollRef.current = true; messagesEndRef.current.scrollIntoView({ behavior: "auto" }); } }; const handleScroll = () => { if (isProgrammaticScrollRef.current) { isProgrammaticScrollRef.current = false; return; } if (messagesContainerRef.current) { const { scrollTop, scrollHeight, clientHeight } = messagesContainerRef.current; isUserScrollUpRef.current = scrollTop + clientHeight < scrollHeight; } }; (0, import_react2.useEffect)(() => { const container = messagesContainerRef.current; if (container) { container.addEventListener("scroll", handleScroll); } return () => { if (container) { container.removeEventListener("scroll", handleScroll); } }; }, []); (0, import_react2.useEffect)(() => { const container = messagesContainerRef.current; if (!container) { return; } const mutationObserver = new MutationObserver(() => { if (!isUserScrollUpRef.current) { scrollToBottom(); } }); mutationObserver.observe(container, { childList: true, subtree: true, characterData: true }); return () => { mutationObserver.disconnect(); }; }, []); (0, import_react2.useEffect)(() => { isUserScrollUpRef.current = false; scrollToBottom(); }, [messages.filter((m) => m.isTextMessage() && m.role === import_runtime_client_gql.Role.User).length]); return { messagesEndRef, messagesContainerRef }; } // src/components/chat/Input.tsx var import_react5 = require("react"); // src/components/chat/Textarea.tsx var import_react3 = require("react"); var import_jsx_runtime4 = require("react/jsx-runtime"); var AutoResizingTextarea = (0, import_react3.forwardRef)( ({ maxRows = 1, placeholder, value, onChange, onKeyDown, autoFocus }, ref) => { const internalTextareaRef = (0, import_react3.useRef)(null); const [maxHeight, setMaxHeight] = (0, import_react3.useState)(0); (0, import_react3.useImperativeHandle)(ref, () => internalTextareaRef.current); (0, import_react3.useEffect)(() => { const calculateMaxHeight = () => { const textarea = internalTextareaRef.current; if (textarea) { textarea.style.height = "auto"; const singleRowHeight = textarea.scrollHeight; setMaxHeight(singleRowHeight * maxRows); if (autoFocus) { textarea.focus(); } } }; calculateMaxHeight(); }, [maxRows]); (0, import_react3.useEffect)(() => { const textarea = internalTextareaRef.current; if (textarea) { textarea.style.height = "auto"; textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`; } }, [value, maxHeight]); return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)( "textarea", { ref: internalTextareaRef, value, onChange, onKeyDown, placeholder, style: { overflow: "auto", resize: "none", maxHeight: `${maxHeight}px` }, rows: 1 } ); } ); var Textarea_default = AutoResizingTextarea; // src/hooks/use-push-to-talk.tsx var import_react_core2 = require("@copilotkit/react-core"); var import_react4 = require("react"); var startRecording = (mediaStreamRef, mediaRecorderRef, audioContextRef, recordedChunks, onStop) => __async(void 0, null, function* () { if (!mediaStreamRef.current || !audioContextRef.current) { mediaStreamRef.current = yield navigator.mediaDevices.getUserMedia({ audio: true }); audioContextRef.current = new window.AudioContext(); yield audioContextRef.current.resume(); } mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current); mediaRecorderRef.current.start(1e3); mediaRecorderRef.current.ondataavailable = (event) => { recordedChunks.push(event.data); }; mediaRecorderRef.current.onstop = onStop; }); var stopRecording = (mediaRecorderRef) => { if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") { mediaRecorderRef.current.stop(); } }; var transcribeAudio = (recordedChunks, transcribeAudioUrl) => __async(void 0, null, function* () { const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" }); const formData = new FormData(); formData.append("file", completeBlob, "recording.mp4"); const response = yield fetch(transcribeAudioUrl, { method: "POST", body: formData }); if (!response.ok) { throw new Error(`Error: ${response.statusText}`); } const transcription = yield response.json(); return transcription.text; }); var playAudioResponse = (text, textToSpeechUrl, audioContext) => { const encodedText = encodeURIComponent(text); const url = `${textToSpeechUrl}?text=${encodedText}`; fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer)).then((audioBuffer) => { const source = audioContext.createBufferSource(); source.buffer = audioBuffer; source.connect(audioContext.destination); source.start(0); }).catch((error) => { console.error("Error with decoding audio data", error); }); }; var usePushToTalk = ({ sendFunction, inProgress }) => { const [pushToTalkState, setPushToTalkState] = (0, import_react4.useState)("idle"); const mediaStreamRef = (0, import_react4.useRef)(null); const audioContextRef = (0, import_react4.useRef)(null); const mediaRecorderRef = (0, import_react4.useRef)(null); const recordedChunks = (0, import_react4.useRef)([]); const generalContext = (0, import_react_core2.useCopilotContext)(); const messagesContext = (0, import_react_core2.useCopilotMessagesContext)(); const context = __spreadValues(__spreadValues({}, generalContext), messagesContext); const [startReadingFromMessageId, setStartReadingFromMessageId] = (0, import_react4.useState)(null); (0, import_react4.useEffect)(() => { if (pushToTalkState === "recording") { startRecording( mediaStreamRef, mediaRecorderRef, audioContextRef, recordedChunks.current, () => { setPushToTalkState("transcribing"); } ); } else { stopRecording(mediaRecorderRef); if (pushToTalkState === "transcribing") { transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl).then( (transcription) => __async(void 0, null, function* () { recordedChunks.current = []; setPushToTalkState("idle"); const message = yield sendFunction(transcription); setStartReadingFromMessageId(message.id); }) ); } } return () => { stopRecording(mediaRecorderRef); }; }, [pushToTalkState]); (0, import_react4.useEffect)(() => { if (inProgress === false && startReadingFromMessageId) { const lastMessageIndex = context.messages.findIndex( (message) => message.id === startReadingFromMessageId ); const messagesAfterLast = context.messages.slice(lastMessageIndex + 1).filter( (message) => message.isTextMessage() && message.role === "assistant" ); const text = messagesAfterLast.map((message) => message.content).join("\n"); playAudioResponse(text, context.copilotApiConfig.textToSpeechUrl, audioContextRef.current); setStartReadingFromMessageId(null); } }, [startReadingFromMessageId, inProgress]); return { pushToTalkState, setPushToTalkState }; }; // src/components/chat/Input.tsx var import_react_core3 = require("@copilotkit/react-core"); var import_jsx_runtime5 = require("react/jsx-runtime"); var Input = ({ inProgress, onSend, isVisible = false, onStop }) => { const context = useChatContext(); const copilotContext = (0, import_react_core3.useCopilotContext)(); const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0; const textareaRef = (0, import_react5.useRef)(null); const handleDivClick = (event) => { var _a; const target = event.target; if (target.closest("button")) return; if (target.tagName === "TEXTAREA") return; (_a = textareaRef.current) == null ? void 0 : _a.focus(); }; const [text, setText] = (0, import_react5.useState)(""); const send = () => { var _a; if (inProgress) return; onSend(text); setText(""); (_a = textareaRef.current) == null ? void 0 : _a.focus(); }; (0, import_react5.useEffect)(() => { var _a; if (isVisible) { (_a = textareaRef.current) == null ? void 0 : _a.focus(); } }, [isVisible]); const { pushToTalkState, setPushToTalkState } = usePushToTalk({ sendFunction: onSend, inProgress }); const isInProgress = inProgress || pushToTalkState === "transcribing"; const buttonIcon = isInProgress ? context.icons.stopIcon : context.icons.sendIcon; const showPushToTalk = pushToTalkConfigured && (pushToTalkState === "idle" || pushToTalkState === "recording") && !inProgress; const canSend = () => { var _a; const interruptEvent = (_a = copilotContext.langGraphInterruptAction) == null ? void 0 : _a.event; const interruptInProgress = (interruptEvent == null ? void 0 : interruptEvent.name) === "LangGraphInterruptEvent" && !(interruptEvent == null ? void 0 : interruptEvent.response); return (isInProgress || !isInProgress && text.trim().length > 0) && pushToTalkState === "idle" && !interruptInProgress; }; const sendDisabled = !canSend(); return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "copilotKitInputContainer", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)( Textarea_default, { ref: textareaRef, placeholder: context.labels.placeholder, autoFocus: true, maxRows: 5, value: text, onChange: (event) => setText(event.target.value), onKeyDown: (event) => { if (event.key === "Enter" && !event.shiftKey) { event.preventDefault(); if (canSend()) { send(); } } } } ), /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "copilotKitInputControls", children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { flexGrow: 1 } }), showPushToTalk && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)( "button", { onClick: () => setPushToTalkState(pushToTalkState === "idle" ? "recording" : "transcribing"), className: pushToTalkState === "recording" ? "copilotKitInputControlButton copilotKitPushToTalkRecording" : "copilotKitInputControlButton", children: context.icons.pushToTalkIcon } ), /* @__PURE__ */ (0, import_jsx_runtime5.jsx)( "button", { disabled: sendDisabled, onClick: isInProgress ? onStop : send, "data-copilotkit-in-progress": inProgress, "data-test-id": inProgress ? "copilot-chat-request-in-progress" : "copilot-chat-ready", className: "copilotKitInputControlButton", children: buttonIcon } ) ] }) ] }) }); }; // src/components/chat/messages/RenderTextMessage.tsx var import_jsx_runtime6 = require("react/jsx-runtime"); function RenderTextMessage(props) { const { message, inProgress, index, isCurrentMessage, UserMessage: UserMessage2, AssistantMessage: AssistantMessage2, onRegenerate, onCopy, onThumbsUp, onThumbsDown } = props; if (message.isTextMessage()) { if (message.role === "user") { return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( UserMessage2, { "data-message-role": "user", message: message.content, rawData: message }, index ); } else if (message.role == "assistant") { return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( AssistantMessage2, { "data-message-role": "assistant", message: message.content, rawData: message, isLoading: inProgress && isCurrentMessage && !message.content, isGenerating: inProgress && isCurrentMessage && !!message.content, isCurrentMessage, onRegenerate, onCopy, onThumbsUp, onThumbsDown }, index ); } } } // src/components/chat/messages/RenderActionExecutionMessage.tsx var import_runtime_client_gql2 = require("@copilotkit/runtime-client-gql"); var import_react_core4 = require("@copilotkit/react-core"); var import_jsx_runtime7 = require("react/jsx-runtime"); function RenderActionExecutionMessage(props) { const { chatComponentsCache } = (0, import_react_core4.useCopilotContext)(); const { message, inProgress, index, isCurrentMessage, actionResult, AssistantMessage: AssistantMessage2 } = props; if (message.isActionExecutionMessage()) { if (chatComponentsCache.current !== null && (chatComponentsCache.current.actions[message.name] || chatComponentsCache.current.actions["*"])) { const render = chatComponentsCache.current.actions[message.name] || chatComponentsCache.current.actions["*"]; if (typeof render === "string") { if (isCurrentMessage && inProgress) { return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( AssistantMessage2, { rawData: message, "data-message-role": "assistant", isLoading: false, isGenerating: true, message: render }, index ); } else { return null; } } else { const args = message.arguments; let status = "inProgress"; if (actionResult !== void 0) { status = "complete"; } else if (message.status.code !== import_runtime_client_gql2.MessageStatusCode.Pending) { status = "executing"; } try { const toRender = render({ status, args, result: actionResult, name: message.name }); if (!toRender && status === "complete") { return null; } if (typeof toRender === "string") { return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( AssistantMessage2, { rawData: message, "data-message-role": "assistant", isLoading: false, isGenerating: false, message: toRender }, index ); } else { return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( AssistantMessage2, { rawData: message, "data-message-role": "action-render", isLoading: false, isGenerating: false, subComponent: toRender }, index ); } } catch (e) { console.error(`Error executing render function for action ${message.name}: ${e}`); return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( AssistantMessage2, { rawData: message, "data-message-role": "assistant", isLoading: false, isGenerating: false, subComponent: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "copilotKitMessage copilotKitAssistantMessage", children: [ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("b", { children: [ "\u274C Error executing render function for action ", message.name, ":" ] }), /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { children: e instanceof Error ? e.message : String(e) }) ] }) }, index ); } } } else if (!inProgress || !isCurrentMessage) { return null; } else { return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( AssistantMessage2, { rawData: message, "data-message-role": "assistant", isLoading: true, isGenerating: true }, index ); } } } // src/components/chat/messages/RenderResultMessage.tsx var import_jsx_runtime8 = require("react/jsx-runtime"); function RenderResultMessage(props) { const { message, inProgress, index, isCurrentMessage, AssistantMessage: AssistantMessage2 } = props; if (message.isResultMessage() && inProgress && isCurrentMessage) { return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)( AssistantMessage2, { "data-message-role": "assistant", rawData: message, isLoading: true, isGenerating: true }, index ); } else { return null; } } // src/components/chat/messages/RenderAgentStateMessage.tsx var import_react_core5 = require("@copilotkit/react-core"); var import_jsx_runtime9 = require("react/jsx-runtime"); function RenderAgentStateMessage(props) { const { chatComponentsCache } = (0, import_react_core5.useCopilotContext)(); const { message, inProgress, index, isCurrentMessage, AssistantMessage: AssistantMessage2 } = props; if (message.isAgentStateMessage()) { let render; if (chatComponentsCache.current !== null) { render = chatComponentsCache.current.coAgentStateRenders[`${message.agentName}-${message.nodeName}`] || chatComponentsCache.current.coAgentStateRenders[`${message.agentName}-global`]; } if (render) { if (typeof render === "string") { if (isCurrentMessage && inProgress) { return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)( AssistantMessage2, { rawData: message, message: render, "data-message-role": "assistant", isLoading: true, isGenerating: true }, index ); } else { return null; } } else { const state = message.state; let status = message.active ? "inProgress" : "complete"; const toRender = render({ status, state, nodeName: message.nodeName }); if (!toRender && status === "complete") { return null; } if (!toRender && isCurrentMessage && inProgress) { return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)( AssistantMessage2, { "data-message-role": "assistant", rawData: message, isLoading: true, isGenerating: true }, index ); } else if (!toRender) { return null; } if (typeof toRender === "string") { return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)( AssistantMessage2, { rawData: message, message: toRender, isLoading: true, isGenerating: true, "data-message-role": "assistant" }, index ); } else { return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)( AssistantMessage2, { rawData: message, "data-message-role": "agent-state-render", isLoading: false, isGenerating: false, subComponent: toRender }, index ); } } } else if (!inProgress || !isCurrentMessage) { return null; } else { return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)( AssistantMessage2, { rawData: message, isLoading: true, isGenerating: true, "data-message-role": "assistant" }, index ); } } } // src/components/chat/Markdown.tsx var import_react7 = require("react"); var import_react_markdown = __toESM(require("react-markdown")); // src/components/chat/CodeBlock.tsx var import_react6 = require("react"); var import_react_syntax_highlighter = require("react-syntax-highlighter"); // src/hooks/use-copy-to-clipboard.tsx var React4 = __toESM(require("react")); function useCopyToClipboard({ timeout = 2e3 }) { const [isCopied, setIsCopied] = React4.useState(false); const copyToClipboard = (value) => { var _a; if (typeof window === "undefined" || !((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) { return; } if (!value) { return; } navigator.clipboard.writeText(value).then(() => { setIsCopied(true); setTimeout(() => { setIsCopied(false); }, timeout); }); }; return { isCopied, copyToClipboard }; } // src/components/chat/CodeBlock.tsx var import_jsx_runtime10 = require("react/jsx-runtime"); var programmingLanguages = { javascript: ".js", python: ".py", java: ".java", c: ".c", cpp: ".cpp", "c++": ".cpp", "c#": ".cs", ruby: ".rb", php: ".php", swift: ".swift", "objective-c": ".m", kotlin: ".kt", typescript: ".ts", go: ".go", perl: ".pl", rust: ".rs", scala: ".scala", haskell: ".hs", lua: ".lua", shell: ".sh", sql: ".sql", html: ".html", css: ".css" // add more file extensions here, make sure the key is same as language prop in CodeBlock.tsx component }; var generateRandomString = (length, lowercase = false) => { const chars = "ABCDEFGHJKLMNPQRSTUVWXY3456789"; let result = ""; for (let i = 0; i < length; i++) { result += chars.charAt(Math.floor(Math.random() * chars.length)); } return lowercase ? result.toLowerCase() : result; }; var CodeBlock = (0, import_react6.memo)(({ language, value }) => { const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2e3 }); const downloadAsFile = () => { if (typeof window === "undefined") { return; } const fileExtension = programmingLanguages[language] || ".file"; const suggestedFileName = `file-${generateRandomString(3, true)}${fileExtension}`; const fileName = window.prompt("Enter file name", suggestedFileName); if (!fileName) { return; } const blob = new Blob([value], { type: "text/plain" }); const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.download = fileName; link.href = url; link.style.display = "none"; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); }; const onCopy = () => { if (isCopied) return; copyToClipboard(value); }; return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitCodeBlock", children: [ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitCodeBlockToolbar", children: [ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "copilotKitCodeBlockToolbarLanguage", children: language }), /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitCodeBlockToolbarButtons", children: [ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: downloadAsFile, children: DownloadIcon }), /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: onCopy, children: isCopied ? CheckIcon : CopyIcon }) ] }) ] }), /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( import_react_syntax_highlighter.Prism, { language, style: highlightStyle, PreTag: "div", customStyle: { margin: 0, borderBottomLeftRadius: "0.375rem", borderBottomRightRadius: "0.375rem" }, children: value } ) ] }); }); CodeBlock.displayName = "CodeBlock"; var highlightStyle = { 'pre[class*="language-"]': { color: "#d4d4d4", fontSize: "13px", textShadow: "none", fontFamily: 'Menlo, Monaco, Consolas, "Andale Mono", "Ubuntu Mono", "Courier New", monospace', direction: "ltr", textAlign: "left", whiteSpace: "pre", wordSpacing: "normal", wordBreak: "normal", lineHeight: "1.5", MozTabSize: "4", OTabSize: "4", tabSize: "4", WebkitHyphens: "none", MozHyphens: "none", msHyphens: "none", hyphens: "none", padding: "1em", margin: ".5em 0", overflow: "auto", background: "#1e1e1e" }, 'code[class*="language-"]': { color: "#d4d4d4", fontSize: "13px", textShadow: "none", fontFamily: 'Menlo, Monaco, Consolas, "Andale Mono", "Ubuntu Mono", "Courier New", monospace', direction: "ltr", textAlign: "left", whiteSpace: "pre", wordSpacing: "normal", wordBreak: "normal", lineHeight: "1.5", MozTabSize: "4", OTabSize: "4", tabSize: "4", WebkitHyphens: "none", MozHyphens: "none", msHyphens: "none", hyphens: "none" }, 'pre[class*="language-"]::selection': { textShadow: "none", background: "#264F78" }, 'code[class*="language-"]::selection': { textShadow: "none", background: "#264F78" }, 'pre[class*="language-"] *::selection': { textShadow: "none", background: "#264F78" }, 'code[class*="language-"] *::selection': { textShadow: "none", background: "#264F78" }, ':not(pre) > code[class*="language-"]': { padding: ".1em .3em", borderRadius: ".3em", color: "#db4c69", background: "#1e1e1e" }, ".namespace": { Opacity: ".7" }, "doctype.doctype-tag": { color: "#569CD6" }, "doctype.name": { color: "#9cdcfe" }, comment: { color: "#6a9955" }, prolog: { color: "#6a9955" }, punctuation: { color: "#d4d4d4" }, ".language-html .language-css .token.punctuation": { color: "#d4d4d4" }, ".language-html .language-javascript .token.punctuation": { color: "#d4d4d4" }, property: { color: "#9cdcfe" }, tag: { color: "#569cd6" }, boolean: { color: "#569cd6" }, number: { color: "#b5cea8" }, constant: { color: "#9cdcfe" }, symbol: { color: "#b5cea8" }, inserted: { color: "#b5cea8" }, unit: { color: "#b5cea8" }, selector: { color: "#d7ba7d" }, "attr-name": { color: "#9cdcfe" }, string: { color: "#ce9178" }, char: { color: "#ce9178" }, builtin: { color: "#ce9178" }, deleted: { color: "#ce9178" }, ".language-css .token.string.url": { textDecoration: "underline" }, operator: { color: "#d4d4d4" }, entity: { color: "#569cd6" }, "operator.arrow": { color: "#569CD6" }, atrule: { color: "#ce9178" }, "atrule.rule": { color: "#c586c0" }, "atrule.url": { color: "#9cdcfe" }, "atrule.url.function": { color: "#dcdcaa" }, "atrule.url.punctuation": { color: "#d4d4d4" }, keyword: { color: "#569CD6" }, "keyword.module": { color: "#c586c0" }, "keyword.control-flow": { color: "#c586c0" }, function: { color: "#dcdcaa" }, "function.maybe-class-name": { color: "#dcdcaa" }, regex: { color: "#d16969" }, important: { color: "#569cd6" }, italic: { fontStyle: "italic" }, "class-name": { color: "#4ec9b0" }, "maybe-class-name": { color: "#4ec9b0" }, console: { color: "#9cdcfe" }, parameter: { color: "#9cdcfe" }, interpolation: { color: "#9cdcfe" }, "punctuation.interpolation-punctuation": { color: "#569cd6" }, variable: { color: "#9cdcfe" }, "imports.maybe-class-name": { color: "#9cdcfe" }, "exports.maybe-class-name": { color: "#9cdcfe" }, escape: { color: "#d7ba7d" }, "tag.punctuation": { color: "#808080" }, cdata: { color: "#808080" }, "attr-value": { color: "#ce9178" }, "attr-value.punctuation": { color: "#ce9178" }, "attr-value.punctuation.attr-equals": { color: "#d4d4d4" }, namespace: { color: "#4ec9b0" }, 'pre[class*="language-javascript"]': { color: "#9cdcfe" }, 'code[class*="language-javascript"]': { color: "#9cdcfe" }, 'pre[class*="language-jsx"]': { color: "#9cdcfe" }, 'code[class*="language-jsx"]': { color: "#9cdcfe" }, 'pre[class*="language-typescript"]': { color: "#9cdcfe" }, 'code[class*="language-typescript"]': { color: "#9cdcfe" }, 'pre[class*="language-tsx"]': { color: "#9cdcfe" }, 'code[class*="language-tsx"]': { color: "#9cdcfe" }, 'pre[class*="language-css"]': { color: "#ce9178" }, 'code[class*="language-css"]': { color: "#ce9178" }, 'pre[class*="language-html"]': { color: "#d4d4d4" }, 'code[class*="language-html"]': { color: "#d4d4d4" }, ".language-regex .token.anchor": { color: "#dcdcaa" }, ".language-html .token.punctuation": { color: "#808080" }, 'pre[class*="language-"] > code[class*="language-"]': { position: "relative", zIndex: "1" }, ".line-highlight.line-highlight": { background: "#f7ebc6", boxShadow: "inset 5px 0 0 #f7d87c", zIndex: "0" } }; // src/components/chat/Markdown.tsx var import_remark_gfm = __toESM(require("remark-gfm")); var import_remark_math = __toESM(require("remark-math")); var import_jsx_runtime11 = require("react/jsx-runtime"); var MemoizedReactMarkdown = (0, import_react7.memo)( import_react_markdown.default, (prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.className === nextProps.className ); var Markdown = ({ content }) => { return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "copilotKitMarkdown", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MemoizedReactMarkdown, { components, remarkPlugins: [import_remark_gfm.default, import_remark_math.default], children: content }) }); }; var components = { a(_a) { var _b = _a, { children } = _b, props = __objRest(_b, ["children"]); return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)( "a", __spreadProps(__spreadValues({ style: { color: "blue", textDecoration: "underline" } }, props), { target: "_blank", rel: "noopener noreferrer", children }) ); }, code(_c) { var _d = _c, { children, className, inline } = _d, props = __objRest(_d, ["children", "className", "inline"]); if (children.length) { if (children[0] == "\u258D") { return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)( "span", { style: { animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite", marginT