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;" />

1,351 lines (1,330 loc) • 79.9 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/index.ts var hooks_exports = {}; __export(hooks_exports, { useCoAgent: () => useCoAgent, useCoAgentStateRender: () => useCoAgentStateRender, useCopilotAction: () => useCopilotAction, useCopilotAdditionalInstructions: () => useCopilotAdditionalInstructions, useCopilotAuthenticatedAction_c: () => useCopilotAuthenticatedAction_c, useCopilotChat: () => useCopilotChat, useCopilotChatHeadless_c: () => useCopilotChatHeadless_c, useCopilotChatInternal: () => useCopilotChatInternal, useCopilotChatSuggestions: () => useCopilotChatSuggestions, useCopilotReadable: () => useCopilotReadable, useCopilotRuntimeClient: () => useCopilotRuntimeClient, useDefaultTool: () => useDefaultTool, useFrontendTool: () => useFrontendTool, useHumanInTheLoop: () => useHumanInTheLoop, useLangGraphInterrupt: () => useLangGraphInterrupt, useLangGraphInterruptRender: () => useLangGraphInterruptRender, useLazyToolRenderer: () => useLazyToolRenderer, useMakeCopilotDocumentReadable: () => useMakeCopilotDocumentReadable, useRenderToolCall: () => useRenderToolCall2 }); module.exports = __toCommonJS(hooks_exports); // src/hooks/use-copilot-chat_internal.ts var import_react14 = 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_react15 = 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_react12 = require("@copilotkitnext/react"); var import_react13 = require("react"); var import_shared4 = require("@copilotkit/shared"); // src/hooks/use-coagent-state-render-bridge.helpers.ts 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 isPlaceholderMessageId(messageId) { return !!messageId && messageId.startsWith("coagent-state-render-"); } function isPlaceholderMessageName(messageName) { return messageName === "coagent-state-render"; } function readCachedMessageEntry(entry) { if (!entry || typeof entry !== "object") { return { snapshot: entry, runId: void 0 }; } const snapshot = "snapshot" in entry ? entry.snapshot : entry; const runId = "runId" in entry ? entry.runId : void 0; return { snapshot, runId }; } function getEffectiveRunId({ existingClaimRunId, cachedMessageRunId, runId }) { return existingClaimRunId || cachedMessageRunId || runId || "pending"; } function resolveClaim({ claims, context, stateSnapshot }) { const { messageId, stateRenderId, runId, messageIndex } = context; const existing = claims[messageId]; if (existing) { const canRender = existing.stateRenderId === stateRenderId; const shouldUpdateRunId = canRender && runId && (!existing.runId || existing.runId === "pending"); return { canRender, action: canRender ? "existing" /* Existing */ : "block" /* Block */, updateRunId: shouldUpdateRunId ? runId : void 0 }; } const normalizedRunId = runId != null ? runId : "pending"; const renderClaimedByOtherMessageEntry = Object.entries(claims).find( ([, claim]) => { var _a; return claim.stateRenderId === stateRenderId && ((_a = claim.runId) != null ? _a : "pending") === normalizedRunId && (0, import_shared3.dataToUUID)(getStateWithoutConstantKeys(claim.stateSnapshot)) === (0, import_shared3.dataToUUID)(getStateWithoutConstantKeys(stateSnapshot)); } ); const renderClaimedByOtherMessage = renderClaimedByOtherMessageEntry == null ? void 0 : renderClaimedByOtherMessageEntry[1]; const claimedMessageId = renderClaimedByOtherMessageEntry == null ? void 0 : renderClaimedByOtherMessageEntry[0]; if (renderClaimedByOtherMessage) { if (messageIndex !== void 0 && renderClaimedByOtherMessage.messageIndex !== void 0 && messageIndex > renderClaimedByOtherMessage.messageIndex) { return { canRender: true, action: "override" /* Override */, nextClaim: { stateRenderId, runId, messageIndex }, lockOthers: runId === renderClaimedByOtherMessage.runId || isPlaceholderMessageId(claimedMessageId) }; } if (runId && renderClaimedByOtherMessage.runId && runId !== renderClaimedByOtherMessage.runId) { return { canRender: true, action: "override" /* Override */, nextClaim: { stateRenderId, runId, messageIndex }, lockOthers: isPlaceholderMessageId(claimedMessageId) }; } if (isPlaceholderMessageId(claimedMessageId)) { return { canRender: true, action: "override" /* Override */, nextClaim: { stateRenderId, runId, messageIndex }, lockOthers: true }; } if (stateSnapshot && renderClaimedByOtherMessage.stateSnapshot && !areStatesEquals(renderClaimedByOtherMessage.stateSnapshot, stateSnapshot)) { return { canRender: true, action: "override" /* Override */, nextClaim: { stateRenderId, runId } }; } return { canRender: false, action: "block" /* Block */ }; } if (!runId) { return { canRender: false, action: "block" /* Block */ }; } return { canRender: true, action: "create" /* Create */, nextClaim: { stateRenderId, runId, messageIndex } }; } function selectSnapshot({ messageId, messageName, allowLiveState, skipLatestCache, stateRenderId, effectiveRunId, stateSnapshotProp, agentState, agentMessages, existingClaim, caches }) { var _a, _b, _c, _d, _e, _f; const lastAssistantId = agentMessages ? (_a = [...agentMessages].reverse().find((msg) => msg.role === "assistant")) == null ? void 0 : _a.id : void 0; const latestSnapshot = stateRenderId !== void 0 ? caches.byStateRenderAndRun[`${stateRenderId}::latest`] : void 0; const messageIndex = agentMessages ? agentMessages.findIndex((msg) => msg.id === messageId) : -1; const messageRole = messageIndex >= 0 && agentMessages ? (_b = agentMessages[messageIndex]) == null ? void 0 : _b.role : void 0; let previousUserMessageId; if (messageIndex > 0 && agentMessages) { for (let i = messageIndex - 1; i >= 0; i -= 1) { if (((_c = agentMessages[i]) == null ? void 0 : _c.role) === "user") { previousUserMessageId = (_d = agentMessages[i]) == null ? void 0 : _d.id; break; } } } const liveStateIsStale = stateSnapshotProp === void 0 && latestSnapshot !== void 0 && agentState !== void 0 && areStatesEquals(latestSnapshot, agentState); const shouldUseLiveState = (Boolean(allowLiveState) || !lastAssistantId || messageId === lastAssistantId) && !liveStateIsStale; const snapshot = stateSnapshotProp ? (0, import_shared3.parseJson)(stateSnapshotProp, stateSnapshotProp) : shouldUseLiveState ? agentState : void 0; const hasSnapshotKeys = !!(snapshot && Object.keys(snapshot).length > 0); const allowEmptySnapshot = snapshot !== void 0 && !hasSnapshotKeys && (stateSnapshotProp !== void 0 || shouldUseLiveState); const messageCacheEntry = caches.byMessageId[messageId]; const cachedMessageSnapshot = readCachedMessageEntry(messageCacheEntry).snapshot; const cacheKey = stateRenderId !== void 0 ? `${stateRenderId}::${effectiveRunId}` : void 0; let cachedSnapshot = cachedMessageSnapshot != null ? cachedMessageSnapshot : caches.byMessageId[messageId]; if (cachedSnapshot === void 0 && cacheKey && caches.byStateRenderAndRun[cacheKey] !== void 0) { cachedSnapshot = caches.byStateRenderAndRun[cacheKey]; } if (cachedSnapshot === void 0 && stateRenderId && previousUserMessageId && caches.byStateRenderAndRun[`${stateRenderId}::pending:${previousUserMessageId}`] !== void 0) { cachedSnapshot = caches.byStateRenderAndRun[`${stateRenderId}::pending:${previousUserMessageId}`]; } if (cachedSnapshot === void 0 && !skipLatestCache && stateRenderId && messageRole !== "assistant" && (stateSnapshotProp !== void 0 || agentState && Object.keys(agentState).length > 0)) { cachedSnapshot = caches.byStateRenderAndRun[`${stateRenderId}::latest`]; } const snapshotForClaim = (existingClaim == null ? void 0 : existingClaim.locked) ? (_e = existingClaim.stateSnapshot) != null ? _e : cachedSnapshot : hasSnapshotKeys ? snapshot : (_f = existingClaim == null ? void 0 : existingClaim.stateSnapshot) != null ? _f : cachedSnapshot; return { snapshot, hasSnapshotKeys, cachedSnapshot, allowEmptySnapshot, snapshotForClaim }; } // src/hooks/use-coagent-state-render-registry.ts var import_react11 = require("react"); var LAST_SNAPSHOTS_BY_RENDER_AND_RUN = "__lastSnapshotsByStateRenderIdAndRun"; var LAST_SNAPSHOTS_BY_MESSAGE = "__lastSnapshotsByMessageId"; function getClaimsStore(claimsRef) { return claimsRef.current; } function getSnapshotCaches(claimsRef) { var _a, _b; const store = getClaimsStore(claimsRef); return { byStateRenderAndRun: (_a = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _a : {}, byMessageId: (_b = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _b : {} }; } function useStateRenderRegistry({ agentId, stateRenderId, message, messageIndex, stateSnapshot, agentState, agentMessages, claimsRef }) { var _a, _b, _c, _d, _e, _f; const store = getClaimsStore(claimsRef); const runId = message.runId; const cachedMessageEntry = (_a = store[LAST_SNAPSHOTS_BY_MESSAGE]) == null ? void 0 : _a[message.id]; const { runId: cachedMessageRunId } = readCachedMessageEntry(cachedMessageEntry); const existingClaimRunId = (_b = claimsRef.current[message.id]) == null ? void 0 : _b.runId; const effectiveRunId = getEffectiveRunId({ existingClaimRunId, cachedMessageRunId, runId }); (0, import_react11.useEffect)(() => { return () => { var _a2, _b2, _c2, _d2; const existingClaim2 = claimsRef.current[message.id]; if ((existingClaim2 == null ? void 0 : existingClaim2.stateSnapshot) && Object.keys(existingClaim2.stateSnapshot).length > 0) { const snapshotCache = __spreadValues({}, (_a2 = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _a2 : {}); const cacheKey = `${existingClaim2.stateRenderId}::${(_b2 = existingClaim2.runId) != null ? _b2 : "pending"}`; snapshotCache[cacheKey] = existingClaim2.stateSnapshot; snapshotCache[`${existingClaim2.stateRenderId}::latest`] = existingClaim2.stateSnapshot; store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache; const messageCache = __spreadValues({}, (_c2 = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _c2 : {}); messageCache[message.id] = { snapshot: existingClaim2.stateSnapshot, runId: (_d2 = existingClaim2.runId) != null ? _d2 : effectiveRunId }; store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache; } delete claimsRef.current[message.id]; }; }, [claimsRef, effectiveRunId, message.id]); if (!stateRenderId) { return { canRender: false }; } const caches = getSnapshotCaches(claimsRef); const existingClaim = claimsRef.current[message.id]; const { snapshot, hasSnapshotKeys, allowEmptySnapshot, snapshotForClaim } = selectSnapshot({ messageId: message.id, messageName: message.name, allowLiveState: isPlaceholderMessageName(message.name) || isPlaceholderMessageId(message.id), skipLatestCache: isPlaceholderMessageName(message.name) || isPlaceholderMessageId(message.id), stateRenderId, effectiveRunId, stateSnapshotProp: stateSnapshot, agentState, agentMessages, existingClaim, caches }); const resolution = resolveClaim({ claims: claimsRef.current, context: { agentId, messageId: message.id, stateRenderId, runId: effectiveRunId, messageIndex }, stateSnapshot: snapshotForClaim }); if (resolution.action === "block" /* Block */) { return { canRender: false }; } if (resolution.updateRunId && claimsRef.current[message.id]) { claimsRef.current[message.id].runId = resolution.updateRunId; } if (resolution.nextClaim) { claimsRef.current[message.id] = resolution.nextClaim; } if (resolution.lockOthers) { Object.entries(claimsRef.current).forEach(([id, claim]) => { if (id !== message.id && claim.stateRenderId === stateRenderId) { claim.locked = true; } }); } if (existingClaim && !existingClaim.locked && (agentMessages == null ? void 0 : agentMessages.length)) { const indexInAgentMessages = agentMessages.findIndex( (msg) => msg.id === message.id ); if (indexInAgentMessages >= 0 && indexInAgentMessages < agentMessages.length - 1) { existingClaim.locked = true; } } const existingSnapshot = claimsRef.current[message.id].stateSnapshot; const snapshotChanged = stateSnapshot && existingSnapshot !== void 0 && !areStatesEquals(existingSnapshot, snapshot); if (snapshot && (stateSnapshot || hasSnapshotKeys || allowEmptySnapshot) && (!claimsRef.current[message.id].locked || snapshotChanged)) { if (!claimsRef.current[message.id].locked || snapshotChanged) { claimsRef.current[message.id].stateSnapshot = snapshot; const snapshotCache = __spreadValues({}, (_c = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _c : {}); const cacheKey = `${stateRenderId}::${effectiveRunId}`; snapshotCache[cacheKey] = snapshot; snapshotCache[`${stateRenderId}::latest`] = snapshot; store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache; const messageCache = __spreadValues({}, (_d = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _d : {}); messageCache[message.id] = { snapshot, runId: effectiveRunId }; store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache; if (stateSnapshot) { claimsRef.current[message.id].locked = true; } } } else if (snapshotForClaim) { const existingSnapshot2 = claimsRef.current[message.id].stateSnapshot; if (!existingSnapshot2) { claimsRef.current[message.id].stateSnapshot = snapshotForClaim; const snapshotCache = __spreadValues({}, (_e = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _e : {}); const cacheKey = `${stateRenderId}::${effectiveRunId}`; snapshotCache[cacheKey] = snapshotForClaim; snapshotCache[`${stateRenderId}::latest`] = snapshotForClaim; store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache; const messageCache = __spreadValues({}, (_f = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _f : {}); messageCache[message.id] = { snapshot: snapshotForClaim, runId: effectiveRunId }; store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache; } } return { canRender: true }; } // src/hooks/use-coagent-state-render-bridge.tsx function useCoagentStateRenderBridge(agentId, props) { var _a; const { stateSnapshot, message } = props; const { coAgentStateRenders, claimsRef } = useCoAgentStateRenders(); const { agent } = (0, import_react12.useAgent)({ agentId }); const [nodeName, setNodeName] = (0, import_react13.useState)(void 0); const [, forceUpdate] = (0, import_react13.useState)(0); (0, import_react13.useEffect)(() => { if (!agent) return; const subscriber = { onStateChanged: () => { forceUpdate((value) => value + 1); }, 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_react13.useCallback)( (messageId) => { return Object.entries(coAgentStateRenders).find( ([stateRenderId2, stateRender2]) => { if (claimsRef.current[messageId]) { return stateRenderId2 === claimsRef.current[messageId].stateRenderId; } const matchingAgentName = stateRender2.name === agentId; const matchesNodeContext = stateRender2.nodeName ? stateRender2.nodeName === nodeName : true; return matchingAgentName && matchesNodeContext; } ); }, [coAgentStateRenders, nodeName, agentId] ); const stateRenderEntry = (0, import_react13.useMemo)( () => getStateRender(message.id), [getStateRender, message.id] ); const stateRenderId = stateRenderEntry == null ? void 0 : stateRenderEntry[0]; const stateRender = stateRenderEntry == null ? void 0 : stateRenderEntry[1]; const registryMessage = __spreadProps(__spreadValues({}, message), { runId: (_a = props.runId) != null ? _a : message.runId }); const { canRender } = useStateRenderRegistry({ agentId, stateRenderId, message: registryMessage, messageIndex: props.messageIndex, stateSnapshot, agentState: agent == null ? void 0 : agent.state, agentMessages: agent == null ? void 0 : agent.messages, claimsRef }); return (0, import_react13.useMemo)(() => { var _a2, _b; if (!stateRender || !stateRenderId) { return null; } if (!canRender) { return null; } if (stateRender.handler) { stateRender.handler({ state: stateSnapshot ? (0, import_shared4.parseJson)(stateSnapshot, stateSnapshot) : (_a2 = agent == null ? void 0 : agent.state) != null ? _a2 : {}, nodeName: nodeName != null ? nodeName : "" }); } if (stateRender.render) { const status = (agent == null ? void 0 : agent.isRunning) ? "inProgress" /* InProgress */ : "complete" /* 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: (_b = claimsRef.current[message.id].stateSnapshot) != null ? _b : {}, nodeName: nodeName != null ? nodeName : "" }); } }, [ stateRender, stateRenderId, agent == null ? void 0 : agent.state, agent == null ? void 0 : agent.isRunning, nodeName, message.id, stateSnapshot, canRender ]); } 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_react15.useCopilotKit)(); const { threadId, agentSession } = useCopilotContext(); const existingConfig = (0, import_react15.useCopilotChatConfiguration)(); const [agentAvailable, setAgentAvailable] = (0, import_react14.useState)(false); const resolvedAgentId = (_a = existingConfig == null ? void 0 : existingConfig.agentId) != null ? _a : "default"; const { agent } = (0, import_react15.useAgent)({ agentId: resolvedAgentId }); (0, import_react14.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 { console.error("CopilotChat: connectAgent failed", 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_react14.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_react14.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_react14.useCallback)( (messageId) => { return latestDelete.current(messageId); }, [latestDelete] ); const currentSuggestions = (0, import_react15.useSuggestions)({ agentId: resolvedAgentId }); const reload = useAsyncCallback( (reloadMessageId) => __async(this, null, function* () { var _a2; if (!agent) return; const messages = (_a2 = agent == null ? void 0 : agent.messages) != null ? _a2 : []; const isLoading = agent.isRunning; 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) { try { yield copilotkit.runAgent({ agent }); } catch (error) { console.error("CopilotChat: runAgent failed during reload", error); } } return; }), [ agent == null ? void 0 : agent.messages.length, agent == null ? void 0 : agent.isRunning, 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); } 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 : ""; try { yield onSubmitMessage(content); } catch (error) { console.error("Error in onSubmitMessage:", error); } } agent == null ? void 0 : agent.addMessage(message); if (followUp) { try { yield copilotkit.runAgent({ agent }); } catch (error) { console.error("CopilotChat: runAgent failed", error); } } }), [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_react14.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_react14.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_react14.useCallback)(() => { return latestReset.current(); }, [latestReset]); const lazyToolRendered = useLazyToolRenderer(); const renderCustomMessage = (0, import_react15.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_react14.useMemo)(() => { var _a2, _b2; 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 ? () => { var _a3; if (legacyCustomMessageRenderer) { return legacyCustomMessageRenderer({ message, position: "before" }); } try { return (_a3 = renderCustomMessage == null ? void 0 : renderCustomMessage({ message, position: "before" })) != null ? _a3 : null; } catch (error) { console.warn( "[CopilotKit] renderCustomMessages failed, falling back to legacy renderer", error ); return null; } } : null; if (bridgeRenderer) { return __spreadProps(__spreadValues({}, message), { generativeUI: bridgeRenderer, generativeUIPosition: "before" }); } return message; }); const hasAssistantMessages = processedMessages.some( (msg) => msg.role === "assistant" ); const canUseCustomRenderer = Boolean( renderCustomMessage && ((_a2 = copilotkit == null ? void 0 : copilotkit.getAgent) == null ? void 0 : _a2.call(copilotkit, resolvedAgentId)) ); const placeholderRenderer = legacyCustomMessageRenderer ? legacyCustomMessageRenderer : canUseCustomRenderer ? renderCustomMessage : null; const shouldRenderPlaceholder = Boolean(agent == null ? void 0 : agent.isRunning) || Boolean((agent == null ? void 0 : agent.state) && Object.keys(agent.state).length); const effectiveThreadId = (_b2 = threadId != null ? threadId : agent == null ? void 0 : agent.threadId) != null ? _b2 : "default"; let latestUserIndex = -1; for (let i = processedMessages.length - 1; i >= 0; i -= 1) { if (processedMessages[i].role === "user") { latestUserIndex = i; break; } } const latestUserMessageId = latestUserIndex >= 0 ? processedMessages[latestUserIndex].id : void 0; const currentRunId = latestUserMessageId ? copilotkit.getRunIdForMessage( resolvedAgentId, effectiveThreadId, latestUserMessageId ) || `pending:${latestUserMessageId}` : void 0; const hasAssistantForCurrentRun = latestUserIndex >= 0 ? processedMessages.slice(latestUserIndex + 1).some((msg) => msg.role === "assistant") : hasAssistantMessages; if (placeholderRenderer && shouldRenderPlaceholder && !hasAssistantForCurrentRun) { const placeholderId = currentRunId ? `coagent-state-render-${resolvedAgentId}-${currentRunId}` : `coagent-state-render-${resolvedAgentId}`; const placeholderMessage = { id: placeholderId, role: "assistant", content: "", name: "coagent-state-render", runId: currentRunId }; processedMessages = [ ...processedMessages, __spreadProps(__spreadValues({}, placeholderMessage), { generativeUIPosition: "before", generativeUI: () => placeholderRenderer({ message: placeholderMessage, position: "before" }) }) ]; } return processedMessages; }, [ agent == null ? void 0 : agent.messages, lazyToolRendered, allMessages, renderCustomMessage, legacyCustomMessageRenderer, resolvedAgentId, copilotkit, agent == null ? void 0 : agent.isRunning, agent == null ? void 0 : agent.state ]); const renderedSuggestions = (0, import_react14.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_react14.useRef)(value); (0, import_react14.useEffect)(() => { ref.current = value; }, [value]); return ref; } function useLegacyCoagentRenderer({ copilotkit, agent, agentId, threadId }) { return (0, import_react14.useMemo)(() => { if (!copilotkit || !agent) { return null; } return ({ message, position }) => { var _a; const effectiveThreadId = (_a = threadId != null ? threadId : agent.threadId) != null ? _a : "default"; const providedRunId = message.runId; const existingRunId = providedRunId ? providedRunId : 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_react14.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, isLoad