UNPKG

@copilotkit/react-core

Version:

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

978 lines (960 loc) • 34.3 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/hooks/use-copilot-chat.ts var use_copilot_chat_exports = {}; __export(use_copilot_chat_exports, { useCopilotChat: () => useCopilotChat }); module.exports = __toCommonJS(use_copilot_chat_exports); // src/hooks/use-copilot-chat_internal.ts var import_react13 = require("react"); // src/context/copilot-context.tsx var import_react = __toESM(require("react")); var emptyCopilotContext = { actions: {}, setAction: () => { }, removeAction: () => { }, setRegisteredActions: () => "", removeRegisteredAction: () => { }, chatComponentsCache: { current: { actions: {}, coAgentStateRenders: {} } }, getContextString: (documents, categories) => returnAndThrowInDebug(""), addContext: () => "", removeContext: () => { }, getAllContext: () => [], getFunctionCallHandler: () => returnAndThrowInDebug(() => __async(void 0, null, function* () { })), isLoading: false, setIsLoading: () => returnAndThrowInDebug(false), chatInstructions: "", setChatInstructions: () => returnAndThrowInDebug(""), additionalInstructions: [], setAdditionalInstructions: () => returnAndThrowInDebug([]), getDocumentsContext: (categories) => returnAndThrowInDebug([]), addDocumentContext: () => returnAndThrowInDebug(""), removeDocumentContext: () => { }, copilotApiConfig: new class { get chatApiEndpoint() { throw new Error("Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!"); } get headers() { return {}; } get body() { return {}; } }(), chatSuggestionConfiguration: {}, addChatSuggestionConfiguration: () => { }, removeChatSuggestionConfiguration: () => { }, showDevConsole: false, coagentStates: {}, setCoagentStates: () => { }, coagentStatesRef: { current: {} }, setCoagentStatesWithRef: () => { }, agentSession: null, setAgentSession: () => { }, forwardedParameters: {}, agentLock: null, threadId: "", setThreadId: () => { }, runId: null, setRunId: () => { }, chatAbortControllerRef: { current: null }, availableAgents: [], extensions: {}, setExtensions: () => { }, interruptActions: {}, setInterruptAction: () => { }, removeInterruptAction: () => { }, interruptEventQueue: {}, addInterruptEvent: () => { }, resolveInterruptEvent: () => { }, onError: () => { }, bannerError: null, setBannerError: () => { }, internalErrorHandlers: {}, setInternalErrorHandler: () => { }, removeInternalErrorHandler: () => { } }; var CopilotContext = import_react.default.createContext(emptyCopilotContext); function useCopilotContext() { const context = import_react.default.useContext(CopilotContext); if (context === emptyCopilotContext) { throw new Error("Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!"); } return context; } function returnAndThrowInDebug(_value) { throw new Error("Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!"); } // src/components/error-boundary/error-utils.tsx var import_react3 = require("react"); // src/components/toast/toast-provider.tsx var import_react2 = require("react"); var import_shared = require("@copilotkit/shared"); var import_jsx_runtime = require("react/jsx-runtime"); var ToastContext = (0, import_react2.createContext)(void 0); function useToast() { const context = (0, import_react2.useContext)(ToastContext); if (!context) { throw new Error("useToast must be used within a ToastProvider"); } return context; } // src/components/toast/exclamation-mark-icon.tsx var import_jsx_runtime2 = require("react/jsx-runtime"); var ExclamationMarkIcon = ({ className, style }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)( "svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: `lucide lucide-circle-alert ${className ? className : ""}`, style, children: [ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "12", x2: "12", y1: "8", y2: "12" }), /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "12", x2: "12.01", y1: "16", y2: "16" }) ] } ); // src/components/error-boundary/error-utils.tsx var import_react_markdown = __toESM(require("react-markdown")); var import_jsx_runtime3 = require("react/jsx-runtime"); function ErrorToast({ errors }) { const errorsToRender = errors.map((error, idx) => { var _a, _b, _c; const originalError = "extensions" in error ? (_a = error.extensions) == null ? void 0 : _a.originalError : {}; const message = (_b = originalError == null ? void 0 : originalError.message) != null ? _b : error.message; const code = "extensions" in error ? (_c = error.extensions) == null ? void 0 : _c.code : null; return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)( "div", { style: { marginTop: idx === 0 ? 0 : 10, marginBottom: 14 }, children: [ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ExclamationMarkIcon, { style: { marginBottom: 4 } }), code && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)( "div", { style: { fontWeight: "600", marginBottom: 4 }, children: [ "Copilot Runtime Error:", " ", /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontFamily: "monospace", fontWeight: "normal" }, children: code }) ] } ), /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_markdown.default, { children: message }) ] }, idx ); }); return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)( "div", { style: { fontSize: "13px", maxWidth: "600px" }, children: [ errorsToRender, /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: "11px", opacity: 0.75 }, children: "NOTE: This error only displays during local development." }) ] } ); } function useErrorToast() { const { addToast } = useToast(); return (0, import_react3.useCallback)( (errors) => { const errorId = errors.map((err) => { var _a, _b; const message = "extensions" in err ? ((_b = (_a = err.extensions) == null ? void 0 : _a.originalError) == null ? void 0 : _b.message) || err.message : err.message; const stack = err.stack || ""; return btoa(message + stack).slice(0, 32); }).join("|"); addToast({ type: "error", id: errorId, // Toast libraries typically dedupe by id message: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ErrorToast, { errors }) }); }, [addToast] ); } function useAsyncCallback(callback, deps) { const addErrorToast = useErrorToast(); return (0, import_react3.useCallback)((...args) => __async(this, null, function* () { try { return yield callback(...args); } catch (error) { console.error("Error in async callback:", error); addErrorToast([error]); throw error; } }), deps); } // src/hooks/use-copilot-chat_internal.ts var import_runtime_client_gql2 = require("@copilotkit/runtime-client-gql"); // src/context/coagent-state-renders-context.tsx var import_react4 = require("react"); var import_jsx_runtime4 = require("react/jsx-runtime"); var CoAgentStateRendersContext = (0, import_react4.createContext)( void 0 ); function useCoAgentStateRenders() { const context = (0, import_react4.useContext)(CoAgentStateRendersContext); if (!context) { throw new Error("useCoAgentStateRenders must be used within CoAgentStateRendersProvider"); } return context; } // src/hooks/use-langgraph-interrupt-render.ts var import_react7 = __toESM(require("react")); var import_runtime_client_gql = require("@copilotkit/runtime-client-gql"); var import_shared2 = require("@copilotkit/shared"); // src/hooks/use-agent-nodename.ts var import_react5 = require("react"); var import_react6 = require("@copilotkitnext/react"); function useAgentNodeName(agentName) { const { agent } = (0, import_react6.useAgent)({ agentId: agentName }); const nodeNameRef = (0, import_react5.useRef)("start"); (0, import_react5.useEffect)(() => { if (!agent) return; const subscriber = { onStepStartedEvent: ({ event }) => { nodeNameRef.current = event.stepName; }, onRunStartedEvent: () => { nodeNameRef.current = "start"; }, onRunFinishedEvent: () => { nodeNameRef.current = "end"; } }; const subscription = agent.subscribe(subscriber); return () => { subscription.unsubscribe(); }; }, [agent]); return nodeNameRef.current; } // src/hooks/use-langgraph-interrupt-render.ts var import_react8 = require("@copilotkitnext/react"); var InterruptRenderer = ({ event, result, render, resolve }) => { return render({ event, result, resolve }); }; function useLangGraphInterruptRender(agent) { var _a; const { interruptActions, agentSession, threadId, interruptEventQueue, addInterruptEvent, resolveInterruptEvent } = useCopilotContext(); const existingConfig = (0, import_react8.useCopilotChatConfiguration)(); const resolvedAgentId = (_a = existingConfig == null ? void 0 : existingConfig.agentId) != null ? _a : "default"; const nodeName = useAgentNodeName(resolvedAgentId); (0, import_react7.useEffect)(() => { if (!agent) return; let localInterrupt = null; const subscriber = { onCustomEvent: ({ event }) => { if (event.name === "on_interrupt") { const eventData = { name: import_runtime_client_gql.MetaEventName.LangGraphInterruptEvent, type: event.type, value: (0, import_shared2.parseJson)(event.value, event.value) }; const eventId = (0, import_shared2.dataToUUID)(eventData, "interruptEvents"); localInterrupt = { eventId, threadId, event: eventData }; } }, onRunStartedEvent: () => { localInterrupt = null; }, onRunFinalized: () => { if (localInterrupt) { addInterruptEvent(localInterrupt); localInterrupt = null; } } }; const { unsubscribe } = agent.subscribe(subscriber); return () => { unsubscribe(); }; }, [agent, threadId]); const handleResolve = (0, import_react7.useCallback)( (eventId, response) => { agent == null ? void 0 : agent.runAgent({ forwardedProps: { command: { resume: response } } }); resolveInterruptEvent(threadId, eventId, response != null ? response : ""); }, // eslint-disable-next-line react-hooks/exhaustive-deps [agent, threadId] ); return (0, import_react7.useMemo)(() => { const eventQueue = interruptEventQueue[threadId] || []; const currentQueuedEvent = eventQueue.find((qe) => !qe.event.response); if (!currentQueuedEvent || !agentSession) return null; const allActions = Object.values(interruptActions); const matchingAction = allActions.find((action) => { if (!action.enabled) return true; return action.enabled({ eventValue: currentQueuedEvent.event.value, agentMetadata: __spreadProps(__spreadValues({}, agentSession), { nodeName }) }); }); if (!matchingAction) return null; const { render, handler } = matchingAction; const resolveInterrupt = (response) => { handleResolve(currentQueuedEvent.eventId, response); }; let result = null; if (handler) { result = handler({ event: currentQueuedEvent.event, resolve: resolveInterrupt }); } if (!render) return null; return import_react7.default.createElement(InterruptRenderer, { event: currentQueuedEvent.event, result, render, resolve: resolveInterrupt }); }, [interruptActions, interruptEventQueue, threadId, agentSession, handleResolve]); } // src/hooks/use-copilot-chat_internal.ts var import_react14 = require("@copilotkitnext/react"); // src/hooks/use-lazy-tool-renderer.tsx var import_react9 = require("@copilotkitnext/react"); var import_react10 = require("react"); function useLazyToolRenderer() { const renderToolCall = (0, import_react9.useRenderToolCall)(); return (0, import_react10.useCallback)( (message, messages) => { var _a; if (!((_a = message == null ? void 0 : message.toolCalls) == null ? void 0 : _a.length)) return null; const toolCall = message.toolCalls[0]; if (!toolCall) return null; const toolMessage = messages == null ? void 0 : messages.find( (m) => m.role === "tool" && m.toolCallId === toolCall.id ); return () => renderToolCall({ toolCall, toolMessage }); }, [renderToolCall] ); } // src/hooks/use-copilot-chat_internal.ts var import_client = require("@ag-ui/client"); // src/hooks/use-coagent-state-render-bridge.tsx var import_react11 = require("@copilotkitnext/react"); var import_react12 = require("react"); var import_shared3 = require("@copilotkit/shared"); function getStateWithoutConstantKeys(state) { if (!state) return {}; const _a = state, { messages, tools, copilotkit } = _a, stateWithoutConstantKeys = __objRest(_a, ["messages", "tools", "copilotkit"]); return stateWithoutConstantKeys; } function areStatesEquals(a, b) { if (a && !b || !a && b) return false; const _a = a, { messages, tools, copilotkit } = _a, aWithoutConstantKeys = __objRest(_a, ["messages", "tools", "copilotkit"]); const _b = b, { messages: bMessages, tools: bTools, copilotkit: bCopilotkit } = _b, bWithoutConstantKeys = __objRest(_b, [ "messages", "tools", "copilotkit" ]); return JSON.stringify(aWithoutConstantKeys) === JSON.stringify(bWithoutConstantKeys); } function useCoagentStateRenderBridge(agentId, props) { var _a; const { stateSnapshot, messageIndexInRun, message } = props; const { coAgentStateRenders, claimsRef } = useCoAgentStateRenders(); const { agent } = (0, import_react11.useAgent)({ agentId }); const [nodeName, setNodeName] = (0, import_react12.useState)(void 0); const runId = (_a = props.runId) != null ? _a : message.runId; const effectiveRunId = runId || "pending"; (0, import_react12.useEffect)(() => { if (!agent) return; const subscriber = { onStepStartedEvent: ({ event }) => { if (event.stepName !== nodeName) { setNodeName(event.stepName); } }, onStepFinishedEvent: ({ event }) => { if (event.stepName === nodeName) { setNodeName(void 0); } } }; const { unsubscribe } = agent.subscribe(subscriber); return () => { unsubscribe(); }; }, [agentId, nodeName]); const getStateRender = (0, import_react12.useCallback)( (messageId) => { return Object.entries(coAgentStateRenders).find(([stateRenderId, stateRender]) => { if (claimsRef.current[messageId]) { return stateRenderId === claimsRef.current[messageId].stateRenderId; } const matchingAgentName = stateRender.name === agentId; const matchesNodeContext = stateRender.nodeName ? stateRender.nodeName === nodeName : true; return matchingAgentName && matchesNodeContext; }); }, [coAgentStateRenders, nodeName, agentId] ); const handleRenderRequest = ({ stateRenderId, messageId, runId: runId2, stateSnapshot: renderSnapshot }) => { if (claimsRef.current[messageId]) { const canRender = claimsRef.current[messageId].stateRenderId === stateRenderId; if (canRender && runId2 && (!claimsRef.current[messageId].runId || claimsRef.current[messageId].runId === "pending")) { claimsRef.current[messageId].runId = runId2; } return canRender; } const renderClaimedByOtherMessage = Object.values(claimsRef.current).find( (c) => c.stateRenderId === stateRenderId && (0, import_shared3.dataToUUID)(getStateWithoutConstantKeys(c.stateSnapshot)) === (0, import_shared3.dataToUUID)(getStateWithoutConstantKeys(renderSnapshot)) ); if (renderClaimedByOtherMessage) { if (renderSnapshot && renderClaimedByOtherMessage.stateSnapshot && !areStatesEquals(renderClaimedByOtherMessage.stateSnapshot, renderSnapshot)) { claimsRef.current[messageId] = { stateRenderId, runId: runId2 }; return true; } return false; } if (!runId2) { return false; } claimsRef.current[messageId] = { stateRenderId, runId: runId2 }; return true; }; return (0, import_react12.useMemo)(() => { var _a2, _b, _c; if (messageIndexInRun !== 0) { return null; } const [stateRenderId, stateRender] = (_a2 = getStateRender(message.id)) != null ? _a2 : []; if (!stateRender || !stateRenderId) { return null; } const snapshot = stateSnapshot ? (0, import_shared3.parseJson)(stateSnapshot, stateSnapshot) : agent == null ? void 0 : agent.state; const canRender = handleRenderRequest({ stateRenderId, messageId: message.id, runId: effectiveRunId, stateSnapshot: snapshot }); if (!canRender) { return null; } if (snapshot && !claimsRef.current[message.id].locked) { if (stateSnapshot) { claimsRef.current[message.id].stateSnapshot = snapshot; claimsRef.current[message.id].locked = true; } else { claimsRef.current[message.id].stateSnapshot = snapshot; } } if (stateRender.handler) { stateRender.handler({ state: stateSnapshot ? (0, import_shared3.parseJson)(stateSnapshot, stateSnapshot) : (_b = agent == null ? void 0 : agent.state) != null ? _b : {}, nodeName: nodeName != null ? nodeName : "" }); } if (stateRender.render) { const status = (agent == null ? void 0 : agent.isRunning) ? "inProgress" : "complete"; if (typeof stateRender.render === "string") return stateRender.render; return stateRender.render({ status, // Always use state from claim, to make sure the state does not seem "wiped" for a fraction of a second state: (_c = claimsRef.current[message.id].stateSnapshot) != null ? _c : {}, nodeName: nodeName != null ? nodeName : "" }); } }, [ getStateRender, stateSnapshot, agent == null ? void 0 : agent.state, agent == null ? void 0 : agent.isRunning, nodeName, effectiveRunId, message.id, messageIndexInRun ]); } function CoAgentStateRenderBridge(props) { return useCoagentStateRenderBridge(props.agentId, props); } // src/hooks/use-copilot-chat_internal.ts function useCopilotChatInternal({ suggestions, onInProgress, onSubmitMessage, onStopGeneration, onReloadMessages } = {}) { var _a, _b, _c; const { copilotkit } = (0, import_react14.useCopilotKit)(); const { threadId, agentSession } = useCopilotContext(); const existingConfig = (0, import_react14.useCopilotChatConfiguration)(); const [agentAvailable, setAgentAvailable] = (0, import_react13.useState)(false); const resolvedAgentId = (_a = existingConfig == null ? void 0 : existingConfig.agentId) != null ? _a : "default"; const { agent } = (0, import_react14.useAgent)({ agentId: resolvedAgentId }); (0, import_react13.useEffect)(() => { const connect = (agent2) => __async(this, null, function* () { setAgentAvailable(false); try { yield copilotkit.connectAgent({ agent: agent2 }); setAgentAvailable(true); } catch (error) { if (error instanceof import_client.AGUIConnectNotImplementedError) { } else { throw error; } } }); if (agent && (existingConfig == null ? void 0 : existingConfig.threadId) && agent.threadId !== existingConfig.threadId) { agent.threadId = existingConfig.threadId; connect(agent); } return () => { }; }, [existingConfig == null ? void 0 : existingConfig.threadId, agent, copilotkit, resolvedAgentId]); (0, import_react13.useEffect)(() => { onInProgress == null ? void 0 : onInProgress(Boolean(agent == null ? void 0 : agent.isRunning)); }, [agent == null ? void 0 : agent.isRunning, onInProgress]); const interrupt = useLangGraphInterruptRender(agent); const reset = () => { agent == null ? void 0 : agent.setMessages([]); agent == null ? void 0 : agent.setState(null); }; const deleteMessage = (0, import_react13.useCallback)( (messageId) => { var _a2; const filteredMessages = ((_a2 = agent == null ? void 0 : agent.messages) != null ? _a2 : []).filter( (message) => message.id !== messageId ); agent == null ? void 0 : agent.setMessages(filteredMessages); }, [agent == null ? void 0 : agent.setMessages, agent == null ? void 0 : agent.messages] ); const latestDelete = useUpdatedRef(deleteMessage); const latestDeleteFunc = (0, import_react13.useCallback)( (messageId) => { return latestDelete.current(messageId); }, [latestDelete] ); const currentSuggestions = (0, import_react14.useSuggestions)({ agentId: resolvedAgentId }); const reload = useAsyncCallback( (reloadMessageId) => __async(this, null, function* () { var _a2; const messages = (_a2 = agent == null ? void 0 : agent.messages) != null ? _a2 : []; const isLoading = false; if (isLoading || messages.length === 0) { return; } const reloadMessageIndex = messages.findIndex((msg) => msg.id === reloadMessageId); if (reloadMessageIndex === -1) { console.warn(`Message with id ${reloadMessageId} not found`); return; } const reloadMessageRole = messages[reloadMessageIndex].role; if (reloadMessageRole !== "assistant") { console.warn(`Regenerate cannot be performed on ${reloadMessageRole} role`); return; } let historyCutoff = [messages[0]]; if (messages.length > 2 && reloadMessageIndex !== 0) { const lastUserMessageBeforeRegenerate = messages.slice(0, reloadMessageIndex).reverse().find((msg) => msg.role === "user"); if (!lastUserMessageBeforeRegenerate) { historyCutoff = [messages[0]]; } else { const indexOfLastUserMessageBeforeRegenerate = messages.findIndex( (msg) => msg.id === lastUserMessageBeforeRegenerate.id ); historyCutoff = messages.slice(0, indexOfLastUserMessageBeforeRegenerate + 1); } } else if (messages.length > 2 && reloadMessageIndex === 0) { historyCutoff = [messages[0], messages[1]]; } agent == null ? void 0 : agent.setMessages(historyCutoff); if (agent) { copilotkit.runAgent({ agent }); } return; }), [agent == null ? void 0 : agent.setMessages, copilotkit == null ? void 0 : copilotkit.runAgent] ); const latestSendMessageFunc = useAsyncCallback( (message, options) => __async(this, null, function* () { var _a2; if (!agent) return; const followUp = (_a2 = options == null ? void 0 : options.followUp) != null ? _a2 : true; if (options == null ? void 0 : options.clearSuggestions) { copilotkit.clearSuggestions(resolvedAgentId); } agent == null ? void 0 : agent.addMessage(message); if (followUp) { try { yield copilotkit.runAgent({ agent }); } catch (error) { console.error("CopilotChat: runAgent failed", error); } } if (onSubmitMessage) { const content = typeof message.content === "string" ? message.content : message.content && "text" in message.content ? message.content.text : message.content && "filename" in message.content ? message.content.filename : ""; onSubmitMessage(content); } }), [agent, copilotkit, resolvedAgentId, onSubmitMessage] ); const latestAppendFunc = useAsyncCallback( (message, options) => __async(this, null, function* () { return latestSendMessageFunc((0, import_runtime_client_gql2.gqlToAGUI)([message])[0], options); }), [latestSendMessageFunc] ); const latestSetMessagesFunc = (0, import_react13.useCallback)( (messages) => { var _a2, _b2; if (messages.every((message) => message instanceof import_runtime_client_gql2.Message)) { return (_a2 = agent == null ? void 0 : agent.setMessages) == null ? void 0 : _a2.call(agent, (0, import_runtime_client_gql2.gqlToAGUI)(messages)); } return (_b2 = agent == null ? void 0 : agent.setMessages) == null ? void 0 : _b2.call(agent, messages); }, [agent == null ? void 0 : agent.setMessages, agent] ); const latestReload = useUpdatedRef(reload); const latestReloadFunc = useAsyncCallback( (messageId) => __async(this, null, function* () { var _a2; onReloadMessages == null ? void 0 : onReloadMessages({ messageId, currentAgentName: agent == null ? void 0 : agent.agentId, messages: (_a2 = agent == null ? void 0 : agent.messages) != null ? _a2 : [] }); return yield latestReload.current(messageId); }), [latestReload, agent, onReloadMessages] ); const latestStopFunc = (0, import_react13.useCallback)(() => { var _a2, _b2; onStopGeneration == null ? void 0 : onStopGeneration({ currentAgentName: agent == null ? void 0 : agent.agentId, messages: (_a2 = agent == null ? void 0 : agent.messages) != null ? _a2 : [] }); return (_b2 = agent == null ? void 0 : agent.abortRun) == null ? void 0 : _b2.call(agent); }, [onStopGeneration, agent]); const latestReset = useUpdatedRef(reset); const latestResetFunc = (0, import_react13.useCallback)(() => { return latestReset.current(); }, [latestReset]); const lazyToolRendered = useLazyToolRenderer(); const renderCustomMessage = (0, import_react14.useRenderCustomMessages)(); const legacyCustomMessageRenderer = useLegacyCoagentRenderer({ copilotkit, agent, agentId: resolvedAgentId, threadId: (_b = existingConfig == null ? void 0 : existingConfig.threadId) != null ? _b : threadId }); const allMessages = (_c = agent == null ? void 0 : agent.messages) != null ? _c : []; const resolvedMessages = (0, import_react13.useMemo)(() => { let processedMessages = allMessages.map((message) => { if (message.role !== "assistant") { return message; } const lazyRendered = lazyToolRendered(message, allMessages); if (lazyRendered) { const renderedGenUi = lazyRendered(); if (renderedGenUi) { return __spreadProps(__spreadValues({}, message), { generativeUI: () => renderedGenUi }); } } const bridgeRenderer = legacyCustomMessageRenderer || renderCustomMessage ? () => { const customRender = renderCustomMessage == null ? void 0 : renderCustomMessage({ message, position: "before" }); if (customRender) { return customRender; } return legacyCustomMessageRenderer == null ? void 0 : legacyCustomMessageRenderer({ message, position: "before" }); } : null; if (bridgeRenderer) { return __spreadProps(__spreadValues({}, message), { generativeUI: bridgeRenderer }); } return message; }); const hasAssistantMessages = processedMessages.some((msg) => msg.role === "assistant"); return processedMessages; }, [ agent == null ? void 0 : agent.messages, lazyToolRendered, allMessages, renderCustomMessage, // legacyCustomMessageRenderer, resolvedAgentId ]); const renderedSuggestions = (0, import_react13.useMemo)(() => { if (Array.isArray(suggestions)) { return { suggestions: suggestions.map((s) => __spreadProps(__spreadValues({}, s), { isLoading: false })), isLoading: false }; } return currentSuggestions; }, [suggestions, currentSuggestions]); return { messages: resolvedMessages, sendMessage: latestSendMessageFunc, appendMessage: latestAppendFunc, setMessages: latestSetMessagesFunc, reloadMessages: latestReloadFunc, stopGeneration: latestStopFunc, reset: latestResetFunc, deleteMessage: latestDeleteFunc, isAvailable: agentAvailable, isLoading: Boolean(agent == null ? void 0 : agent.isRunning), // mcpServers, // setMcpServers, suggestions: renderedSuggestions.suggestions, setSuggestions: (suggestions2) => copilotkit.addSuggestionsConfig({ suggestions: suggestions2 }), generateSuggestions: () => __async(this, null, function* () { return copilotkit.reloadSuggestions(resolvedAgentId); }), resetSuggestions: () => copilotkit.clearSuggestions(resolvedAgentId), isLoadingSuggestions: renderedSuggestions.isLoading, interrupt, agent, threadId }; } function useUpdatedRef(value) { const ref = (0, import_react13.useRef)(value); (0, import_react13.useEffect)(() => { ref.current = value; }, [value]); return ref; } function useLegacyCoagentRenderer({ copilotkit, agent, agentId, threadId }) { return (0, import_react13.useMemo)(() => { if (!copilotkit || !agent) { return null; } return ({ message, position }) => { var _a; const effectiveThreadId = (_a = threadId != null ? threadId : agent.threadId) != null ? _a : "default"; const existingRunId = copilotkit.getRunIdForMessage(agentId, effectiveThreadId, message.id); const runId = existingRunId || `pending:${message.id}`; const messageIndex = Math.max( agent.messages.findIndex((msg) => msg.id === message.id), 0 ); const bridgeProps = { message, position, runId, messageIndex, messageIndexInRun: 0, numberOfMessagesInRun: 1, agentId, stateSnapshot: message.state }; return (0, import_react13.createElement)(CoAgentStateRenderBridge, bridgeProps); }; }, [agent, agentId, copilotkit, threadId]); } // src/hooks/use-copilot-chat.ts function useCopilotChat(options = {}) { const { visibleMessages, appendMessage, reloadMessages, stopGeneration, reset, isLoading, isAvailable, runChatCompletion, mcpServers, setMcpServers } = useCopilotChatInternal(options); return { visibleMessages, appendMessage, reloadMessages, stopGeneration, reset, isLoading, isAvailable, runChatCompletion, mcpServers, setMcpServers }; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { useCopilotChat }); //# sourceMappingURL=use-copilot-chat.js.map