@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
JavaScript
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