UNPKG

@copilotkit/runtime

Version:

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

287 lines (285 loc) • 12.3 kB
require("reflect-metadata"); const require_runtime = require('../../_virtual/_rolldown/runtime.cjs'); const require_agui_to_gql = require('../../graphql/message-conversion/agui-to-gql.cjs'); const require_telemetry_disclosure = require('../telemetry-disclosure.cjs'); const require_in_memory = require('../../v2/runtime/runner/in-memory.cjs'); const require_runtime$1 = require('../../v2/runtime/core/runtime.cjs'); const require_telemetry_agent_runner = require('./telemetry-agent-runner.cjs'); const require_types = require('./types.cjs'); const require_mcp_tools_utils = require('./mcp-tools-utils.cjs'); const require_index = require('../../agent/index.cjs'); const require_telemetry_client = require('../telemetry-client.cjs'); let _copilotkit_shared = require("@copilotkit/shared"); //#region src/lib/runtime/copilot-runtime.ts /** * <Callout type="info"> * This is the reference for the `CopilotRuntime` class. For more information and example code snippets, please see [Concept: Copilot Runtime](/concepts/copilot-runtime). * </Callout> * * ## Usage * * ```tsx * import { CopilotRuntime } from "@copilotkit/runtime"; * * const copilotKit = new CopilotRuntime(); * ``` */ /** * Central runtime object passed to all request handlers. */ var CopilotRuntime = class { constructor(params) { this.mcpToolsCache = /* @__PURE__ */ new Map(); require_telemetry_disclosure.logRuntimeTelemetryDisclosure(); const agents = params?.agents ?? {}; const endpointAgents = this.assignEndpointsToAgents(params?.remoteEndpoints ?? []); let mergedAgents; if (typeof agents === "function") mergedAgents = async (ctx) => { const resolved = await agents(ctx); return { ...endpointAgents, ...resolved }; }; else mergedAgents = Promise.resolve(agents).then((resolved) => ({ ...endpointAgents, ...resolved })); const baseRunner = params?.runner ?? new require_in_memory.InMemoryAgentRunner(); const runner = (0, _copilotkit_shared.isTelemetryDisabled)() ? baseRunner : new require_telemetry_agent_runner.TelemetryAgentRunner({ runner: baseRunner }); const resolvedLicenseToken = params?.licenseToken ?? process.env.COPILOTKIT_LICENSE_TOKEN; if (resolvedLicenseToken) require_telemetry_client.default.setLicenseToken(resolvedLicenseToken); this.runtimeArgs = { agents: mergedAgents, runner, licenseToken: params?.licenseToken, debug: params?.debug, beforeRequestMiddleware: this.createOnBeforeRequestHandler(params).bind(this), ...params?.afterRequestMiddleware || params?.middleware?.onAfterRequest ? { afterRequestMiddleware: this.createOnAfterRequestHandler(params).bind(this) } : {}, a2ui: params?.a2ui, mcpApps: params?.mcpApps, openGenerativeUI: params?.openGenerativeUI }; this.params = params; this.observability = params?.observability_c; } get instance() { if (!this._instance) this._instance = new require_runtime$1.CopilotRuntime(this.runtimeArgs); return this._instance; } assignEndpointsToAgents(endpoints) { let result = {}; if (endpoints.some((endpoint) => resolveEndpointType(endpoint) == require_types.EndpointType.LangGraphPlatform)) throw new _copilotkit_shared.CopilotKitMisuseError({ message: "LangGraphPlatformEndpoint in remoteEndpoints is deprecated. Please use the \"agents\" option instead with LangGraphAgent from \"@copilotkit/runtime/langgraph\". Example: agents: { myAgent: new LangGraphAgent({ deploymentUrl: \"...\", graphId: \"...\" }) }" }); return result; } handleServiceAdapter(serviceAdapter) { this.runtimeArgs.agents = Promise.resolve(this.runtimeArgs.agents ?? {}).then(async (agents) => { let agentsList = agents; const isAgentsListEmpty = !Object.keys(agents).length; const hasServiceAdapter = Boolean(serviceAdapter); const serviceAdapterCanBeUsedForAgent = !["EmptyAdapter"].includes(serviceAdapter.name); if (isAgentsListEmpty && (!hasServiceAdapter || !serviceAdapterCanBeUsedForAgent)) throw new _copilotkit_shared.CopilotKitMisuseError({ message: "No default agent provided. Please provide a default agent in the runtime config." }); if (isAgentsListEmpty) { const languageModel = serviceAdapter.getLanguageModel?.(); if (languageModel) agentsList.default = new require_index.BuiltInAgent({ model: languageModel }); else if (serviceAdapter.provider && serviceAdapter.model) agentsList.default = new require_index.BuiltInAgent({ model: `${serviceAdapter.provider}/${serviceAdapter.model}` }); else throw new _copilotkit_shared.CopilotKitMisuseError({ message: `Service adapter "${serviceAdapter.name ?? "unknown"}" does not provide model information. When using adapters like LangChainAdapter without an explicit agents list, please provide a default agent in the runtime config. Example:\n new CopilotRuntime({\n agents: { default: new BuiltInAgent({ model: "openai/gpt-4o" }) }\n })` }); } const actions = this.params?.actions; if (actions) { const mcpTools = await this.getToolsFromMCP(); agentsList = this.assignToolsToAgents(agents, [...this.getToolsFromActions(actions), ...mcpTools]); } return agentsList; }); } getToolsFromActions(actions) { return (typeof actions === "function" ? actions({ properties: {}, url: void 0 }) : actions).map((action) => { const zodSchema = (0, _copilotkit_shared.getZodParameters)(action.parameters || []); return { name: action.name, description: action.description || "", parameters: zodSchema, execute: () => Promise.resolve() }; }); } assignToolsToAgents(agents, tools) { if (!tools?.length) return agents; const enrichedAgents = { ...agents }; for (const [agentId, agent] of Object.entries(enrichedAgents)) { const existingConfig = Reflect.get(agent, "config") ?? {}; if ("factory" in existingConfig) continue; const classicConfig = existingConfig; const existingTools = classicConfig.tools ?? []; const updatedConfig = { ...classicConfig, tools: [...existingTools, ...tools] }; Reflect.set(agent, "config", updatedConfig); enrichedAgents[agentId] = agent; } return enrichedAgents; } createOnBeforeRequestHandler(params) { return async (hookParams) => { const { request } = hookParams; const publicApiKey = request.headers.get("x-copilotcloud-public-api-key"); const body = await (0, _copilotkit_shared.readBody)(request); const forwardedProps = body?.forwardedProps; const cloudBaseUrl = process.env.COPILOT_CLOUD_BASE_URL || "https://api.cloud.copilotkit.ai"; require_telemetry_client.default.capture("oss.runtime.copilot_request_created", { "cloud.guardrails.enabled": forwardedProps?.cloud?.guardrails !== void 0, requestType: forwardedProps?.metadata?.requestType ?? "unknown", "cloud.api_key_provided": !!publicApiKey, ...publicApiKey ? { "cloud.public_api_key": publicApiKey } : {}, "cloud.base_url": cloudBaseUrl }); if (request.method === "GET" || !body) return; const middlewareResult = await params?.beforeRequestMiddleware?.(hookParams); if (params?.middleware?.onBeforeRequest) { const { request, runtime, path } = hookParams; const { inputMessages, outputMessages } = require_agui_to_gql.aguiToGQL(body.messages).reduce((acc, msg) => { if ("role" in msg && msg.role === "user") acc.inputMessages.push(msg); else acc.outputMessages.push(msg); return acc; }, { inputMessages: [], outputMessages: [] }); params.middleware.onBeforeRequest({ threadId: body.threadId, runId: body.runId, inputMessages, properties: body.forwardedProps, url: request.url }); } return middlewareResult; }; } createOnAfterRequestHandler(params) { return async (hookParams) => { params?.afterRequestMiddleware?.(hookParams); if (params?.middleware?.onAfterRequest) { const messages = hookParams.messages ?? []; params.middleware.onAfterRequest({ threadId: hookParams.threadId ?? "", runId: hookParams.runId, inputMessages: messages.filter((m) => "role" in m && m.role === "user"), outputMessages: messages.filter((m) => "role" in m && m.role !== "user"), properties: {}, url: hookParams.path }); } }; } /** * Log LLM request if observability is enabled */ async logObservabilityBeforeRequest(requestData) { try { await this.observability.hooks.handleRequest(requestData); } catch (error) { console.error("Error logging LLM request:", error); } } /** * Log final LLM response after request completes */ logObservabilityAfterRequest(outputMessagesPromise, baseData, streamedChunks, requestStartTime, publicApiKey) { try { outputMessagesPromise.then((outputMessages) => { const responseData = { threadId: baseData.threadId, runId: baseData.runId, model: baseData.model, output: this.observability.progressive ? streamedChunks : outputMessages, latency: Date.now() - requestStartTime, timestamp: Date.now(), provider: baseData.provider, isFinalResponse: true, agentName: baseData.agentName, nodeName: baseData.nodeName }; try { this.observability.hooks.handleResponse(responseData); } catch (logError) { console.error("Error logging LLM response:", logError); } }).catch((error) => { console.error("Failed to get output messages for logging:", error); }); } catch (error) { console.error("Error setting up logging for LLM response:", error); } } async getToolsFromMCP(options) { const runtimeMcpServers = this.params?.mcpServers ?? []; const createMCPClient = this.params?.createMCPClient; const requestMcpServers = (options?.properties)?.mcpServers ?? (options?.properties)?.mcpEndpoints ?? []; if (!((runtimeMcpServers?.length ?? 0) > 0 || (requestMcpServers?.length ?? 0) > 0)) return []; if (!createMCPClient) throw new _copilotkit_shared.CopilotKitMisuseError({ message: "MCP Integration Error: `mcpServers` were provided, but the `createMCPClient` function was not passed to the CopilotRuntime constructor. Please provide an implementation for `createMCPClient`." }); const effectiveEndpoints = (() => { const byUrl = /* @__PURE__ */ new Map(); for (const ep of runtimeMcpServers) if (ep?.endpoint) byUrl.set(ep.endpoint, ep); for (const ep of requestMcpServers) if (ep?.endpoint) byUrl.set(ep.endpoint, ep); return Array.from(byUrl.values()); })(); const allTools = []; for (const config of effectiveEndpoints) { const endpointUrl = config.endpoint; const cached = this.mcpToolsCache.get(endpointUrl); if (cached) { allTools.push(...cached); continue; } try { const toolsMap = await (await createMCPClient(config)).tools(); const toolDefs = Object.entries(toolsMap).map(([toolName, tool]) => { const zodSchema = (0, _copilotkit_shared.getZodParameters)(require_mcp_tools_utils.extractParametersFromSchema(tool)); return { name: toolName, description: tool.description || `MCP tool: ${toolName} (from ${endpointUrl})`, parameters: zodSchema, execute: () => Promise.resolve() }; }); this.mcpToolsCache.set(endpointUrl, toolDefs); allTools.push(...toolDefs); } catch (error) { console.error(`MCP: Failed to fetch tools from endpoint ${endpointUrl}. Skipping. Error:`, error); this.mcpToolsCache.set(endpointUrl, []); } } const dedupedByName = /* @__PURE__ */ new Map(); for (const tool of allTools) dedupedByName.set(tool.name, tool); return Array.from(dedupedByName.values()); } }; function copilotKitEndpoint(config) { return { ...config, type: require_types.EndpointType.CopilotKit }; } function langGraphPlatformEndpoint(config) { return { ...config, type: require_types.EndpointType.LangGraphPlatform }; } function resolveEndpointType(endpoint) { if (!endpoint.type) if ("deploymentUrl" in endpoint && "agents" in endpoint) return require_types.EndpointType.LangGraphPlatform; else return require_types.EndpointType.CopilotKit; return endpoint.type; } //#endregion exports.CopilotRuntime = CopilotRuntime; exports.copilotKitEndpoint = copilotKitEndpoint; exports.langGraphPlatformEndpoint = langGraphPlatformEndpoint; exports.resolveEndpointType = resolveEndpointType; //# sourceMappingURL=copilot-runtime.cjs.map