UNPKG

@copilotkit/react-ui

Version:

<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />

474 lines (472 loc) • 14.7 kB
import { RenderActionExecutionMessage } from "./chunk-53CVDVS5.mjs"; import { RenderAgentStateMessage } from "./chunk-2II3Q27P.mjs"; import { RenderImageMessage } from "./chunk-ULDQXCED.mjs"; import { RenderResultMessage } from "./chunk-C7OB63U5.mjs"; import { RenderTextMessage } from "./chunk-32MUWKL3.mjs"; import { AssistantMessage } from "./chunk-L3GZ7TXC.mjs"; import { UserMessage } from "./chunk-HWMFMBJC.mjs"; import { Suggestions } from "./chunk-QGSPTXOV.mjs"; import { reloadSuggestions } from "./chunk-IMBPSLL4.mjs"; import { ImageUploadQueue } from "./chunk-PLHTVHUW.mjs"; import { Input } from "./chunk-4HUXYD3B.mjs"; import { Messages } from "./chunk-B3D7U7TJ.mjs"; import { ChatContext, ChatContextProvider } from "./chunk-IEMQ2SQW.mjs"; import { __async, __spreadProps, __spreadValues } from "./chunk-MRXNTQOX.mjs"; // src/components/chat/Chat.tsx import React, { useEffect, useRef, useState } from "react"; import { useCopilotChat, useCopilotContext, useCopilotMessagesContext } from "@copilotkit/react-core"; import { Role, TextMessage, ImageMessage } from "@copilotkit/runtime-client-gql"; import { randomId } from "@copilotkit/shared"; import { runAgent, stopAgent } from "@copilotkit/react-core"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; function CopilotChat({ instructions, onSubmitMessage, makeSystemMessage, onInProgress, onStopGeneration, onReloadMessages, onRegenerate, onCopy, onThumbsUp, onThumbsDown, markdownTagRenderers, Messages: Messages2 = Messages, RenderTextMessage: RenderTextMessage2 = RenderTextMessage, RenderActionExecutionMessage: RenderActionExecutionMessage2 = RenderActionExecutionMessage, RenderAgentStateMessage: RenderAgentStateMessage2 = RenderAgentStateMessage, RenderResultMessage: RenderResultMessage2 = RenderResultMessage, RenderImageMessage: RenderImageMessage2 = RenderImageMessage, RenderSuggestionsList = Suggestions, Input: Input2 = Input, className, icons, labels, AssistantMessage: AssistantMessage2 = AssistantMessage, UserMessage: UserMessage2 = UserMessage, imageUploadsEnabled, inputFileAccept = "image/*", hideStopButton }) { const { additionalInstructions, setChatInstructions } = useCopilotContext(); const [selectedImages, setSelectedImages] = useState([]); const fileInputRef = useRef(null); useEffect(() => { if (!imageUploadsEnabled) return; const handlePaste = (e) => __async(this, null, function* () { var _a, _b; const target = e.target; if (!((_a = target.parentElement) == null ? void 0 : _a.classList.contains("copilotKitInput"))) return; const items = Array.from(((_b = e.clipboardData) == null ? void 0 : _b.items) || []); const imageItems = items.filter((item) => item.type.startsWith("image/")); if (imageItems.length === 0) return; e.preventDefault(); const imagePromises = imageItems.map((item) => { const file = item.getAsFile(); if (!file) return Promise.resolve(null); return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e2) => { var _a2, _b2; const base64String = (_b2 = (_a2 = e2.target) == null ? void 0 : _a2.result) == null ? void 0 : _b2.split(",")[1]; if (base64String) { resolve({ contentType: file.type, bytes: base64String }); } else { resolve(null); } }; reader.onerror = reject; reader.readAsDataURL(file); }); }); try { const loadedImages = (yield Promise.all(imagePromises)).filter((img) => img !== null); setSelectedImages((prev) => [...prev, ...loadedImages]); } catch (error) { console.error("Error processing pasted images:", error); } }); document.addEventListener("paste", handlePaste); return () => document.removeEventListener("paste", handlePaste); }, [imageUploadsEnabled]); useEffect(() => { if (!(additionalInstructions == null ? void 0 : additionalInstructions.length)) { setChatInstructions(instructions || ""); return; } const combinedAdditionalInstructions = [ instructions, "Additionally, follow these instructions:", ...additionalInstructions.map((instruction) => `- ${instruction}`) ]; console.log("combinedAdditionalInstructions", combinedAdditionalInstructions); setChatInstructions(combinedAdditionalInstructions.join("\n") || ""); }, [instructions, additionalInstructions]); const { visibleMessages, isLoading, currentSuggestions, sendMessage, stopGeneration, reloadMessages } = useCopilotChatLogic( makeSystemMessage, onInProgress, onSubmitMessage, onStopGeneration, onReloadMessages ); const handleSendMessage = (text) => { const images = selectedImages; setSelectedImages([]); if (fileInputRef.current) { fileInputRef.current.value = ""; } return sendMessage(text, images); }; const chatContext = React.useContext(ChatContext); const isVisible = chatContext ? chatContext.open : true; const handleRegenerate = (messageId) => { if (onRegenerate) { onRegenerate(messageId); } reloadMessages(messageId); }; const handleCopy = (message) => { if (onCopy) { onCopy(message); } }; const handleImageUpload = (event) => __async(this, null, function* () { if (!event.target.files || event.target.files.length === 0) { return; } const files = Array.from(event.target.files).filter((file) => file.type.startsWith("image/")); if (files.length === 0) return; const fileReadPromises = files.map((file) => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => { var _a, _b; const base64String = ((_b = (_a = e.target) == null ? void 0 : _a.result) == null ? void 0 : _b.split(",")[1]) || ""; if (base64String) { resolve({ contentType: file.type, bytes: base64String }); } }; reader.onerror = reject; reader.readAsDataURL(file); }); }); try { const loadedImages = yield Promise.all(fileReadPromises); setSelectedImages((prev) => [...prev, ...loadedImages]); } catch (error) { console.error("Error reading files:", error); } }); const removeSelectedImage = (index) => { setSelectedImages((prev) => prev.filter((_, i) => i !== index)); }; return /* @__PURE__ */ jsxs(WrappedCopilotChat, { icons, labels, className, children: [ /* @__PURE__ */ jsx( Messages2, { AssistantMessage: AssistantMessage2, UserMessage: UserMessage2, RenderTextMessage: RenderTextMessage2, RenderActionExecutionMessage: RenderActionExecutionMessage2, RenderAgentStateMessage: RenderAgentStateMessage2, RenderResultMessage: RenderResultMessage2, RenderImageMessage: RenderImageMessage2, messages: visibleMessages, inProgress: isLoading, onRegenerate: handleRegenerate, onCopy: handleCopy, onThumbsUp, onThumbsDown, markdownTagRenderers, children: currentSuggestions.length > 0 && /* @__PURE__ */ jsx( RenderSuggestionsList, { onSuggestionClick: handleSendMessage, suggestions: currentSuggestions } ) } ), imageUploadsEnabled && /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(ImageUploadQueue, { images: selectedImages, onRemoveImage: removeSelectedImage }), /* @__PURE__ */ jsx( "input", { type: "file", multiple: true, ref: fileInputRef, onChange: handleImageUpload, accept: inputFileAccept, style: { display: "none" } } ) ] }), /* @__PURE__ */ jsx( Input2, { inProgress: isLoading, onSend: handleSendMessage, isVisible, onStop: stopGeneration, onUpload: imageUploadsEnabled ? () => { var _a; return (_a = fileInputRef.current) == null ? void 0 : _a.click(); } : void 0, hideStopButton } ) ] }); } function WrappedCopilotChat({ children, icons, labels, className }) { const chatContext = React.useContext(ChatContext); if (!chatContext) { return /* @__PURE__ */ jsx(ChatContextProvider, { icons, labels, open: true, setOpen: () => { }, children: /* @__PURE__ */ jsx("div", { className: `copilotKitChat ${className != null ? className : ""}`, children }) }); } return /* @__PURE__ */ jsx(Fragment, { children }); } var SUGGESTIONS_DEBOUNCE_TIMEOUT = 1e3; var useCopilotChatLogic = (makeSystemMessage, onInProgress, onSubmitMessage, onStopGeneration, onReloadMessages) => { var _a; const { visibleMessages, appendMessage, reloadMessages: defaultReloadMessages, stopGeneration: defaultStopGeneration, runChatCompletion, isLoading } = useCopilotChat({ id: randomId(), makeSystemMessage }); const [currentSuggestions, setCurrentSuggestions] = useState([]); const suggestionsAbortControllerRef = useRef(null); const debounceTimerRef = useRef(); const abortSuggestions = () => { var _a2; (_a2 = suggestionsAbortControllerRef.current) == null ? void 0 : _a2.abort(); suggestionsAbortControllerRef.current = null; }; const generalContext = useCopilotContext(); const messagesContext = useCopilotMessagesContext(); const context = __spreadValues(__spreadValues({}, generalContext), messagesContext); useEffect(() => { onInProgress == null ? void 0 : onInProgress(isLoading); abortSuggestions(); debounceTimerRef.current = setTimeout( () => { if (!isLoading && Object.keys(context.chatSuggestionConfiguration).length !== 0) { suggestionsAbortControllerRef.current = new AbortController(); reloadSuggestions( context, context.chatSuggestionConfiguration, setCurrentSuggestions, suggestionsAbortControllerRef ); } }, currentSuggestions.length == 0 ? 0 : SUGGESTIONS_DEBOUNCE_TIMEOUT ); return () => { clearTimeout(debounceTimerRef.current); }; }, [ isLoading, context.chatSuggestionConfiguration, // hackish way to trigger suggestions reload on reset, but better than moving suggestions to the // global context visibleMessages.length == 0 ]); const sendMessage = (messageContent, imagesToUse) => __async(void 0, null, function* () { const images = imagesToUse || []; abortSuggestions(); setCurrentSuggestions([]); let firstMessage = null; if (messageContent.trim().length > 0) { const textMessage = new TextMessage({ content: messageContent, role: Role.User }); if (onSubmitMessage) { try { yield onSubmitMessage(messageContent); } catch (error) { console.error("Error in onSubmitMessage:", error); } } yield appendMessage(textMessage, { followUp: images.length === 0 }); if (!firstMessage) { firstMessage = textMessage; } } if (images.length > 0) { for (let i = 0; i < images.length; i++) { const imageMessage = new ImageMessage({ format: images[i].contentType.replace("image/", ""), bytes: images[i].bytes, role: Role.User }); yield appendMessage(imageMessage, { followUp: i === images.length - 1 }); if (!firstMessage) { firstMessage = imageMessage; } } } if (!firstMessage) { return new TextMessage({ content: "", role: Role.User }); } return firstMessage; }); const messages = visibleMessages; const { setMessages } = messagesContext; const currentAgentName = (_a = generalContext.agentSession) == null ? void 0 : _a.agentName; const restartCurrentAgent = (hint) => __async(void 0, null, function* () { if (generalContext.agentSession) { generalContext.setAgentSession(__spreadProps(__spreadValues({}, generalContext.agentSession), { nodeName: void 0, threadId: void 0 })); generalContext.setCoagentStates((prevAgentStates) => { return __spreadProps(__spreadValues({}, prevAgentStates), { [generalContext.agentSession.agentName]: __spreadProps(__spreadValues({}, prevAgentStates[generalContext.agentSession.agentName]), { threadId: void 0, nodeName: void 0, runId: void 0 }) }); }); } }); const runCurrentAgent = (hint) => __async(void 0, null, function* () { if (generalContext.agentSession) { yield runAgent( generalContext.agentSession.agentName, context, appendMessage, runChatCompletion, hint ); } }); const stopCurrentAgent = () => { if (generalContext.agentSession) { stopAgent(generalContext.agentSession.agentName, context); } }; const setCurrentAgentState = (state) => { if (generalContext.agentSession) { generalContext.setCoagentStates((prevAgentStates) => { return __spreadProps(__spreadValues({}, prevAgentStates), { [generalContext.agentSession.agentName]: { state } }); }); } }; function stopGeneration() { if (onStopGeneration) { onStopGeneration({ messages, setMessages, stopGeneration: defaultStopGeneration, currentAgentName, restartCurrentAgent, stopCurrentAgent, runCurrentAgent, setCurrentAgentState }); } else { defaultStopGeneration(); } } function reloadMessages(messageId) { if (onReloadMessages) { onReloadMessages({ messages, setMessages, stopGeneration: defaultStopGeneration, currentAgentName, restartCurrentAgent, stopCurrentAgent, runCurrentAgent, setCurrentAgentState, messageId }); } else { defaultReloadMessages(messageId); } } return { visibleMessages, isLoading, currentSuggestions, sendMessage, stopGeneration, reloadMessages }; }; export { CopilotChat, WrappedCopilotChat, useCopilotChatLogic }; //# sourceMappingURL=chunk-HKTWKCPS.mjs.map