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

551 lines (548 loc) • 18.9 kB
import { CopilotErrorBoundary } from "./chunk-LHERIF3L.mjs"; import { CopilotMessages, MessagesTapProvider } from "./chunk-HE22TZMF.mjs"; import { shouldShowDevConsole } from "./chunk-ICIK2BSB.mjs"; import { use_tree_default } from "./chunk-RKTVJRK7.mjs"; import { use_flat_category_store_default } from "./chunk-YYN33GSG.mjs"; import { CoAgentStateRenderBridge } from "./chunk-QNUAXSDP.mjs"; import { ThreadsProvider, useThreads } from "./chunk-F555TVE4.mjs"; import { CopilotListeners } from "./chunk-WF65O6HX.mjs"; import { ToastProvider } from "./chunk-EFL5OBKN.mjs"; import { UsageBanner, getErrorActions } from "./chunk-6ZLPNY7X.mjs"; import { CoAgentStateRendersProvider } from "./chunk-FDOMAPJY.mjs"; import { CopilotContext } from "./chunk-AFNWX62Q.mjs"; import { __async, __objRest, __restKey, __spreadProps, __spreadValues } from "./chunk-SKC7AJIV.mjs"; // src/components/copilot-provider/copilotkit.tsx import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { CopilotChatConfigurationProvider, CopilotKitProvider as CopilotKitNextProvider } from "@copilotkitnext/react"; import { flushSync } from "react-dom"; import { COPILOT_CLOUD_CHAT_URL, COPILOT_CLOUD_PUBLIC_API_KEY_HEADER, randomUUID, ConfigurationError, MissingPublicApiKeyError } from "@copilotkit/shared"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; function CopilotKit(_a) { var _b = _a, { children } = _b, props = __objRest(_b, ["children"]); const enabled = shouldShowDevConsole(props.showDevConsole); const showInspector = shouldShowDevConsole(props.enableInspector); const publicApiKey = props.publicApiKey || props.publicLicenseKey; const renderArr = useMemo(() => [{ render: CoAgentStateRenderBridge }], []); return /* @__PURE__ */ jsx(ToastProvider, { enabled, children: /* @__PURE__ */ jsx(CopilotErrorBoundary, { publicApiKey, showUsageBanner: enabled, children: /* @__PURE__ */ jsx(ThreadsProvider, { threadId: props.threadId, children: /* @__PURE__ */ jsx( CopilotKitNextProvider, __spreadProps(__spreadValues({}, props), { showDevConsole: showInspector, renderCustomMessages: renderArr, useSingleEndpoint: true, children: /* @__PURE__ */ jsx(CopilotKitInternal, __spreadProps(__spreadValues({}, props), { children })) }) ) }) }) }); } function CopilotKitInternal(cpkProps) { var _b; const _a = cpkProps, { children } = _a, props = __objRest(_a, ["children"]); validateProps(cpkProps); const publicApiKey = props.publicLicenseKey || props.publicApiKey; const chatApiEndpoint = props.runtimeUrl || COPILOT_CLOUD_CHAT_URL; const [actions, setActions] = useState({}); const [registeredActionConfigs, setRegisteredActionConfigs] = useState(/* @__PURE__ */ new Map()); const chatComponentsCache = useRef({ actions: {}, coAgentStateRenders: {} }); const { addElement, removeElement, printTree, getAllElements } = use_tree_default(); const [isLoading, setIsLoading] = useState(false); const [chatInstructions, setChatInstructions] = useState(""); const [authStates, setAuthStates] = useState({}); const [extensions, setExtensions] = useState({}); const [additionalInstructions, setAdditionalInstructions] = useState([]); const { addElement: addDocument, removeElement: removeDocument, allElements: allDocuments } = use_flat_category_store_default(); const setAction = useCallback((id, action) => { setActions((prevPoints) => { return __spreadProps(__spreadValues({}, prevPoints), { [id]: action }); }); }, []); const removeAction = useCallback((id) => { setActions((prevPoints) => { const newPoints = __spreadValues({}, prevPoints); delete newPoints[id]; return newPoints; }); }, []); const getContextString = useCallback( (documents, categories) => { const documentsString = documents.map((document) => { return `${document.name} (${document.sourceApplication}): ${document.getContents()}`; }).join("\n\n"); const nonDocumentStrings = printTree(categories); return `${documentsString} ${nonDocumentStrings}`; }, [printTree] ); const addContext = useCallback( (context, parentId, categories = defaultCopilotContextCategories) => { return addElement(context, categories, parentId); }, [addElement] ); const removeContext = useCallback( (id) => { removeElement(id); }, [removeElement] ); const getAllContext = useCallback(() => { return getAllElements(); }, [getAllElements]); const getFunctionCallHandler = useCallback( (customEntryPoints) => { return entryPointsToFunctionCallHandler(Object.values(customEntryPoints || actions)); }, [actions] ); const getDocumentsContext = useCallback( (categories) => { return allDocuments(categories); }, [allDocuments] ); const addDocumentContext = useCallback( (documentPointer, categories = defaultCopilotContextCategories) => { return addDocument(documentPointer, categories); }, [addDocument] ); const removeDocumentContext = useCallback( (documentId) => { removeDocument(documentId); }, [removeDocument] ); const copilotApiConfig = useMemo(() => { var _a2, _b2; let cloud = void 0; if (publicApiKey) { cloud = { guardrails: { input: { restrictToTopic: { enabled: Boolean(props.guardrails_c), validTopics: ((_a2 = props.guardrails_c) == null ? void 0 : _a2.validTopics) || [], invalidTopics: ((_b2 = props.guardrails_c) == null ? void 0 : _b2.invalidTopics) || [] } } } }; } return __spreadProps(__spreadValues({ publicApiKey }, cloud ? { cloud } : {}), { chatApiEndpoint, headers: props.headers || {}, properties: props.properties || {}, transcribeAudioUrl: props.transcribeAudioUrl, textToSpeechUrl: props.textToSpeechUrl, credentials: props.credentials }); }, [ publicApiKey, props.headers, props.properties, props.transcribeAudioUrl, props.textToSpeechUrl, props.credentials, props.cloudRestrictToTopic, props.guardrails_c ]); const headers = useMemo(() => { const authHeaders = Object.values(authStates || {}).reduce((acc, state) => { if (state.status === "authenticated" && state.authHeaders) { return __spreadValues(__spreadValues({}, acc), Object.entries(state.authHeaders).reduce( (headers2, [key, value]) => __spreadProps(__spreadValues({}, headers2), { [key.startsWith("X-Custom-") ? key : `X-Custom-${key}`]: value }), {} )); } return acc; }, {}); return __spreadValues(__spreadValues(__spreadValues({}, copilotApiConfig.headers || {}), copilotApiConfig.publicApiKey ? { [COPILOT_CLOUD_PUBLIC_API_KEY_HEADER]: copilotApiConfig.publicApiKey } : {}), authHeaders); }, [copilotApiConfig.headers, copilotApiConfig.publicApiKey, authStates]); const [internalErrorHandlers, _setInternalErrorHandler] = useState({}); const setInternalErrorHandler = useCallback((handler) => { _setInternalErrorHandler((prev) => __spreadValues(__spreadValues({}, prev), handler)); }, []); const removeInternalErrorHandler = useCallback((key) => { _setInternalErrorHandler((prev) => { const _a2 = prev, { [key]: _removed } = _a2, rest = __objRest(_a2, [__restKey(key)]); return rest; }); }, []); const onErrorRef = useRef(props.onError); useEffect(() => { onErrorRef.current = props.onError; }, [props.onError]); const internalHandlersRef = useRef({}); useEffect(() => { internalHandlersRef.current = internalErrorHandlers; }, [internalErrorHandlers]); const handleErrors = useCallback( (error) => __async(this, null, function* () { if (copilotApiConfig.publicApiKey && onErrorRef.current) { try { yield onErrorRef.current(error); } catch (e) { console.error("Error in public onError handler:", e); } } const handlers = Object.values(internalHandlersRef.current); yield Promise.all( handlers.map( (h) => Promise.resolve(h(error)).catch( (e) => console.error("Error in internal error handler:", e) ) ) ); }), [copilotApiConfig.publicApiKey] ); const [chatSuggestionConfiguration, setChatSuggestionConfiguration] = useState({}); const addChatSuggestionConfiguration = useCallback( (id, suggestion) => { setChatSuggestionConfiguration((prev) => __spreadProps(__spreadValues({}, prev), { [id]: suggestion })); }, [setChatSuggestionConfiguration] ); const removeChatSuggestionConfiguration = useCallback( (id) => { setChatSuggestionConfiguration((prev) => { const _a2 = prev, { [id]: _ } = _a2, rest = __objRest(_a2, [__restKey(id)]); return rest; }); }, [setChatSuggestionConfiguration] ); const [availableAgents, setAvailableAgents] = useState([]); const [coagentStates, setCoagentStates] = useState({}); const coagentStatesRef = useRef({}); const setCoagentStatesWithRef = useCallback( (value) => { const newValue = typeof value === "function" ? value(coagentStatesRef.current) : value; coagentStatesRef.current = newValue; setCoagentStates((prev) => { return newValue; }); }, [] ); let initialAgentSession = null; if (props.agent) { initialAgentSession = { agentName: props.agent }; } const [agentSession, setAgentSession] = useState(initialAgentSession); useEffect(() => { if (props.agent) { setAgentSession({ agentName: props.agent }); } else { setAgentSession(null); } }, [props.agent]); const { threadId, setThreadId: setInternalThreadId } = useThreads(); const setThreadId = useCallback( (value) => { if (props.threadId) { throw new Error("Cannot call setThreadId() when threadId is provided via props."); } setInternalThreadId(value); }, [props.threadId] ); const [runId, setRunId] = useState(null); const chatAbortControllerRef = useRef(null); const showDevConsole = shouldShowDevConsole(props.showDevConsole); const [interruptActions, _setInterruptActions] = useState({}); const setInterruptAction = useCallback((action) => { _setInterruptActions((prev) => { var _a2; if (action == null || !action.id) { return prev; } return __spreadProps(__spreadValues({}, prev), { [action.id]: __spreadValues(__spreadValues({}, (_a2 = prev[action.id]) != null ? _a2 : {}), action) }); }); }, []); const removeInterruptAction = useCallback((actionId) => { _setInterruptActions((prev) => { const _a2 = prev, { [actionId]: _ } = _a2, rest = __objRest(_a2, [__restKey(actionId)]); return rest; }); }, []); const [interruptEventQueue, setInterruptEventQueue] = useState({}); const addInterruptEvent = useCallback((queuedEvent) => { setInterruptEventQueue((prev) => { const threadQueue = prev[queuedEvent.threadId] || []; return __spreadProps(__spreadValues({}, prev), { [queuedEvent.threadId]: [...threadQueue, queuedEvent] }); }); }, []); const resolveInterruptEvent = useCallback( (threadId2, eventId, response) => { setInterruptEventQueue((prev) => { const threadQueue = prev[threadId2] || []; return __spreadProps(__spreadValues({}, prev), { [threadId2]: threadQueue.map( (queuedEvent) => queuedEvent.eventId === eventId ? __spreadProps(__spreadValues({}, queuedEvent), { event: __spreadProps(__spreadValues({}, queuedEvent.event), { response }) }) : queuedEvent ) }); }); }, [] ); const memoizedChildren = useMemo(() => children, [children]); const [bannerError, setBannerError] = useState(null); const agentLock = useMemo(() => { var _a2; return (_a2 = props.agent) != null ? _a2 : null; }, [props.agent]); const forwardedParameters = useMemo( () => { var _a2; return (_a2 = props.forwardedParameters) != null ? _a2 : {}; }, [props.forwardedParameters] ); const updateExtensions = useCallback( (newExtensions) => { setExtensions((prev) => { const resolved = typeof newExtensions === "function" ? newExtensions(prev) : newExtensions; const isSameLength = Object.keys(resolved).length === Object.keys(prev).length; const isEqual = isSameLength && // @ts-ignore Object.entries(resolved).every(([key, value]) => prev[key] === value); return isEqual ? prev : resolved; }); }, [setExtensions] ); const updateAuthStates = useCallback( (newAuthStates) => { setAuthStates((prev) => { const resolved = typeof newAuthStates === "function" ? newAuthStates(prev) : newAuthStates; const isSameLength = Object.keys(resolved).length === Object.keys(prev).length; const isEqual = isSameLength && // @ts-ignore Object.entries(resolved).every(([key, value]) => prev[key] === value); return isEqual ? prev : resolved; }); }, [setAuthStates] ); const handleSetRegisteredActions = useCallback((actionConfig) => { const key = actionConfig.action.name || randomUUID(); setRegisteredActionConfigs((prev) => { const newMap = new Map(prev); newMap.set(key, actionConfig); return newMap; }); return key; }, []); const handleRemoveRegisteredAction = useCallback((actionKey) => { setRegisteredActionConfigs((prev) => { const newMap = new Map(prev); newMap.delete(actionKey); return newMap; }); }, []); const RegisteredActionsRenderer = useMemo(() => { return () => /* @__PURE__ */ jsx(Fragment, { children: Array.from(registeredActionConfigs.entries()).map(([key, config]) => { const Component = config.component; return /* @__PURE__ */ jsx(Component, { action: config.action }, key); }) }); }, [registeredActionConfigs]); return /* @__PURE__ */ jsx( CopilotChatConfigurationProvider, { agentId: (_b = props.agent) != null ? _b : "default", threadId, children: /* @__PURE__ */ jsxs( CopilotContext.Provider, { value: { actions, chatComponentsCache, getFunctionCallHandler, setAction, removeAction, setRegisteredActions: handleSetRegisteredActions, removeRegisteredAction: handleRemoveRegisteredAction, getContextString, addContext, removeContext, getAllContext, getDocumentsContext, addDocumentContext, removeDocumentContext, copilotApiConfig, isLoading, setIsLoading, chatSuggestionConfiguration, addChatSuggestionConfiguration, removeChatSuggestionConfiguration, chatInstructions, setChatInstructions, additionalInstructions, setAdditionalInstructions, showDevConsole, coagentStates, setCoagentStates, coagentStatesRef, setCoagentStatesWithRef, agentSession, setAgentSession, forwardedParameters, agentLock, threadId, setThreadId, runId, setRunId, chatAbortControllerRef, availableAgents, authConfig_c: props.authConfig_c, authStates_c: authStates, setAuthStates_c: updateAuthStates, extensions, setExtensions: updateExtensions, interruptActions, setInterruptAction, removeInterruptAction, interruptEventQueue, addInterruptEvent, resolveInterruptEvent, bannerError, setBannerError, onError: handleErrors, internalErrorHandlers, setInternalErrorHandler, removeInternalErrorHandler }, children: [ /* @__PURE__ */ jsx(CopilotListeners, {}), /* @__PURE__ */ jsxs(CoAgentStateRendersProvider, { children: [ /* @__PURE__ */ jsx(MessagesTapProvider, { children: /* @__PURE__ */ jsxs(CopilotMessages, { children: [ memoizedChildren, /* @__PURE__ */ jsx(RegisteredActionsRenderer, {}) ] }) }), bannerError && showDevConsole && /* @__PURE__ */ jsx( UsageBanner, { severity: bannerError.severity, message: bannerError.message, onClose: () => setBannerError(null), actions: getErrorActions(bannerError) } ) ] }) ] } ) } ); } var defaultCopilotContextCategories = ["global"]; function entryPointsToFunctionCallHandler(actions) { return (_0) => __async(this, [_0], function* ({ name, args }) { let actionsByFunctionName = {}; for (let action2 of actions) { actionsByFunctionName[action2.name] = action2; } const action = actionsByFunctionName[name]; let result = void 0; if (action) { yield new Promise((resolve, reject) => { flushSync(() => __async(this, null, function* () { var _a; try { result = yield (_a = action.handler) == null ? void 0 : _a.call(action, args); resolve(); } catch (error) { reject(error); } })); }); yield new Promise((resolve) => setTimeout(resolve, 20)); } return result; }); } function formatFeatureName(featureName) { return featureName.replace(/_c$/, "").split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" "); } function validateProps(props) { const cloudFeatures = Object.keys(props).filter((key) => key.endsWith("_c")); const hasApiKey = props.publicApiKey || props.publicLicenseKey; if (!props.runtimeUrl && !hasApiKey) { throw new ConfigurationError( "Missing required prop: 'runtimeUrl' or 'publicApiKey' or 'publicLicenseKey'" ); } if (cloudFeatures.length > 0 && !hasApiKey) { throw new MissingPublicApiKeyError( `Missing required prop: 'publicApiKey' or 'publicLicenseKey' to use cloud features: ${cloudFeatures.map(formatFeatureName).join(", ")}` ); } } export { CopilotKit, CopilotKitInternal, defaultCopilotContextCategories }; //# sourceMappingURL=chunk-4YZA2BZC.mjs.map