rdesign/frontend/node_modules/@copilotkitnext/react/dist/providers/CopilotKitProvider.cjs

274 lines
11 KiB
JavaScript

"use client";
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
const require_CopilotKitInspector = require('../components/CopilotKitInspector.cjs');
const require_MCPAppsActivityRenderer = require('../components/MCPAppsActivityRenderer.cjs');
const require_A2UIMessageRenderer = require('../a2ui/A2UIMessageRenderer.cjs');
const require_react_core = require('../lib/react-core.cjs');
let react = require("react");
let react_jsx_runtime = require("react/jsx-runtime");
let zod = require("zod");
let _copilotkit_a2ui_renderer = require("@copilotkit/a2ui-renderer");
//#region src/providers/CopilotKitProvider.tsx
const HEADER_NAME = "X-CopilotCloud-Public-Api-Key";
const COPILOT_CLOUD_CHAT_URL = "https://api.cloud.copilotkit.ai/copilotkit/v1";
const CopilotKitContext = (0, react.createContext)({
copilotkit: null,
executingToolCallIds: /* @__PURE__ */ new Set()
});
function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
const empty = (0, react.useMemo)(() => [], []);
const value = prop ?? empty;
const initial = (0, react.useRef)(value);
(0, react.useEffect)(() => {
if (warningMessage && value !== initial.current && (isMeaningfulChange ? isMeaningfulChange(initial.current, value) : true)) console.error(warningMessage);
}, [value, warningMessage]);
return value;
}
const CopilotKitProvider = ({ children, runtimeUrl, headers = {}, credentials, publicApiKey, publicLicenseKey, properties = {}, agents__unsafe_dev_only: agents = {}, selfManagedAgents = {}, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, showDevConsole = false, useSingleEndpoint = false, onError, a2ui }) => {
const [shouldRenderInspector, setShouldRenderInspector] = (0, react.useState)(false);
const [runtimeA2UIEnabled, setRuntimeA2UIEnabled] = (0, react.useState)(false);
(0, react.useEffect)(() => {
if (typeof window === "undefined") return;
if (showDevConsole === true) setShouldRenderInspector(true);
else if (showDevConsole === "auto") if (new Set(["localhost", "127.0.0.1"]).has(window.location.hostname)) setShouldRenderInspector(true);
else setShouldRenderInspector(false);
else setShouldRenderInspector(false);
}, [showDevConsole]);
const renderToolCallsList = useStableArrayProp(renderToolCalls, "renderToolCalls must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.", (initial, next) => {
const key = (rc) => `${rc?.agentId ?? ""}:${rc?.name ?? ""}`;
const setFrom = (arr) => new Set(arr.map(key));
const a = setFrom(initial);
const b = setFrom(next);
if (a.size !== b.size) return true;
for (const k of a) if (!b.has(k)) return true;
return false;
});
const renderCustomMessagesList = useStableArrayProp(renderCustomMessages, "renderCustomMessages must be a stable array.");
const renderActivityMessagesList = useStableArrayProp(renderActivityMessages, "renderActivityMessages must be a stable array.");
const builtInActivityRenderers = (0, react.useMemo)(() => {
const renderers = [{
activityType: require_MCPAppsActivityRenderer.MCPAppsActivityType,
content: require_MCPAppsActivityRenderer.MCPAppsActivityContentSchema,
render: require_MCPAppsActivityRenderer.MCPAppsActivityRenderer
}];
if (runtimeA2UIEnabled) renderers.unshift(require_A2UIMessageRenderer.createA2UIMessageRenderer({ theme: a2ui?.theme ?? _copilotkit_a2ui_renderer.viewerTheme }));
return renderers;
}, [runtimeA2UIEnabled, a2ui]);
const allActivityRenderers = (0, react.useMemo)(() => {
return [...renderActivityMessagesList, ...builtInActivityRenderers];
}, [renderActivityMessagesList, builtInActivityRenderers]);
const resolvedPublicKey = publicApiKey ?? publicLicenseKey;
const mergedAgents = (0, react.useMemo)(() => ({
...agents,
...selfManagedAgents
}), [agents, selfManagedAgents]);
const hasLocalAgents = mergedAgents && Object.keys(mergedAgents).length > 0;
const mergedHeaders = (0, react.useMemo)(() => {
if (!resolvedPublicKey) return headers;
if (headers[HEADER_NAME]) return headers;
return {
...headers,
[HEADER_NAME]: resolvedPublicKey
};
}, [headers, resolvedPublicKey]);
if (!runtimeUrl && !resolvedPublicKey && !hasLocalAgents) {
const message = "Missing required prop: 'runtimeUrl' or 'publicApiKey' or 'publicLicenseKey'";
if (process.env.NODE_ENV === "production") throw new Error(message);
else console.warn(message);
}
const chatApiEndpoint = runtimeUrl ?? (resolvedPublicKey ? COPILOT_CLOUD_CHAT_URL : void 0);
const frontendToolsList = useStableArrayProp(frontendTools, "frontendTools must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.");
const humanInTheLoopList = useStableArrayProp(humanInTheLoop, "humanInTheLoop must be a stable array. If you want to dynamically add or remove human-in-the-loop tools, use `useHumanInTheLoop` instead.");
const processedHumanInTheLoopTools = (0, react.useMemo)(() => {
const processedTools = [];
const processedRenderToolCalls = [];
humanInTheLoopList.forEach((tool) => {
const frontendTool = {
name: tool.name,
description: tool.description,
parameters: tool.parameters,
followUp: tool.followUp,
...tool.agentId && { agentId: tool.agentId },
handler: async () => {
return new Promise((resolve) => {
console.warn(`Human-in-the-loop tool '${tool.name}' called but no interactive handler is set up.`);
resolve(void 0);
});
}
};
processedTools.push(frontendTool);
if (tool.render) processedRenderToolCalls.push({
name: tool.name,
args: tool.parameters,
render: tool.render,
...tool.agentId && { agentId: tool.agentId }
});
});
return {
tools: processedTools,
renderToolCalls: processedRenderToolCalls
};
}, [humanInTheLoopList]);
const allTools = (0, react.useMemo)(() => {
const tools = [];
tools.push(...frontendToolsList);
tools.push(...processedHumanInTheLoopTools.tools);
return tools;
}, [frontendToolsList, processedHumanInTheLoopTools]);
const allRenderToolCalls = (0, react.useMemo)(() => {
const combined = [...renderToolCallsList];
frontendToolsList.forEach((tool) => {
if (tool.render) {
const args = tool.parameters || (tool.name === "*" ? zod.z.any() : void 0);
if (args) combined.push({
name: tool.name,
args,
render: tool.render
});
}
});
combined.push(...processedHumanInTheLoopTools.renderToolCalls);
return combined;
}, [
renderToolCallsList,
frontendToolsList,
processedHumanInTheLoopTools
]);
const copilotkitRef = (0, react.useRef)(null);
if (copilotkitRef.current === null) copilotkitRef.current = new require_react_core.CopilotKitCoreReact({
runtimeUrl: chatApiEndpoint,
runtimeTransport: useSingleEndpoint ? "single" : "rest",
headers: mergedHeaders,
credentials,
properties,
agents__unsafe_dev_only: mergedAgents,
tools: allTools,
renderToolCalls: allRenderToolCalls,
renderActivityMessages: allActivityRenderers,
renderCustomMessages: renderCustomMessagesList
});
const copilotkit = copilotkitRef.current;
(0, react.useEffect)(() => {
const subscription = copilotkit.subscribe({ onRuntimeConnectionStatusChanged: () => {
setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);
} });
return () => {
subscription.unsubscribe();
};
}, [copilotkit]);
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
(0, react.useEffect)(() => {
const subscription = copilotkit.subscribe({ onRenderToolCallsChanged: () => {
forceUpdate();
} });
return () => {
subscription.unsubscribe();
};
}, [copilotkit]);
const [executingToolCallIds, setExecutingToolCallIds] = (0, react.useState)(() => /* @__PURE__ */ new Set());
(0, react.useEffect)(() => {
const subscription = copilotkit.subscribe({
onToolExecutionStart: ({ toolCallId }) => {
setExecutingToolCallIds((prev) => {
if (prev.has(toolCallId)) return prev;
const next = new Set(prev);
next.add(toolCallId);
return next;
});
},
onToolExecutionEnd: ({ toolCallId }) => {
setExecutingToolCallIds((prev) => {
if (!prev.has(toolCallId)) return prev;
const next = new Set(prev);
next.delete(toolCallId);
return next;
});
}
});
return () => {
subscription.unsubscribe();
};
}, [copilotkit]);
const onErrorRef = (0, react.useRef)(onError);
(0, react.useEffect)(() => {
onErrorRef.current = onError;
}, [onError]);
(0, react.useEffect)(() => {
if (!onErrorRef.current) return;
const subscription = copilotkit.subscribe({ onError: (event) => {
onErrorRef.current?.({
error: event.error,
code: event.code,
context: event.context
});
} });
return () => {
subscription.unsubscribe();
};
}, [copilotkit]);
(0, react.useEffect)(() => {
copilotkit.setRuntimeUrl(chatApiEndpoint);
copilotkit.setRuntimeTransport(useSingleEndpoint ? "single" : "rest");
copilotkit.setHeaders(mergedHeaders);
copilotkit.setCredentials(credentials);
copilotkit.setProperties(properties);
copilotkit.setAgents__unsafe_dev_only(mergedAgents);
}, [
copilotkit,
chatApiEndpoint,
mergedHeaders,
credentials,
properties,
mergedAgents,
useSingleEndpoint
]);
const didMountRef = (0, react.useRef)(false);
(0, react.useEffect)(() => {
if (!didMountRef.current) return;
copilotkit.setTools(allTools);
}, [copilotkit, allTools]);
(0, react.useEffect)(() => {
if (!didMountRef.current) return;
copilotkit.setRenderToolCalls(allRenderToolCalls);
}, [copilotkit, allRenderToolCalls]);
(0, react.useEffect)(() => {
if (!didMountRef.current) return;
copilotkit.setRenderActivityMessages(allActivityRenderers);
}, [copilotkit, allActivityRenderers]);
(0, react.useEffect)(() => {
if (!didMountRef.current) return;
copilotkit.setRenderCustomMessages(renderCustomMessagesList);
}, [copilotkit, renderCustomMessagesList]);
(0, react.useEffect)(() => {
didMountRef.current = true;
}, []);
const contextValue = (0, react.useMemo)(() => ({
copilotkit,
executingToolCallIds
}), [copilotkit, executingToolCallIds]);
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(CopilotKitContext.Provider, {
value: contextValue,
children: [children, shouldRenderInspector ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_CopilotKitInspector.CopilotKitInspector, { core: copilotkit }) : null]
});
};
const useCopilotKit = () => {
const context = (0, react.useContext)(CopilotKitContext);
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
if (!context) throw new Error("useCopilotKit must be used within CopilotKitProvider");
(0, react.useEffect)(() => {
const subscription = context.copilotkit.subscribe({ onRuntimeConnectionStatusChanged: () => {
forceUpdate();
} });
return () => {
subscription.unsubscribe();
};
}, []);
return context;
};
//#endregion
exports.CopilotKitProvider = CopilotKitProvider;
exports.useCopilotKit = useCopilotKit;
//# sourceMappingURL=CopilotKitProvider.cjs.map