@copilotkit/runtime 1.75.1 → 1.76.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/converters/aisdk.cjs +68 -10
- package/dist/agent/converters/aisdk.cjs.map +1 -1
- package/dist/agent/converters/aisdk.d.cts.map +1 -1
- package/dist/agent/converters/aisdk.d.mts.map +1 -1
- package/dist/agent/converters/aisdk.mjs +67 -11
- package/dist/agent/converters/aisdk.mjs.map +1 -1
- package/dist/agent/converters/tanstack.cjs +8 -6
- package/dist/agent/converters/tanstack.cjs.map +1 -1
- package/dist/agent/converters/tanstack.d.cts.map +1 -1
- package/dist/agent/converters/tanstack.d.mts.map +1 -1
- package/dist/agent/converters/tanstack.mjs +9 -7
- package/dist/agent/converters/tanstack.mjs.map +1 -1
- package/dist/agent/converters/usage.cjs +8 -2
- package/dist/agent/converters/usage.cjs.map +1 -1
- package/dist/agent/converters/usage.d.cts +3 -1
- package/dist/agent/converters/usage.d.cts.map +1 -1
- package/dist/agent/converters/usage.d.mts +3 -1
- package/dist/agent/converters/usage.d.mts.map +1 -1
- package/dist/agent/converters/usage.mjs +8 -2
- package/dist/agent/converters/usage.mjs.map +1 -1
- package/dist/agent/index.cjs +164 -34
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +18 -6
- package/dist/agent/index.d.cts.map +1 -1
- package/dist/agent/index.d.mts +18 -6
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +166 -36
- package/dist/agent/index.mjs.map +1 -1
- package/dist/agent/mcp-tool-names.cjs +84 -0
- package/dist/agent/mcp-tool-names.cjs.map +1 -0
- package/dist/agent/mcp-tool-names.mjs +81 -0
- package/dist/agent/mcp-tool-names.mjs.map +1 -0
- package/dist/lib/runtime/copilot-runtime.cjs +20 -9
- package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.mjs +20 -9
- package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
- package/dist/package.cjs +6 -7
- package/dist/package.mjs +6 -7
- package/dist/v2/runtime/handlers/intelligence/connect.cjs +1 -0
- package/dist/v2/runtime/handlers/intelligence/connect.cjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/connect.mjs +1 -0
- package/dist/v2/runtime/handlers/intelligence/connect.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs +90 -4
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs +90 -4
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
- package/dist/v2/runtime/runner/in-memory.cjs +16 -1
- package/dist/v2/runtime/runner/in-memory.cjs.map +1 -1
- package/dist/v2/runtime/runner/in-memory.d.cts.map +1 -1
- package/dist/v2/runtime/runner/in-memory.d.mts.map +1 -1
- package/dist/v2/runtime/runner/in-memory.mjs +16 -1
- package/dist/v2/runtime/runner/in-memory.mjs.map +1 -1
- package/dist/v2/runtime/runner/intelligence.cjs +5 -2
- package/dist/v2/runtime/runner/intelligence.cjs.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.mjs +6 -3
- package/dist/v2/runtime/runner/intelligence.mjs.map +1 -1
- package/package.json +7 -10
|
@@ -8,6 +8,7 @@ import { createRuntimeErrorReporter, runtimeErrorReporterOption } from "../../v2
|
|
|
8
8
|
import { CopilotRuntime as CopilotRuntime$1 } from "../../v2/runtime/core/runtime.mjs";
|
|
9
9
|
import { EndpointType } from "./types.mjs";
|
|
10
10
|
import { extractParametersFromSchema } from "./mcp-tools-utils.mjs";
|
|
11
|
+
import { resolveMCPToolNames } from "../../agent/mcp-tool-names.mjs";
|
|
11
12
|
import { BuiltInAgent } from "../../agent/index.mjs";
|
|
12
13
|
import telemetryClient from "../telemetry-client.mjs";
|
|
13
14
|
import { CopilotKitMisuseError, getZodParameters, readBody } from "@copilotkit/shared";
|
|
@@ -116,11 +117,20 @@ var CopilotRuntime = class {
|
|
|
116
117
|
const baseAgents = typeof configuredAgents === "function" ? this.ensureDefaultAgent({ ...await configuredAgents({ request }) }, serviceAdapter) : await this.baseAgents;
|
|
117
118
|
const properties = await this.readRequestProperties(request);
|
|
118
119
|
const actions = this.params?.actions;
|
|
119
|
-
const
|
|
120
|
-
const
|
|
120
|
+
const mcpSources = await this.getToolsFromMCP({ properties });
|
|
121
|
+
const actionTools = actions ? this.getToolsFromActions(actions, {
|
|
121
122
|
properties,
|
|
122
123
|
url: request.url
|
|
123
|
-
}) : []
|
|
124
|
+
}) : [];
|
|
125
|
+
const mcpNames = resolveMCPToolNames(new Set(actionTools.map((tool) => tool.name)), mcpSources.map(({ label, tools }) => ({
|
|
126
|
+
label,
|
|
127
|
+
names: tools.map((tool) => tool.name)
|
|
128
|
+
})), "");
|
|
129
|
+
const mcpTools = mcpSources.flatMap(({ tools }, i) => tools.map((tool, j) => ({
|
|
130
|
+
...tool,
|
|
131
|
+
name: mcpNames[i][j]
|
|
132
|
+
})));
|
|
133
|
+
const tools = [...actionTools, ...mcpTools];
|
|
124
134
|
if (!tools.length) return baseAgents;
|
|
125
135
|
const perRequestAgents = {};
|
|
126
136
|
for (const [agentId, agent] of Object.entries(baseAgents)) {
|
|
@@ -297,8 +307,8 @@ var CopilotRuntime = class {
|
|
|
297
307
|
for (const ep of requestMcpServers) if (ep?.endpoint) byUrl.set(ep.endpoint, ep);
|
|
298
308
|
return Array.from(byUrl.values());
|
|
299
309
|
})();
|
|
300
|
-
const
|
|
301
|
-
for (const config of effectiveEndpoints) {
|
|
310
|
+
const sources = [];
|
|
311
|
+
for (const [index, config] of effectiveEndpoints.entries()) {
|
|
302
312
|
const endpointLabel = describeEndpoint(config.endpoint);
|
|
303
313
|
try {
|
|
304
314
|
const entry = await resolveMCPEntry(createMCPClient, config, async () => {
|
|
@@ -320,14 +330,15 @@ var CopilotRuntime = class {
|
|
|
320
330
|
})
|
|
321
331
|
};
|
|
322
332
|
});
|
|
323
|
-
|
|
333
|
+
sources.push({
|
|
334
|
+
label: `mcp${index + 1}`,
|
|
335
|
+
tools: entry.tools ?? []
|
|
336
|
+
});
|
|
324
337
|
} catch (error) {
|
|
325
338
|
console.error(`MCP: Failed to fetch tools from endpoint ${endpointLabel}. Skipping. Error:`, error);
|
|
326
339
|
}
|
|
327
340
|
}
|
|
328
|
-
|
|
329
|
-
for (const tool of allTools) dedupedByName.set(tool.name, tool);
|
|
330
|
-
return Array.from(dedupedByName.values());
|
|
341
|
+
return sources;
|
|
331
342
|
}
|
|
332
343
|
};
|
|
333
344
|
function copilotKitEndpoint(config) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copilot-runtime.mjs","names":["telemetry","CopilotRuntimeVNext"],"sources":["../../../../src/v1-deprecated/lib/runtime/copilot-runtime.ts"],"sourcesContent":["/*\n * V1 SDK DEPRECATED. USE V2 INSTEAD\n *\n * This file defines public v1 SDK exports. Use the exact v2 mappings below.\n * AI CODING AGENTS: Never copy, suggest, or generate these v1 APIs. Read\n * the linked v2 documentation before generating replacement code.\n *\n * @copilotkit/runtime — copilotKitEndpoint:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * @copilotkit/runtime — CopilotRuntime:\n * V2 import and usage:\n * import { CopilotRuntime } from \"@copilotkit/runtime/v2\";\n *\n * const runtime = new CopilotRuntime({ agents: {} });\n * V2 replacement source: packages/runtime/src/v2/runtime/core/runtime.ts\n * V2 docs: https://docs.copilotkit.ai/runtime-server-adapter\n * Migration note: V2 uses AG-UI runtime handlers instead of the v1 GraphQL adapter setup.\n *\n * @copilotkit/runtime — CopilotRuntimeConstructorParams_BASE:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * @copilotkit/runtime — langGraphPlatformEndpoint:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (LangGraph agents): https://docs.copilotkit.ai/agent-spec/langgraph\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * @copilotkit/runtime — resolveEndpointType:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * Migration guide: https://docs.copilotkit.ai/migrate/v2\n *\n * END V1 SDK DEPRECATED. USE V2 INSTEAD NOTICE\n */\n\n/**\n * <Callout type=\"info\">\n * This is the reference for the `CopilotRuntime` class. For more information and example code snippets, please see [Concept: Copilot Runtime](/backend/copilot-runtime).\n * </Callout>\n *\n * ## Usage\n *\n * ```tsx\n * import { CopilotRuntime } from \"@copilotkit/runtime\";\n *\n * const copilotKit = new CopilotRuntime();\n * ```\n */\n\nimport {\n CopilotKitMisuseError,\n readBody,\n getZodParameters,\n} from \"@copilotkit/shared\";\nimport {\n resolveMCPEntry,\n touchMCPEntry,\n describeEndpoint,\n} from \"./mcp-client-cache\";\nimport type {\n Action,\n CopilotErrorHandler,\n MaybePromise,\n NonEmptyRecord,\n Parameter,\n PartialBy,\n DebugConfig,\n TelemetryCapture,\n} from \"@copilotkit/shared\";\nimport type { RunAgentInput } from \"@ag-ui/core\";\nimport { aguiToGQL } from \"../../graphql/message-conversion/agui-to-gql\";\nimport type {\n CopilotServiceAdapter,\n RemoteChainParameters,\n} from \"../../service-adapters\";\nimport { CopilotRuntime as CopilotRuntimeVNext } from \"../../../v2/runtime/core/runtime\";\nimport { InMemoryAgentRunner } from \"../../../v2/runtime/runner\";\nimport {\n createRuntimeErrorReporter,\n runtimeErrorReporterOption,\n} from \"../../../v2/runtime/core/runtime-error-reporter\";\nimport type { RuntimeErrorReporterOptions } from \"../../../v2/runtime/core/runtime-error-reporter\";\nimport type {\n CopilotIntelligenceRuntimeOptions,\n CopilotRuntimeOptions,\n CopilotRuntimeOptions as CopilotRuntimeOptionsVNext,\n AgentsConfig,\n AgentsFactory,\n AgentFactoryContext,\n} from \"../../../v2/runtime/core/runtime\";\nimport type { AgentRunner } from \"../../../v2/runtime/runner\";\n\nexport type { AgentsConfig, AgentsFactory, AgentFactoryContext };\nimport telemetry from \"../telemetry-client\";\nimport { logRuntimeTelemetryDisclosure } from \"../telemetry-disclosure\";\n\nimport type { MessageInput } from \"../../graphql/inputs/message.input\";\nimport type { Message } from \"../../graphql/types/converted\";\n\nimport { EndpointType } from \"./types\";\nimport type {\n EndpointDefinition,\n CopilotKitEndpoint,\n LangGraphPlatformEndpoint,\n} from \"./types\";\n\nimport type {\n CopilotObservabilityConfig,\n LLMRequestData,\n LLMResponseData,\n} from \"../observability\";\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport {\n firstNonBlankLicenseToken,\n firstNonBlankTelemetryId,\n} from \"../../../v2/runtime/telemetry/telemetry-identity\";\n\n// +++ MCP Imports +++\nimport { extractParametersFromSchema } from \"./mcp-tools-utils\";\nimport type { MCPClient, MCPEndpointConfig, MCPTool } from \"./mcp-tools-utils\";\nimport { BuiltInAgent } from \"../../../agent\";\nimport type { BuiltInAgentClassicConfig } from \"../../../agent\";\n// Define the function type alias here or import if defined elsewhere\ntype CreateMCPClientFunction = (\n config: MCPEndpointConfig,\n) => Promise<MCPClient>;\n\ntype ActionsConfiguration<T extends Parameter[] | [] = []> =\n | Action<T>[]\n | ((ctx: { properties: any; url?: string }) => Action<T>[]);\n\ninterface OnBeforeRequestOptions {\n threadId?: string;\n runId?: string;\n inputMessages: Message[];\n properties: any;\n url?: string;\n}\n\ntype OnBeforeRequestHandler = (\n options: OnBeforeRequestOptions,\n) => void | Promise<void>;\n\ninterface OnAfterRequestOptions {\n threadId: string;\n runId?: string;\n inputMessages: Message[];\n outputMessages: Message[];\n properties: any;\n url?: string;\n}\n\ntype OnAfterRequestHandler = (\n options: OnAfterRequestOptions,\n) => void | Promise<void>;\n\ninterface OnStopGenerationOptions {\n threadId: string;\n runId?: string;\n url?: string;\n agentName?: string;\n lastMessage: MessageInput;\n}\ntype OnStopGenerationHandler = (\n options: OnStopGenerationOptions,\n) => void | Promise<void>;\n\ninterface Middleware {\n /**\n * A function that is called before the request is processed.\n */\n /**\n * @deprecated This middleware hook is deprecated and will be removed in a future version.\n * Use updated middleware integration methods in CopilotRuntimeVNext instead.\n */\n onBeforeRequest?: OnBeforeRequestHandler;\n\n /**\n * A function that is called after the request is processed.\n */\n /**\n * @deprecated This middleware hook is deprecated and will be removed in a future version.\n * Use updated middleware integration methods in CopilotRuntimeVNext instead.\n */\n onAfterRequest?: OnAfterRequestHandler;\n}\n\nexport interface CopilotRuntimeConstructorParams_BASE<\n T extends Parameter[] | [] = [],\n> {\n /** Standalone telemetry identity. Falls back to CPK_TELEMETRY_ID before legacy license identity. */\n telemetryId?: string;\n /**\n * Middleware to be used by the runtime.\n *\n * ```ts\n * onBeforeRequest: (options: {\n * threadId?: string;\n * runId?: string;\n * inputMessages: Message[];\n * properties: any;\n * }) => void | Promise<void>;\n * ```\n *\n * ```ts\n * onAfterRequest: (options: {\n * threadId?: string;\n * runId?: string;\n * inputMessages: Message[];\n * outputMessages: Message[];\n * properties: any;\n * }) => void | Promise<void>;\n * ```\n */\n /**\n * @deprecated This middleware hook is deprecated and will be removed in a future version.\n * Use updated middleware integration methods in CopilotRuntimeVNext instead.\n */\n middleware?: Middleware;\n\n /*\n * A list of server side actions that can be executed. Will be ignored when remoteActions are set\n */\n actions?: ActionsConfiguration<T>;\n\n /*\n * Deprecated: Use `remoteEndpoints`.\n */\n remoteActions?: CopilotKitEndpoint[];\n\n /*\n * A list of remote actions that can be executed.\n */\n remoteEndpoints?: EndpointDefinition[];\n\n /*\n * An array of LangServer URLs.\n */\n langserve?: RemoteChainParameters[];\n\n /**\n * Optional agent runner to use for SSE runtime.\n */\n runner?: AgentRunner;\n\n /*\n * A map of agent names to AGUI agents.\n * Example agent config:\n * ```ts\n * import { AbstractAgent } from \"@ag-ui/client\";\n * // ...\n * agents: {\n * \"support\": new CustomerSupportAgent(),\n * \"technical\": new TechnicalAgent()\n * }\n * ```\n */\n agents?: Record<string, AbstractAgent>;\n\n /*\n * Delegates agent state processing to the service adapter.\n *\n * When enabled, individual agent state requests will not be processed by the agent itself.\n * Instead, all processing will be handled by the service adapter.\n */\n delegateAgentProcessingToServiceAdapter?: boolean;\n\n /**\n * Configuration for LLM request/response logging.\n *\n * Example logging config:\n * ```ts\n * logging: {\n * enabled: true, // Enable or disable logging\n * progressive: true, // Set to false for buffered logging\n * logger: {\n * logRequest: (data) => langfuse.trace({ name: \"LLM Request\", input: data }),\n * logResponse: (data) => langfuse.trace({ name: \"LLM Response\", output: data }),\n * logError: (errorData) => langfuse.trace({ name: \"LLM Error\", metadata: errorData }),\n * },\n * }\n * ```\n */\n observability_c?: CopilotObservabilityConfig;\n\n /**\n * Configuration for connecting to Model Context Protocol (MCP) servers.\n * Allows fetching and using tools defined on external MCP-compliant servers.\n * Requires providing the `createMCPClient` function during instantiation.\n *\n * A request can also name its own servers, as `mcpServers` (or the older\n * `mcpEndpoints`) inside `forwardedProps` — that is what the frontend's\n * `setMcpServers` sends. Those are merged with this list and connected from\n * the server.\n *\n * That merge previously never ran: whatever the browser sent was accepted\n * and discarded. It now takes effect, so a deployment that has been sending\n * `setMcpServers` will start connecting to those endpoints without changing\n * anything on its side.\n *\n * The destination is therefore caller-controlled, not only config-controlled.\n * If your deployment does not mean to let the browser choose an MCP server,\n * check `config.endpoint` inside `createMCPClient` and reject anything\n * outside your allowlist. Without that check a request can aim the server at\n * a loopback, link-local, or otherwise internal address (SSRF).\n * @experimental\n */\n mcpServers?: MCPEndpointConfig[];\n\n /**\n * A function that creates an MCP client instance for a given endpoint configuration.\n * This function is responsible for using the appropriate MCP client library\n * (e.g., `@copilotkit/runtime`, `ai`) to establish a connection.\n * Required if `mcpServers` is provided.\n *\n * ```typescript\n * import { experimental_createMCPClient } from \"ai\"; // Import from vercel ai library\n * // ...\n * const runtime = new CopilotRuntime({\n * mcpServers: [{ endpoint: \"...\" }],\n * async createMCPClient(config) {\n * return await experimental_createMCPClient({\n * transport: {\n * type: \"sse\",\n * url: config.endpoint,\n * headers: config.apiKey\n * ? { Authorization: `Bearer ${config.apiKey}` }\n * : undefined,\n * },\n * });\n * }\n * });\n * ```\n *\n * Define this once, at module scope, if you build a new `CopilotRuntime`\n * per request. Connections are cached against the identity of this function\n * plus the endpoint config, and an inline function is a new object on every\n * request — so a per-request runtime with an inline factory opens a new\n * connection each time and never reuses one. A module-scope factory, which\n * is what the documented setup uses, shares connections across requests and\n * keeps the cache bounded by how many distinct credentials are in play\n * rather than by traffic.\n */\n createMCPClient?: CreateMCPClientFunction;\n\n /**\n * Optional error handler for comprehensive debugging and observability.\n *\n * @param errorEvent - Structured error event with rich debugging context\n *\n * @example\n * ```typescript\n * const runtime = new CopilotRuntime({\n * onError: (errorEvent) => {\n * debugDashboard.capture(errorEvent);\n * }\n * });\n * ```\n */\n onError?: CopilotErrorHandler;\n\n onStopGeneration?: OnStopGenerationHandler;\n\n /**\n * Enable debug logging for the runtime event pipeline.\n * Pass `true` for full output, or an object for granular control:\n *\n * ```ts\n * const runtime = new CopilotRuntime({\n * debug: true,\n * // or: debug: { events: true, lifecycle: true, verbose: false }\n * });\n * ```\n */\n debug?: DebugConfig;\n\n // /** Optional transcription service for audio processing. */\n // transcriptionService?: CopilotRuntimeOptionsVNext[\"transcriptionService\"];\n // /** Optional *before* middleware – callback function or webhook URL. */\n // beforeRequestMiddleware?: CopilotRuntimeOptionsVNext[\"beforeRequestMiddleware\"];\n // /** Optional *after* middleware – callback function or webhook URL. */\n // afterRequestMiddleware?: CopilotRuntimeOptionsVNext[\"afterRequestMiddleware\"];\n}\n\ntype BeforeRequestMiddleware =\n CopilotRuntimeOptionsVNext[\"beforeRequestMiddleware\"];\ntype AfterRequestMiddleware =\n CopilotRuntimeOptionsVNext[\"afterRequestMiddleware\"];\ntype BeforeRequestMiddlewareFn = Exclude<BeforeRequestMiddleware, string>;\ntype BeforeRequestMiddlewareFnParameters =\n Parameters<BeforeRequestMiddlewareFn>;\ntype BeforeRequestMiddlewareFnResult = ReturnType<BeforeRequestMiddlewareFn>;\ntype AfterRequestMiddlewareFn = Exclude<AfterRequestMiddleware, string>;\ntype AfterRequestMiddlewareFnParameters = Parameters<AfterRequestMiddlewareFn>;\n\ninterface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []>\n extends\n Omit<CopilotRuntimeConstructorParams_BASE<T>, \"agents\">,\n Omit<CopilotRuntimeOptionsVNext, \"agents\" | \"transcriptionService\"> {\n /**\n * TODO: un-omit `transcriptionService` above once it's supported\n *\n * This satisfies...\n * – the optional constraint in `CopilotRuntimeConstructorParams_BASE`\n * – the `MaybePromise<NonEmptyRecord<T>>` constraint in `CopilotRuntimeOptionsVNext`\n * – the `Record<string, AbstractAgent>` constraint in `both\n */\n agents?: AgentsConfig;\n\n intelligence?: CopilotIntelligenceRuntimeOptions[\"intelligence\"];\n identifyUser?: CopilotIntelligenceRuntimeOptions[\"identifyUser\"];\n memory?: CopilotIntelligenceRuntimeOptions[\"memory\"];\n channels?: CopilotIntelligenceRuntimeOptions[\"channels\"];\n ɵlearning?: CopilotIntelligenceRuntimeOptions[\"ɵlearning\"];\n generateThreadNames?: CopilotIntelligenceRuntimeOptions[\"generateThreadNames\"];\n maxReconnectMs?: CopilotIntelligenceRuntimeOptions[\"maxReconnectMs\"];\n maxRejoinMs?: CopilotIntelligenceRuntimeOptions[\"maxRejoinMs\"];\n lockTtlSeconds?: CopilotIntelligenceRuntimeOptions[\"lockTtlSeconds\"];\n lockKeyPrefix?: CopilotIntelligenceRuntimeOptions[\"lockKeyPrefix\"];\n lockHeartbeatIntervalSeconds?: CopilotIntelligenceRuntimeOptions[\"lockHeartbeatIntervalSeconds\"];\n}\n\n/**\n * Central runtime object passed to all request handlers.\n * @deprecated The v1 SDK is deprecated. Use v2 instead. Use `CopilotRuntime` from `@copilotkit/runtime/v2` instead.\n *\n * ```tsx\n * import { CopilotRuntime } from \"@copilotkit/runtime/v2\";\n *\n * const runtime = new CopilotRuntime({ agents: {} });\n * ```\n * See https://docs.copilotkit.ai/runtime-server-adapter\n */\nexport class CopilotRuntime<const T extends Parameter[] | [] = []> {\n params?: CopilotRuntimeConstructorParams<T>;\n private observability?: CopilotObservabilityConfig;\n /**\n * The request-independent half of agent resolution: validation, and the\n * default agent built from the service adapter. Resolved once, because\n * re-running the misuse checks on every request would turn a configuration\n * error into a per-request throw.\n */\n private baseAgents?: Promise<Record<string, AbstractAgent>>;\n /**\n * The `agents` value as configured, captured before the per-request factory\n * replaces it, so that repeated `handleServiceAdapter` calls do not wrap the\n * factory in itself.\n */\n private configuredAgents?: CopilotRuntimeOptions[\"agents\"];\n private runtimeArgs: CopilotRuntimeOptions & RuntimeErrorReporterOptions;\n private _instance: CopilotRuntimeVNext;\n /** Runtime-bound telemetry identity and sampling authority. */\n public readonly telemetry: TelemetryCapture;\n\n constructor(params?: CopilotRuntimeConstructorParams<T>) {\n logRuntimeTelemetryDisclosure();\n\n const agents = params?.agents ?? {};\n const endpointAgents = this.assignEndpointsToAgents(\n params?.remoteEndpoints ?? [],\n );\n\n // Merge endpoint agents with user-provided agents.\n // When agents is a factory function, wrap it so endpoint agents are merged\n // at resolution time (spreading a function produces {} — silent data loss).\n let mergedAgents: AgentsConfig;\n if (typeof agents === \"function\") {\n mergedAgents = async (ctx) => {\n const resolved = await agents(ctx);\n return { ...endpointAgents, ...resolved };\n };\n } else {\n mergedAgents = Promise.resolve(agents).then((resolved) => ({\n ...endpointAgents,\n ...resolved,\n }));\n }\n\n // Resolve identity once and bind it to this compatibility Runtime. The\n // capture scope shares process-level sinks and settings without exposing\n // mutable identity to other live runtimes.\n const resolvedLicenseToken = firstNonBlankLicenseToken(\n params?.licenseToken,\n process.env.COPILOTKIT_LICENSE_TOKEN,\n );\n const resolvedTelemetryId = firstNonBlankTelemetryId(\n params?.telemetryId,\n process.env.CPK_TELEMETRY_ID,\n );\n const resolvedTelemetryIdentity =\n resolvedTelemetryId !== undefined\n ? { telemetryId: resolvedTelemetryId }\n : resolvedLicenseToken !== undefined\n ? { licenseToken: resolvedLicenseToken }\n : {};\n this.telemetry = telemetry.createScope(resolvedTelemetryIdentity);\n\n // No TelemetryAgentRunner wrap. The V2 SSE path already emits\n // `agent_execution_stream_*` for this runtime, and since it now emits\n // through this entrypoint's scope, wrapping would put two copies of\n // every stream event on the wire. The class stays exported for callers\n // who construct it themselves. The rawEvent enrichment it used to add\n // moved to `v2/runtime/handlers/shared/sse-response.ts`, so nothing is\n // lost and v2 callers gain it too.\n const runner = params?.runner ?? new InMemoryAgentRunner();\n\n const sharedRuntimeArgs = {\n agents: mergedAgents,\n telemetryId: resolvedTelemetryId,\n licenseToken: resolvedLicenseToken,\n // Emit through this entrypoint's own scope rather than letting the\n // delegated V2 runtime build its own. That scope writes to Segment\n // and stamps the v1 surface, so handing it down is what lets the v1\n // middleware below stop emitting the same events a second time.\n ɵtelemetry: this.telemetry,\n telemetryProperties: params?.telemetryProperties,\n debug: params?.debug,\n // TODO: add support for transcriptionService from CopilotRuntimeOptionsVNext once it is ready\n // transcriptionService: params?.transcriptionService,\n\n beforeRequestMiddleware:\n this.createOnBeforeRequestHandler(params).bind(this),\n ...(params?.afterRequestMiddleware || params?.middleware?.onAfterRequest\n ? {\n afterRequestMiddleware:\n this.createOnAfterRequestHandler(params).bind(this),\n }\n : {}),\n a2ui: params?.a2ui,\n mcpApps: params?.mcpApps,\n openGenerativeUI: params?.openGenerativeUI,\n [runtimeErrorReporterOption]: createRuntimeErrorReporter(params?.onError),\n forwardHeaders: params?.forwardHeaders,\n exposeMemoryRoutes: params?.exposeMemoryRoutes,\n };\n if (params?.intelligence !== undefined) {\n // The compatibility constructor keeps Intelligence identity optional at\n // compile time, while the v2 runtime checks that callers supply web\n // identity, Channels, or both. Preserve that runtime validation here.\n this.runtimeArgs = {\n ...sharedRuntimeArgs,\n intelligence: params.intelligence,\n identifyUser: params.identifyUser,\n memory: params.memory,\n channels: params.channels,\n ɵlearning: params.ɵlearning,\n generateThreadNames: params.generateThreadNames,\n maxReconnectMs: params.maxReconnectMs,\n maxRejoinMs: params.maxRejoinMs,\n lockTtlSeconds: params.lockTtlSeconds,\n lockKeyPrefix: params.lockKeyPrefix,\n lockHeartbeatIntervalSeconds: params.lockHeartbeatIntervalSeconds,\n } as CopilotRuntimeOptions;\n } else {\n this.runtimeArgs = {\n ...sharedRuntimeArgs,\n runner,\n };\n }\n this.params = params;\n this.observability = params?.observability_c;\n }\n\n get instance() {\n if (!this._instance) {\n this._instance = new CopilotRuntimeVNext(this.runtimeArgs);\n }\n\n return this._instance;\n }\n\n private assignEndpointsToAgents(\n endpoints: CopilotRuntimeConstructorParams<T>[\"remoteEndpoints\"],\n ): Record<string, AbstractAgent> {\n let result: Record<string, AbstractAgent> = {};\n\n if (\n endpoints.some(\n (endpoint) =>\n resolveEndpointType(endpoint) == EndpointType.LangGraphPlatform,\n )\n ) {\n throw new CopilotKitMisuseError({\n message:\n \"LangGraphPlatformEndpoint in remoteEndpoints is deprecated. \" +\n 'Please use the \"agents\" option instead with LangGraphAgent from \"@copilotkit/runtime/langgraph\". ' +\n 'Example: agents: { myAgent: new LangGraphAgent({ deploymentUrl: \"...\", graphId: \"...\" }) }',\n });\n }\n\n return result;\n }\n\n handleServiceAdapter(serviceAdapter: CopilotServiceAdapter) {\n // Capture the configured value before the factory below replaces it, so a\n // second call does not wrap the factory in itself.\n this.configuredAgents ??= this.runtimeArgs.agents ?? {};\n const configuredAgents = this.configuredAgents;\n\n // Resolve the request-independent half once. Calling this twice (the\n // endpoint factory runs on every request under the documented v1 route)\n // must not re-validate or rebuild the default agent.\n //\n // A caller who supplied their own agents factory has no request-independent\n // half: their record is whatever they return for this request, so the same\n // checks run per request further down.\n if (typeof configuredAgents !== \"function\") {\n this.baseAgents ??= Promise.resolve(configuredAgents).then((agents) =>\n this.ensureDefaultAgent(\n agents as Record<string, AbstractAgent>,\n serviceAdapter,\n ),\n );\n // A misconfigured adapter rejects that promise, and nothing awaits it\n // until the first request arrives. Attach an inert handler so a runtime\n // that is never called does not surface an unhandled rejection; the\n // factory below still sees the rejection when it awaits.\n this.baseAgents.catch(() => {});\n }\n\n // Install the per-request factory the v2 runtime has supported since\n // #2941. Resolving once was what kept a dynamic `actions` function from\n // ever seeing request properties, and kept every request sharing one MCP\n // client regardless of whose credentials built it (#7116, #2407).\n const resolvePerRequest = async ({ request }: { request: Request }) => {\n // A caller-supplied agents factory is called here, with this request.\n // Treating it as a record instead (a function has no enumerable keys)\n // meant the service adapter's default replaced it and the caller's\n // function was never invoked at all.\n const baseAgents =\n typeof configuredAgents === \"function\"\n ? this.ensureDefaultAgent(\n { ...(await configuredAgents({ request })) },\n serviceAdapter,\n )\n : await this.baseAgents!;\n const properties = await this.readRequestProperties(request);\n const actions = this.params?.actions;\n\n // `actions` and `mcpServers` are attached independently: a runtime may\n // configure MCP servers without any local actions.\n const mcpTools = await this.getToolsFromMCP({ properties });\n const actionTools = actions\n ? this.getToolsFromActions(actions, { properties, url: request.url })\n : [];\n const tools = [...actionTools, ...mcpTools];\n\n // Nothing to attach means nothing to isolate: hand the record back\n // untouched, exactly as a runtime with no actions and no MCP behaved\n // before this became a factory.\n if (!tools.length) {\n return baseAgents;\n }\n\n // Clone before attaching. `assignToolsToAgents` writes `config` onto the\n // agent, so mutating the shared instances would let one request's tools\n // reach another request that is already in flight.\n const perRequestAgents: Record<string, AbstractAgent> = {};\n for (const [agentId, agent] of Object.entries(baseAgents)) {\n const clone = agent.clone() as AbstractAgent;\n // `BuiltInAgent.clone()` rebuilds from `this.config`, so its own tools\n // survive. An agent whose `clone()` does not know about `config` --\n // `HttpAgent`, and anything else a v1 user registered -- would arrive\n // here empty, and the tools it declares itself would be shadowed by a\n // v1 action of the same name. Carry the config across when the clone\n // did not.\n if (\n Reflect.get(clone, \"config\") === undefined &&\n Reflect.get(agent, \"config\") !== undefined\n ) {\n Reflect.set(clone, \"config\", Reflect.get(agent, \"config\"));\n }\n perRequestAgents[agentId] = clone;\n }\n\n return this.assignToolsToAgents(perRequestAgents, tools);\n };\n\n this.runtimeArgs.agents =\n resolvePerRequest as unknown as CopilotRuntimeOptions[\"agents\"];\n }\n\n /**\n * Fill in the default agent the service adapter implies, and reject a\n * configuration that names no model at all.\n */\n private ensureDefaultAgent(\n agentsList: Record<string, AbstractAgent>,\n serviceAdapter: CopilotServiceAdapter,\n ): Record<string, AbstractAgent> {\n const isAgentsListEmpty = !Object.keys(agentsList).length;\n const hasServiceAdapter = Boolean(serviceAdapter);\n const illegalServiceAdapterNames = [\"EmptyAdapter\"];\n const serviceAdapterCanBeUsedForAgent =\n !illegalServiceAdapterNames.includes(serviceAdapter.name);\n\n if (\n isAgentsListEmpty &&\n (!hasServiceAdapter || !serviceAdapterCanBeUsedForAgent)\n ) {\n throw new CopilotKitMisuseError({\n message:\n \"No default agent provided. Please provide a default agent in the runtime config.\",\n });\n }\n\n if (isAgentsListEmpty) {\n const languageModel = serviceAdapter.getLanguageModel?.();\n if (languageModel) {\n // Adapter exposes a pre-configured LanguageModel (e.g. OpenAI/Anthropic adapters)\n agentsList.default = new BuiltInAgent({ model: languageModel });\n } else if (serviceAdapter.provider && serviceAdapter.model) {\n // Adapter exposes provider/model strings\n agentsList.default = new BuiltInAgent({\n model: `${serviceAdapter.provider}/${serviceAdapter.model}`,\n });\n } else {\n throw new CopilotKitMisuseError({\n message:\n `Service adapter \"${serviceAdapter.name ?? \"unknown\"}\" does not provide model information. ` +\n `When using adapters like LangChainAdapter without an explicit agents list, ` +\n `please provide a default agent in the runtime config. Example:\\n` +\n ` new CopilotRuntime({\\n` +\n ` agents: { default: new BuiltInAgent({ model: \"openai/gpt-4o\" }) }\\n` +\n ` })`,\n });\n }\n }\n\n return agentsList;\n }\n\n /**\n * The `forwardedProps` the browser sent with this request, which is what a\n * v1 `actions` function and `mcpServers` overrides are documented to read.\n *\n * `readBody` clones, so the handler still gets an unconsumed body, and it\n * returns `undefined` for GET, which is how the `/info` route reaches here.\n */\n private async readRequestProperties(\n request: Request,\n ): Promise<Record<string, unknown>> {\n try {\n const body = (await readBody(request)) as RunAgentInput | undefined;\n const properties = body?.forwardedProps;\n return properties && typeof properties === \"object\"\n ? (properties as Record<string, unknown>)\n : {};\n } catch {\n // A malformed body is the request handler's problem to report, not a\n // reason to fail agent resolution.\n return {};\n }\n }\n\n // Receive this.params.action and turn it into the AbstractAgent tools\n private getToolsFromActions(\n actions: ActionsConfiguration<any>,\n ctx: { properties: Record<string, unknown>; url?: string },\n ): BuiltInAgentClassicConfig[\"tools\"] {\n // Resolve actions to an array (handle function case).\n //\n // The function form is documented to receive the request's properties and\n // url. It was called once at resolution time with `{ properties: {}, url:\n // undefined }`, so a runtime that keyed its action list on the tenant, the\n // user, or anything else request-shaped got the same empty context every\n // time (#7116).\n const actionsArray =\n typeof actions === \"function\"\n ? actions({ properties: ctx.properties, url: ctx.url })\n : actions;\n\n // Convert each Action to a ToolDefinition\n return actionsArray.map((action) => {\n // Convert JSON schema to Zod schema\n const zodSchema = getZodParameters(action.parameters || []);\n\n return {\n name: action.name,\n description: action.description || \"\",\n parameters: zodSchema,\n // `handler` is an in-process function and was never part of the remote\n // executor deleted in v1.50.0 — only the wiring to it was lost. Call it.\n //\n // The result must never be `undefined`: `JSON.stringify(undefined)` is\n // not a string, which strips the required `content` off\n // TOOL_CALL_RESULT and surfaces as a Zod error in the browser\n // (#2915, #3198). Both branches below return a string instead.\n execute: async (args: unknown) => {\n if (typeof action.handler !== \"function\") {\n return (\n `The tool \"${action.name}\" was advertised without a handler, so it ` +\n `has no implementation to run. Tell the user this tool is unavailable.`\n );\n }\n const result = await action.handler(args as any);\n return result === undefined\n ? `The tool \"${action.name}\" ran and returned no value.`\n : result;\n },\n };\n });\n }\n\n private assignToolsToAgents(\n agents: Record<string, AbstractAgent>,\n tools: BuiltInAgentClassicConfig[\"tools\"],\n ): Record<string, AbstractAgent> {\n if (!tools?.length) {\n return agents;\n }\n\n const enrichedAgents: Record<string, AbstractAgent> = { ...agents };\n\n for (const [agentId, agent] of Object.entries(enrichedAgents)) {\n const existingConfig = (Reflect.get(agent, \"config\") ?? {}) as Record<\n string,\n unknown\n >;\n\n // Skip factory-mode agents — they don't have a tools property\n if (\"factory\" in existingConfig) {\n continue;\n }\n\n const classicConfig =\n existingConfig as unknown as BuiltInAgentClassicConfig;\n const existingTools = classicConfig.tools ?? [];\n\n // The endpoint factory runs `handleServiceAdapter` every time it is\n // called, and the documented v1 route builds the endpoint inside the\n // request handler — so a module-scope runtime lands here once per\n // request. Appending unconditionally advertised N copies of every tool\n // to the model. Skip names the agent already carries, which also leaves\n // a tool the agent defines itself in place.\n const existingNames = new Set(existingTools.map((tool) => tool.name));\n const newTools = tools.filter((tool) => !existingNames.has(tool.name));\n if (newTools.length === 0) {\n continue;\n }\n\n const updatedConfig: BuiltInAgentClassicConfig = {\n ...classicConfig,\n tools: [...existingTools, ...newTools],\n };\n\n Reflect.set(agent, \"config\", updatedConfig);\n enrichedAgents[agentId] = agent;\n }\n\n return enrichedAgents;\n }\n\n private createOnBeforeRequestHandler(\n params?: CopilotRuntimeConstructorParams<T> &\n PartialBy<CopilotRuntimeOptions, \"agents\">,\n ) {\n return async (hookParams: BeforeRequestMiddlewareFnParameters[0]) => {\n const { request } = hookParams;\n\n // No `copilot_request_created` capture here. The V2 handlers this\n // runtime delegates to already emit it, through this runtime's own\n // scope, and they know the route — so `requestType` is \"run\" or\n // \"connect\" rather than the \"unknown\" this site reported for every\n // request that did not set `forwardedProps.metadata.requestType`.\n const body = (await readBody(request)) as RunAgentInput;\n\n // We do not process middleware for the internal GET requests\n if (request.method === \"GET\" || !body) return;\n\n // TODO: get public api key and run with expected data\n // if (this.observability?.enabled && this.params.publicApiKey) {\n // this.logObservabilityBeforeRequest()\n // }\n\n // TODO: replace hooksParams top argument type with BeforeRequestMiddlewareParameters when exported\n const middlewareResult =\n await params?.beforeRequestMiddleware?.(hookParams);\n\n if (params?.middleware?.onBeforeRequest) {\n const { request, runtime, path } = hookParams;\n const gqlMessages = (aguiToGQL(body.messages) as Message[]).reduce(\n (acc, msg) => {\n if (\"role\" in msg && msg.role === \"user\") {\n acc.inputMessages.push(msg);\n } else {\n acc.outputMessages.push(msg);\n }\n return acc;\n },\n { inputMessages: [] as Message[], outputMessages: [] as Message[] },\n );\n const { inputMessages, outputMessages } = gqlMessages;\n params.middleware.onBeforeRequest({\n threadId: body.threadId,\n runId: body.runId,\n inputMessages,\n properties: body.forwardedProps,\n url: request.url,\n } satisfies OnBeforeRequestOptions);\n }\n\n return middlewareResult;\n };\n }\n\n private createOnAfterRequestHandler(\n params?: CopilotRuntimeConstructorParams<T> &\n PartialBy<CopilotRuntimeOptions, \"agents\">,\n ) {\n return async (hookParams: AfterRequestMiddlewareFnParameters[0]) => {\n // TODO: get public api key and run with expected data\n // if (this.observability?.enabled && publicApiKey) {\n // this.logObservabilityAfterRequest()\n // }\n\n // TODO: replace hooksParams top argument type with AfterRequestMiddlewareParameters when exported\n params?.afterRequestMiddleware?.(hookParams);\n\n if (params?.middleware?.onAfterRequest) {\n const messages = hookParams.messages ?? [];\n params.middleware.onAfterRequest({\n threadId: hookParams.threadId ?? \"\",\n runId: hookParams.runId,\n inputMessages: messages.filter(\n (m): m is typeof m & { role: string } =>\n \"role\" in m && m.role === \"user\",\n ) as unknown as Message[],\n outputMessages: messages.filter(\n (m): m is typeof m & { role: string } =>\n \"role\" in m && m.role !== \"user\",\n ) as unknown as Message[],\n // TODO: forward actual properties once the after-request hook has access to the request body\n properties: {},\n url: hookParams.path,\n } satisfies OnAfterRequestOptions);\n }\n };\n }\n\n // Observability Methods\n\n /**\n * Log LLM request if observability is enabled\n */\n private async logObservabilityBeforeRequest(\n requestData: LLMRequestData,\n ): Promise<void> {\n try {\n await this.observability.hooks.handleRequest(requestData);\n } catch (error) {\n console.error(\"Error logging LLM request:\", error);\n }\n }\n\n /**\n * Log final LLM response after request completes\n */\n private logObservabilityAfterRequest(\n outputMessagesPromise: Promise<Message[]>,\n baseData: {\n threadId: string;\n runId?: string;\n model?: string;\n provider?: string;\n agentName?: string;\n nodeName?: string;\n },\n streamedChunks: any[],\n requestStartTime: number,\n publicApiKey?: string,\n ): void {\n try {\n outputMessagesPromise\n .then((outputMessages) => {\n const responseData: LLMResponseData = {\n threadId: baseData.threadId,\n runId: baseData.runId,\n model: baseData.model,\n // Use collected chunks for progressive mode or outputMessages for regular mode\n output: this.observability.progressive\n ? streamedChunks\n : outputMessages,\n latency: Date.now() - requestStartTime,\n timestamp: Date.now(),\n provider: baseData.provider,\n isFinalResponse: true,\n agentName: baseData.agentName,\n nodeName: baseData.nodeName,\n };\n\n try {\n this.observability.hooks.handleResponse(responseData);\n } catch (logError) {\n console.error(\"Error logging LLM response:\", logError);\n }\n })\n .catch((error) => {\n console.error(\"Failed to get output messages for logging:\", error);\n });\n } catch (error) {\n console.error(\"Error setting up logging for LLM response:\", error);\n }\n }\n\n // Resolve MCP tools to BuiltInAgent tool definitions\n // Optionally accepts request-scoped properties to merge request-provided mcpServers\n private async getToolsFromMCP(options?: {\n properties?: Record<string, unknown>;\n }): Promise<BuiltInAgentClassicConfig[\"tools\"]> {\n const runtimeMcpServers = (this.params?.mcpServers ??\n []) as MCPEndpointConfig[];\n const createMCPClient = this.params?.createMCPClient as\n | CreateMCPClientFunction\n | undefined;\n\n // If no runtime config and no request overrides, nothing to do\n const requestMcpServers = ((\n options?.properties as { mcpServers?: MCPEndpointConfig[] } | undefined\n )?.mcpServers ??\n (\n options?.properties as\n | { mcpEndpoints?: MCPEndpointConfig[] }\n | undefined\n )?.mcpEndpoints ??\n []) as MCPEndpointConfig[];\n\n const hasAnyServers =\n (runtimeMcpServers?.length ?? 0) > 0 ||\n (requestMcpServers?.length ?? 0) > 0;\n if (!hasAnyServers) {\n return [];\n }\n\n if (!createMCPClient) {\n // Mirror legacy behavior: when servers are provided without a factory, treat as misconfiguration\n throw new CopilotKitMisuseError({\n message:\n \"MCP Integration Error: `mcpServers` were provided, but the `createMCPClient` function was not passed to the CopilotRuntime constructor. Please provide an implementation for `createMCPClient`.\",\n });\n }\n\n // Merge and dedupe endpoints by URL; request-level overrides take precedence.\n //\n // `requestMcpServers` is caller-supplied: it arrives in `forwardedProps`\n // from the browser. Validating it here is not this shim's call — the\n // endpoint shape, the transport, and the auth all belong to the\n // application's `createMCPClient`, and a hardcoded allowlist would break\n // the multi-tenant case this per-request path exists to serve. The\n // constraint is documented on `mcpServers` instead: a deployment that does\n // not intend browser-chosen servers has to reject them in its factory.\n const effectiveEndpoints = (() => {\n const byUrl = new Map<string, MCPEndpointConfig>();\n for (const ep of runtimeMcpServers) {\n if (ep?.endpoint) byUrl.set(ep.endpoint, ep);\n }\n for (const ep of requestMcpServers) {\n if (ep?.endpoint) byUrl.set(ep.endpoint, ep);\n }\n return Array.from(byUrl.values());\n })();\n\n const allTools: BuiltInAgentClassicConfig[\"tools\"] = [];\n\n for (const config of effectiveEndpoints) {\n // Everything that leaves this process with the endpoint in it uses the\n // redacted form: the raw URL's query can carry the credential, which is\n // exactly what the #2407 workaround puts there.\n const endpointLabel = describeEndpoint(config.endpoint);\n\n try {\n // Keyed by the client factory plus the whole config, so two callers\n // with different credentials for one endpoint get one client each.\n // Keying on the URL alone is #2407: the first caller's client served\n // everyone, and the reporter's `?uid=<hash>` workaround existed only\n // to force distinct keys.\n const entry = await resolveMCPEntry<BuiltInAgentClassicConfig[\"tools\"]>(\n createMCPClient,\n config,\n async () => {\n const client = await createMCPClient(config);\n const toolsMap = await client.tools();\n\n const toolDefs: BuiltInAgentClassicConfig[\"tools\"] = Object.entries(\n toolsMap,\n ).map(([toolName, tool]: [string, MCPTool]) => {\n const params: Parameter[] = extractParametersFromSchema(tool);\n const zodSchema = getZodParameters(params);\n return {\n name: toolName,\n description:\n tool.description ||\n `MCP tool: ${toolName} (from ${endpointLabel})`,\n parameters: zodSchema,\n // `tool.execute` calls the server over the cached client. That\n // client outlives this request but not necessarily this tool\n // definition: eviction can close it while these defs are still\n // held by an already-resolved agent.\n execute: async (args: unknown) => {\n // Executing is the only evidence this runtime gets that a\n // connection is still in use. Without it the entry ages from\n // the moment the agent resolved, and a busy process evicts\n // and closes a client that a live run is still calling.\n touchMCPEntry(createMCPClient, config);\n return tool.execute(args);\n },\n };\n });\n\n return { client, tools: toolDefs };\n },\n );\n\n allTools.push(...(entry.tools ?? []));\n } catch (error) {\n console.error(\n `MCP: Failed to fetch tools from endpoint ${endpointLabel}. Skipping. Error:`,\n error,\n );\n // Deliberately not cached. Caching the empty result meant a server\n // that was briefly unreachable when the runtime first resolved stayed\n // toolless for the life of that runtime, even after it recovered.\n // `resolveMCPEntry` drops a rejected entry so a later request retries.\n }\n }\n\n // Dedupe tools by name while preserving last-in wins (request overrides)\n const dedupedByName = new Map<string, (typeof allTools)[number]>();\n for (const tool of allTools) {\n dedupedByName.set(tool.name, tool);\n }\n\n return Array.from(dedupedByName.values());\n }\n}\n\n// The two functions below are \"factory functions\", meant to create the action objects that adhere to the expected interfaces\nexport function copilotKitEndpoint(\n config: Omit<CopilotKitEndpoint, \"type\">,\n): CopilotKitEndpoint {\n return {\n ...config,\n type: EndpointType.CopilotKit,\n };\n}\n\nexport function langGraphPlatformEndpoint(\n config: Omit<LangGraphPlatformEndpoint, \"type\">,\n): LangGraphPlatformEndpoint {\n return {\n ...config,\n type: EndpointType.LangGraphPlatform,\n };\n}\n\nexport function resolveEndpointType(endpoint: EndpointDefinition) {\n if (!endpoint.type) {\n if (\"deploymentUrl\" in endpoint && \"agents\" in endpoint) {\n return EndpointType.LangGraphPlatform;\n } else {\n return EndpointType.CopilotKit;\n }\n }\n\n return endpoint.type;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+bA,IAAa,iBAAb,MAAmE;CAqBjE,YAAY,QAA6C;AACvD,iCAA+B;EAE/B,MAAM,SAAS,QAAQ,UAAU,EAAE;EACnC,MAAM,iBAAiB,KAAK,wBAC1B,QAAQ,mBAAmB,EAAE,CAC9B;EAKD,IAAI;AACJ,MAAI,OAAO,WAAW,WACpB,gBAAe,OAAO,QAAQ;GAC5B,MAAM,WAAW,MAAM,OAAO,IAAI;AAClC,UAAO;IAAE,GAAG;IAAgB,GAAG;IAAU;;MAG3C,gBAAe,QAAQ,QAAQ,OAAO,CAAC,MAAM,cAAc;GACzD,GAAG;GACH,GAAG;GACJ,EAAE;EAML,MAAM,uBAAuB,0BAC3B,QAAQ,cACR,QAAQ,IAAI,yBACb;EACD,MAAM,sBAAsB,yBAC1B,QAAQ,aACR,QAAQ,IAAI,iBACb;EACD,MAAM,4BACJ,wBAAwB,SACpB,EAAE,aAAa,qBAAqB,GACpC,yBAAyB,SACvB,EAAE,cAAc,sBAAsB,GACtC,EAAE;AACV,OAAK,YAAYA,gBAAU,YAAY,0BAA0B;EASjE,MAAM,SAAS,QAAQ,UAAU,IAAI,qBAAqB;EAE1D,MAAM,oBAAoB;GACxB,QAAQ;GACR,aAAa;GACb,cAAc;GAKd,YAAY,KAAK;GACjB,qBAAqB,QAAQ;GAC7B,OAAO,QAAQ;GAIf,yBACE,KAAK,6BAA6B,OAAO,CAAC,KAAK,KAAK;GACtD,GAAI,QAAQ,0BAA0B,QAAQ,YAAY,iBACtD,EACE,wBACE,KAAK,4BAA4B,OAAO,CAAC,KAAK,KAAK,EACtD,GACD,EAAE;GACN,MAAM,QAAQ;GACd,SAAS,QAAQ;GACjB,kBAAkB,QAAQ;IACzB,6BAA6B,2BAA2B,QAAQ,QAAQ;GACzE,gBAAgB,QAAQ;GACxB,oBAAoB,QAAQ;GAC7B;AACD,MAAI,QAAQ,iBAAiB,OAI3B,MAAK,cAAc;GACjB,GAAG;GACH,cAAc,OAAO;GACrB,cAAc,OAAO;GACrB,QAAQ,OAAO;GACf,UAAU,OAAO;GACjB,WAAW,OAAO;GAClB,qBAAqB,OAAO;GAC5B,gBAAgB,OAAO;GACvB,aAAa,OAAO;GACpB,gBAAgB,OAAO;GACvB,eAAe,OAAO;GACtB,8BAA8B,OAAO;GACtC;MAED,MAAK,cAAc;GACjB,GAAG;GACH;GACD;AAEH,OAAK,SAAS;AACd,OAAK,gBAAgB,QAAQ;;CAG/B,IAAI,WAAW;AACb,MAAI,CAAC,KAAK,UACR,MAAK,YAAY,IAAIC,iBAAoB,KAAK,YAAY;AAG5D,SAAO,KAAK;;CAGd,AAAQ,wBACN,WAC+B;EAC/B,IAAI,SAAwC,EAAE;AAE9C,MACE,UAAU,MACP,aACC,oBAAoB,SAAS,IAAI,aAAa,kBACjD,CAED,OAAM,IAAI,sBAAsB,EAC9B,SACE,mQAGH,CAAC;AAGJ,SAAO;;CAGT,qBAAqB,gBAAuC;AAG1D,OAAK,qBAAqB,KAAK,YAAY,UAAU,EAAE;EACvD,MAAM,mBAAmB,KAAK;AAS9B,MAAI,OAAO,qBAAqB,YAAY;AAC1C,QAAK,eAAe,QAAQ,QAAQ,iBAAiB,CAAC,MAAM,WAC1D,KAAK,mBACH,QACA,eACD,CACF;AAKD,QAAK,WAAW,YAAY,GAAG;;EAOjC,MAAM,oBAAoB,OAAO,EAAE,cAAoC;GAKrE,MAAM,aACJ,OAAO,qBAAqB,aACxB,KAAK,mBACH,EAAE,GAAI,MAAM,iBAAiB,EAAE,SAAS,CAAC,EAAG,EAC5C,eACD,GACD,MAAM,KAAK;GACjB,MAAM,aAAa,MAAM,KAAK,sBAAsB,QAAQ;GAC5D,MAAM,UAAU,KAAK,QAAQ;GAI7B,MAAM,WAAW,MAAM,KAAK,gBAAgB,EAAE,YAAY,CAAC;GAI3D,MAAM,QAAQ,CAAC,GAHK,UAChB,KAAK,oBAAoB,SAAS;IAAE;IAAY,KAAK,QAAQ;IAAK,CAAC,GACnE,EAAE,EACyB,GAAG,SAAS;AAK3C,OAAI,CAAC,MAAM,OACT,QAAO;GAMT,MAAM,mBAAkD,EAAE;AAC1D,QAAK,MAAM,CAAC,SAAS,UAAU,OAAO,QAAQ,WAAW,EAAE;IACzD,MAAM,QAAQ,MAAM,OAAO;AAO3B,QACE,QAAQ,IAAI,OAAO,SAAS,KAAK,UACjC,QAAQ,IAAI,OAAO,SAAS,KAAK,OAEjC,SAAQ,IAAI,OAAO,UAAU,QAAQ,IAAI,OAAO,SAAS,CAAC;AAE5D,qBAAiB,WAAW;;AAG9B,UAAO,KAAK,oBAAoB,kBAAkB,MAAM;;AAG1D,OAAK,YAAY,SACf;;;;;;CAOJ,AAAQ,mBACN,YACA,gBAC+B;EAC/B,MAAM,oBAAoB,CAAC,OAAO,KAAK,WAAW,CAAC;EACnD,MAAM,oBAAoB,QAAQ,eAAe;EAEjD,MAAM,kCACJ,CAFiC,CAAC,eAAe,CAErB,SAAS,eAAe,KAAK;AAE3D,MACE,sBACC,CAAC,qBAAqB,CAAC,iCAExB,OAAM,IAAI,sBAAsB,EAC9B,SACE,oFACH,CAAC;AAGJ,MAAI,mBAAmB;GACrB,MAAM,gBAAgB,eAAe,oBAAoB;AACzD,OAAI,cAEF,YAAW,UAAU,IAAI,aAAa,EAAE,OAAO,eAAe,CAAC;YACtD,eAAe,YAAY,eAAe,MAEnD,YAAW,UAAU,IAAI,aAAa,EACpC,OAAO,GAAG,eAAe,SAAS,GAAG,eAAe,SACrD,CAAC;OAEF,OAAM,IAAI,sBAAsB,EAC9B,SACE,oBAAoB,eAAe,QAAQ,UAAU,uRAMxD,CAAC;;AAIN,SAAO;;;;;;;;;CAUT,MAAc,sBACZ,SACkC;AAClC,MAAI;GAEF,MAAM,cADQ,MAAM,SAAS,QAAQ,GACZ;AACzB,UAAO,cAAc,OAAO,eAAe,WACtC,aACD,EAAE;UACA;AAGN,UAAO,EAAE;;;CAKb,AAAQ,oBACN,SACA,KACoC;AAcpC,UALE,OAAO,YAAY,aACf,QAAQ;GAAE,YAAY,IAAI;GAAY,KAAK,IAAI;GAAK,CAAC,GACrD,SAGc,KAAK,WAAW;GAElC,MAAM,YAAY,iBAAiB,OAAO,cAAc,EAAE,CAAC;AAE3D,UAAO;IACL,MAAM,OAAO;IACb,aAAa,OAAO,eAAe;IACnC,YAAY;IAQZ,SAAS,OAAO,SAAkB;AAChC,SAAI,OAAO,OAAO,YAAY,WAC5B,QACE,aAAa,OAAO,KAAK;KAI7B,MAAM,SAAS,MAAM,OAAO,QAAQ,KAAY;AAChD,YAAO,WAAW,SACd,aAAa,OAAO,KAAK,gCACzB;;IAEP;IACD;;CAGJ,AAAQ,oBACN,QACA,OAC+B;AAC/B,MAAI,CAAC,OAAO,OACV,QAAO;EAGT,MAAM,iBAAgD,EAAE,GAAG,QAAQ;AAEnE,OAAK,MAAM,CAAC,SAAS,UAAU,OAAO,QAAQ,eAAe,EAAE;GAC7D,MAAM,iBAAkB,QAAQ,IAAI,OAAO,SAAS,IAAI,EAAE;AAM1D,OAAI,aAAa,eACf;GAGF,MAAM,gBACJ;GACF,MAAM,gBAAgB,cAAc,SAAS,EAAE;GAQ/C,MAAM,gBAAgB,IAAI,IAAI,cAAc,KAAK,SAAS,KAAK,KAAK,CAAC;GACrE,MAAM,WAAW,MAAM,QAAQ,SAAS,CAAC,cAAc,IAAI,KAAK,KAAK,CAAC;AACtE,OAAI,SAAS,WAAW,EACtB;GAGF,MAAM,gBAA2C;IAC/C,GAAG;IACH,OAAO,CAAC,GAAG,eAAe,GAAG,SAAS;IACvC;AAED,WAAQ,IAAI,OAAO,UAAU,cAAc;AAC3C,kBAAe,WAAW;;AAG5B,SAAO;;CAGT,AAAQ,6BACN,QAEA;AACA,SAAO,OAAO,eAAuD;GACnE,MAAM,EAAE,YAAY;GAOpB,MAAM,OAAQ,MAAM,SAAS,QAAQ;AAGrC,OAAI,QAAQ,WAAW,SAAS,CAAC,KAAM;GAQvC,MAAM,mBACJ,MAAM,QAAQ,0BAA0B,WAAW;AAErD,OAAI,QAAQ,YAAY,iBAAiB;IACvC,MAAM,EAAE,SAAS,SAAS,SAAS;IAYnC,MAAM,EAAE,eAAe,mBAXF,UAAU,KAAK,SAAS,CAAe,QACzD,KAAK,QAAQ;AACZ,SAAI,UAAU,OAAO,IAAI,SAAS,OAChC,KAAI,cAAc,KAAK,IAAI;SAE3B,KAAI,eAAe,KAAK,IAAI;AAE9B,YAAO;OAET;KAAE,eAAe,EAAE;KAAe,gBAAgB,EAAE;KAAe,CACpE;AAED,WAAO,WAAW,gBAAgB;KAChC,UAAU,KAAK;KACf,OAAO,KAAK;KACZ;KACA,YAAY,KAAK;KACjB,KAAK,QAAQ;KACd,CAAkC;;AAGrC,UAAO;;;CAIX,AAAQ,4BACN,QAEA;AACA,SAAO,OAAO,eAAsD;AAOlE,WAAQ,yBAAyB,WAAW;AAE5C,OAAI,QAAQ,YAAY,gBAAgB;IACtC,MAAM,WAAW,WAAW,YAAY,EAAE;AAC1C,WAAO,WAAW,eAAe;KAC/B,UAAU,WAAW,YAAY;KACjC,OAAO,WAAW;KAClB,eAAe,SAAS,QACrB,MACC,UAAU,KAAK,EAAE,SAAS,OAC7B;KACD,gBAAgB,SAAS,QACtB,MACC,UAAU,KAAK,EAAE,SAAS,OAC7B;KAED,YAAY,EAAE;KACd,KAAK,WAAW;KACjB,CAAiC;;;;;;;CAUxC,MAAc,8BACZ,aACe;AACf,MAAI;AACF,SAAM,KAAK,cAAc,MAAM,cAAc,YAAY;WAClD,OAAO;AACd,WAAQ,MAAM,8BAA8B,MAAM;;;;;;CAOtD,AAAQ,6BACN,uBACA,UAQA,gBACA,kBACA,cACM;AACN,MAAI;AACF,yBACG,MAAM,mBAAmB;IACxB,MAAM,eAAgC;KACpC,UAAU,SAAS;KACnB,OAAO,SAAS;KAChB,OAAO,SAAS;KAEhB,QAAQ,KAAK,cAAc,cACvB,iBACA;KACJ,SAAS,KAAK,KAAK,GAAG;KACtB,WAAW,KAAK,KAAK;KACrB,UAAU,SAAS;KACnB,iBAAiB;KACjB,WAAW,SAAS;KACpB,UAAU,SAAS;KACpB;AAED,QAAI;AACF,UAAK,cAAc,MAAM,eAAe,aAAa;aAC9C,UAAU;AACjB,aAAQ,MAAM,+BAA+B,SAAS;;KAExD,CACD,OAAO,UAAU;AAChB,YAAQ,MAAM,8CAA8C,MAAM;KAClE;WACG,OAAO;AACd,WAAQ,MAAM,8CAA8C,MAAM;;;CAMtE,MAAc,gBAAgB,SAEkB;EAC9C,MAAM,oBAAqB,KAAK,QAAQ,cACtC,EAAE;EACJ,MAAM,kBAAkB,KAAK,QAAQ;EAKrC,MAAM,qBACJ,SAAS,aACR,eAEC,SAAS,aAGR,gBACH,EAAE;AAKJ,MAAI,GAFD,mBAAmB,UAAU,KAAK,MAClC,mBAAmB,UAAU,KAAK,GAEnC,QAAO,EAAE;AAGX,MAAI,CAAC,gBAEH,OAAM,IAAI,sBAAsB,EAC9B,SACE,mMACH,CAAC;EAYJ,MAAM,4BAA4B;GAChC,MAAM,wBAAQ,IAAI,KAAgC;AAClD,QAAK,MAAM,MAAM,kBACf,KAAI,IAAI,SAAU,OAAM,IAAI,GAAG,UAAU,GAAG;AAE9C,QAAK,MAAM,MAAM,kBACf,KAAI,IAAI,SAAU,OAAM,IAAI,GAAG,UAAU,GAAG;AAE9C,UAAO,MAAM,KAAK,MAAM,QAAQ,CAAC;MAC/B;EAEJ,MAAM,WAA+C,EAAE;AAEvD,OAAK,MAAM,UAAU,oBAAoB;GAIvC,MAAM,gBAAgB,iBAAiB,OAAO,SAAS;AAEvD,OAAI;IAMF,MAAM,QAAQ,MAAM,gBAClB,iBACA,QACA,YAAY;KACV,MAAM,SAAS,MAAM,gBAAgB,OAAO;KAC5C,MAAM,WAAW,MAAM,OAAO,OAAO;AA4BrC,YAAO;MAAE;MAAQ,OA1BoC,OAAO,QAC1D,SACD,CAAC,KAAK,CAAC,UAAU,UAA6B;OAE7C,MAAM,YAAY,iBADU,4BAA4B,KAAK,CACnB;AAC1C,cAAO;QACL,MAAM;QACN,aACE,KAAK,eACL,aAAa,SAAS,SAAS,cAAc;QAC/C,YAAY;QAKZ,SAAS,OAAO,SAAkB;AAKhC,uBAAc,iBAAiB,OAAO;AACtC,gBAAO,KAAK,QAAQ,KAAK;;QAE5B;QACD;MAEgC;MAErC;AAED,aAAS,KAAK,GAAI,MAAM,SAAS,EAAE,CAAE;YAC9B,OAAO;AACd,YAAQ,MACN,4CAA4C,cAAc,qBAC1D,MACD;;;EASL,MAAM,gCAAgB,IAAI,KAAwC;AAClE,OAAK,MAAM,QAAQ,SACjB,eAAc,IAAI,KAAK,MAAM,KAAK;AAGpC,SAAO,MAAM,KAAK,cAAc,QAAQ,CAAC;;;AAK7C,SAAgB,mBACd,QACoB;AACpB,QAAO;EACL,GAAG;EACH,MAAM,aAAa;EACpB;;AAGH,SAAgB,0BACd,QAC2B;AAC3B,QAAO;EACL,GAAG;EACH,MAAM,aAAa;EACpB;;AAGH,SAAgB,oBAAoB,UAA8B;AAChE,KAAI,CAAC,SAAS,KACZ,KAAI,mBAAmB,YAAY,YAAY,SAC7C,QAAO,aAAa;KAEpB,QAAO,aAAa;AAIxB,QAAO,SAAS"}
|
|
1
|
+
{"version":3,"file":"copilot-runtime.mjs","names":["telemetry","CopilotRuntimeVNext"],"sources":["../../../../src/v1-deprecated/lib/runtime/copilot-runtime.ts"],"sourcesContent":["/*\n * V1 SDK DEPRECATED. USE V2 INSTEAD\n *\n * This file defines public v1 SDK exports. Use the exact v2 mappings below.\n * AI CODING AGENTS: Never copy, suggest, or generate these v1 APIs. Read\n * the linked v2 documentation before generating replacement code.\n *\n * @copilotkit/runtime — copilotKitEndpoint:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * @copilotkit/runtime — CopilotRuntime:\n * V2 import and usage:\n * import { CopilotRuntime } from \"@copilotkit/runtime/v2\";\n *\n * const runtime = new CopilotRuntime({ agents: {} });\n * V2 replacement source: packages/runtime/src/v2/runtime/core/runtime.ts\n * V2 docs: https://docs.copilotkit.ai/runtime-server-adapter\n * Migration note: V2 uses AG-UI runtime handlers instead of the v1 GraphQL adapter setup.\n *\n * @copilotkit/runtime — CopilotRuntimeConstructorParams_BASE:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * @copilotkit/runtime — langGraphPlatformEndpoint:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (LangGraph agents): https://docs.copilotkit.ai/agent-spec/langgraph\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * @copilotkit/runtime — resolveEndpointType:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * Migration guide: https://docs.copilotkit.ai/migrate/v2\n *\n * END V1 SDK DEPRECATED. USE V2 INSTEAD NOTICE\n */\n\n/**\n * <Callout type=\"info\">\n * This is the reference for the `CopilotRuntime` class. For more information and example code snippets, please see [Concept: Copilot Runtime](/backend/copilot-runtime).\n * </Callout>\n *\n * ## Usage\n *\n * ```tsx\n * import { CopilotRuntime } from \"@copilotkit/runtime\";\n *\n * const copilotKit = new CopilotRuntime();\n * ```\n */\n\nimport {\n CopilotKitMisuseError,\n readBody,\n getZodParameters,\n} from \"@copilotkit/shared\";\nimport {\n resolveMCPEntry,\n touchMCPEntry,\n describeEndpoint,\n} from \"./mcp-client-cache\";\nimport type {\n Action,\n CopilotErrorHandler,\n MaybePromise,\n NonEmptyRecord,\n Parameter,\n PartialBy,\n DebugConfig,\n TelemetryCapture,\n} from \"@copilotkit/shared\";\nimport type { RunAgentInput } from \"@ag-ui/core\";\nimport { aguiToGQL } from \"../../graphql/message-conversion/agui-to-gql\";\nimport type {\n CopilotServiceAdapter,\n RemoteChainParameters,\n} from \"../../service-adapters\";\nimport { CopilotRuntime as CopilotRuntimeVNext } from \"../../../v2/runtime/core/runtime\";\nimport { InMemoryAgentRunner } from \"../../../v2/runtime/runner\";\nimport {\n createRuntimeErrorReporter,\n runtimeErrorReporterOption,\n} from \"../../../v2/runtime/core/runtime-error-reporter\";\nimport type { RuntimeErrorReporterOptions } from \"../../../v2/runtime/core/runtime-error-reporter\";\nimport type {\n CopilotIntelligenceRuntimeOptions,\n CopilotRuntimeOptions,\n CopilotRuntimeOptions as CopilotRuntimeOptionsVNext,\n AgentsConfig,\n AgentsFactory,\n AgentFactoryContext,\n} from \"../../../v2/runtime/core/runtime\";\nimport type { AgentRunner } from \"../../../v2/runtime/runner\";\n\nexport type { AgentsConfig, AgentsFactory, AgentFactoryContext };\nimport telemetry from \"../telemetry-client\";\nimport { logRuntimeTelemetryDisclosure } from \"../telemetry-disclosure\";\n\nimport type { MessageInput } from \"../../graphql/inputs/message.input\";\nimport type { Message } from \"../../graphql/types/converted\";\n\nimport { EndpointType } from \"./types\";\nimport type {\n EndpointDefinition,\n CopilotKitEndpoint,\n LangGraphPlatformEndpoint,\n} from \"./types\";\n\nimport type {\n CopilotObservabilityConfig,\n LLMRequestData,\n LLMResponseData,\n} from \"../observability\";\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport {\n firstNonBlankLicenseToken,\n firstNonBlankTelemetryId,\n} from \"../../../v2/runtime/telemetry/telemetry-identity\";\n\n// +++ MCP Imports +++\nimport { extractParametersFromSchema } from \"./mcp-tools-utils\";\nimport type { MCPClient, MCPEndpointConfig, MCPTool } from \"./mcp-tools-utils\";\nimport { BuiltInAgent } from \"../../../agent\";\nimport type { BuiltInAgentClassicConfig } from \"../../../agent\";\nimport { resolveMCPToolNames } from \"../../../agent/mcp-tool-names\";\n// Define the function type alias here or import if defined elsewhere\ntype CreateMCPClientFunction = (\n config: MCPEndpointConfig,\n) => Promise<MCPClient>;\n\ntype ActionsConfiguration<T extends Parameter[] | [] = []> =\n | Action<T>[]\n | ((ctx: { properties: any; url?: string }) => Action<T>[]);\n\ninterface OnBeforeRequestOptions {\n threadId?: string;\n runId?: string;\n inputMessages: Message[];\n properties: any;\n url?: string;\n}\n\ntype OnBeforeRequestHandler = (\n options: OnBeforeRequestOptions,\n) => void | Promise<void>;\n\ninterface OnAfterRequestOptions {\n threadId: string;\n runId?: string;\n inputMessages: Message[];\n outputMessages: Message[];\n properties: any;\n url?: string;\n}\n\ntype OnAfterRequestHandler = (\n options: OnAfterRequestOptions,\n) => void | Promise<void>;\n\ninterface OnStopGenerationOptions {\n threadId: string;\n runId?: string;\n url?: string;\n agentName?: string;\n lastMessage: MessageInput;\n}\ntype OnStopGenerationHandler = (\n options: OnStopGenerationOptions,\n) => void | Promise<void>;\n\ninterface Middleware {\n /**\n * A function that is called before the request is processed.\n */\n /**\n * @deprecated This middleware hook is deprecated and will be removed in a future version.\n * Use updated middleware integration methods in CopilotRuntimeVNext instead.\n */\n onBeforeRequest?: OnBeforeRequestHandler;\n\n /**\n * A function that is called after the request is processed.\n */\n /**\n * @deprecated This middleware hook is deprecated and will be removed in a future version.\n * Use updated middleware integration methods in CopilotRuntimeVNext instead.\n */\n onAfterRequest?: OnAfterRequestHandler;\n}\n\nexport interface CopilotRuntimeConstructorParams_BASE<\n T extends Parameter[] | [] = [],\n> {\n /** Standalone telemetry identity. Falls back to CPK_TELEMETRY_ID before legacy license identity. */\n telemetryId?: string;\n /**\n * Middleware to be used by the runtime.\n *\n * ```ts\n * onBeforeRequest: (options: {\n * threadId?: string;\n * runId?: string;\n * inputMessages: Message[];\n * properties: any;\n * }) => void | Promise<void>;\n * ```\n *\n * ```ts\n * onAfterRequest: (options: {\n * threadId?: string;\n * runId?: string;\n * inputMessages: Message[];\n * outputMessages: Message[];\n * properties: any;\n * }) => void | Promise<void>;\n * ```\n */\n /**\n * @deprecated This middleware hook is deprecated and will be removed in a future version.\n * Use updated middleware integration methods in CopilotRuntimeVNext instead.\n */\n middleware?: Middleware;\n\n /*\n * A list of server side actions that can be executed. Will be ignored when remoteActions are set\n */\n actions?: ActionsConfiguration<T>;\n\n /*\n * Deprecated: Use `remoteEndpoints`.\n */\n remoteActions?: CopilotKitEndpoint[];\n\n /*\n * A list of remote actions that can be executed.\n */\n remoteEndpoints?: EndpointDefinition[];\n\n /*\n * An array of LangServer URLs.\n */\n langserve?: RemoteChainParameters[];\n\n /**\n * Optional agent runner to use for SSE runtime.\n */\n runner?: AgentRunner;\n\n /*\n * A map of agent names to AGUI agents.\n * Example agent config:\n * ```ts\n * import { AbstractAgent } from \"@ag-ui/client\";\n * // ...\n * agents: {\n * \"support\": new CustomerSupportAgent(),\n * \"technical\": new TechnicalAgent()\n * }\n * ```\n */\n agents?: Record<string, AbstractAgent>;\n\n /*\n * Delegates agent state processing to the service adapter.\n *\n * When enabled, individual agent state requests will not be processed by the agent itself.\n * Instead, all processing will be handled by the service adapter.\n */\n delegateAgentProcessingToServiceAdapter?: boolean;\n\n /**\n * Configuration for LLM request/response logging.\n *\n * Example logging config:\n * ```ts\n * logging: {\n * enabled: true, // Enable or disable logging\n * progressive: true, // Set to false for buffered logging\n * logger: {\n * logRequest: (data) => langfuse.trace({ name: \"LLM Request\", input: data }),\n * logResponse: (data) => langfuse.trace({ name: \"LLM Response\", output: data }),\n * logError: (errorData) => langfuse.trace({ name: \"LLM Error\", metadata: errorData }),\n * },\n * }\n * ```\n */\n observability_c?: CopilotObservabilityConfig;\n\n /**\n * Configuration for connecting to Model Context Protocol (MCP) servers.\n * Allows fetching and using tools defined on external MCP-compliant servers.\n * Requires providing the `createMCPClient` function during instantiation.\n *\n * A request can also name its own servers, as `mcpServers` (or the older\n * `mcpEndpoints`) inside `forwardedProps` — that is what the frontend's\n * `setMcpServers` sends. Those are merged with this list and connected from\n * the server.\n *\n * That merge previously never ran: whatever the browser sent was accepted\n * and discarded. It now takes effect, so a deployment that has been sending\n * `setMcpServers` will start connecting to those endpoints without changing\n * anything on its side.\n *\n * The destination is therefore caller-controlled, not only config-controlled.\n * If your deployment does not mean to let the browser choose an MCP server,\n * check `config.endpoint` inside `createMCPClient` and reject anything\n * outside your allowlist. Without that check a request can aim the server at\n * a loopback, link-local, or otherwise internal address (SSRF).\n * @experimental\n */\n mcpServers?: MCPEndpointConfig[];\n\n /**\n * A function that creates an MCP client instance for a given endpoint configuration.\n * This function is responsible for using the appropriate MCP client library\n * (e.g., `@copilotkit/runtime`, `ai`) to establish a connection.\n * Required if `mcpServers` is provided.\n *\n * ```typescript\n * import { experimental_createMCPClient } from \"ai\"; // Import from vercel ai library\n * // ...\n * const runtime = new CopilotRuntime({\n * mcpServers: [{ endpoint: \"...\" }],\n * async createMCPClient(config) {\n * return await experimental_createMCPClient({\n * transport: {\n * type: \"sse\",\n * url: config.endpoint,\n * headers: config.apiKey\n * ? { Authorization: `Bearer ${config.apiKey}` }\n * : undefined,\n * },\n * });\n * }\n * });\n * ```\n *\n * Define this once, at module scope, if you build a new `CopilotRuntime`\n * per request. Connections are cached against the identity of this function\n * plus the endpoint config, and an inline function is a new object on every\n * request — so a per-request runtime with an inline factory opens a new\n * connection each time and never reuses one. A module-scope factory, which\n * is what the documented setup uses, shares connections across requests and\n * keeps the cache bounded by how many distinct credentials are in play\n * rather than by traffic.\n */\n createMCPClient?: CreateMCPClientFunction;\n\n /**\n * Optional error handler for comprehensive debugging and observability.\n *\n * @param errorEvent - Structured error event with rich debugging context\n *\n * @example\n * ```typescript\n * const runtime = new CopilotRuntime({\n * onError: (errorEvent) => {\n * debugDashboard.capture(errorEvent);\n * }\n * });\n * ```\n */\n onError?: CopilotErrorHandler;\n\n onStopGeneration?: OnStopGenerationHandler;\n\n /**\n * Enable debug logging for the runtime event pipeline.\n * Pass `true` for full output, or an object for granular control:\n *\n * ```ts\n * const runtime = new CopilotRuntime({\n * debug: true,\n * // or: debug: { events: true, lifecycle: true, verbose: false }\n * });\n * ```\n */\n debug?: DebugConfig;\n\n // /** Optional transcription service for audio processing. */\n // transcriptionService?: CopilotRuntimeOptionsVNext[\"transcriptionService\"];\n // /** Optional *before* middleware – callback function or webhook URL. */\n // beforeRequestMiddleware?: CopilotRuntimeOptionsVNext[\"beforeRequestMiddleware\"];\n // /** Optional *after* middleware – callback function or webhook URL. */\n // afterRequestMiddleware?: CopilotRuntimeOptionsVNext[\"afterRequestMiddleware\"];\n}\n\ntype BeforeRequestMiddleware =\n CopilotRuntimeOptionsVNext[\"beforeRequestMiddleware\"];\ntype AfterRequestMiddleware =\n CopilotRuntimeOptionsVNext[\"afterRequestMiddleware\"];\ntype BeforeRequestMiddlewareFn = Exclude<BeforeRequestMiddleware, string>;\ntype BeforeRequestMiddlewareFnParameters =\n Parameters<BeforeRequestMiddlewareFn>;\ntype BeforeRequestMiddlewareFnResult = ReturnType<BeforeRequestMiddlewareFn>;\ntype AfterRequestMiddlewareFn = Exclude<AfterRequestMiddleware, string>;\ntype AfterRequestMiddlewareFnParameters = Parameters<AfterRequestMiddlewareFn>;\n\ninterface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []>\n extends\n Omit<CopilotRuntimeConstructorParams_BASE<T>, \"agents\">,\n Omit<CopilotRuntimeOptionsVNext, \"agents\" | \"transcriptionService\"> {\n /**\n * TODO: un-omit `transcriptionService` above once it's supported\n *\n * This satisfies...\n * – the optional constraint in `CopilotRuntimeConstructorParams_BASE`\n * – the `MaybePromise<NonEmptyRecord<T>>` constraint in `CopilotRuntimeOptionsVNext`\n * – the `Record<string, AbstractAgent>` constraint in `both\n */\n agents?: AgentsConfig;\n\n intelligence?: CopilotIntelligenceRuntimeOptions[\"intelligence\"];\n identifyUser?: CopilotIntelligenceRuntimeOptions[\"identifyUser\"];\n memory?: CopilotIntelligenceRuntimeOptions[\"memory\"];\n channels?: CopilotIntelligenceRuntimeOptions[\"channels\"];\n ɵlearning?: CopilotIntelligenceRuntimeOptions[\"ɵlearning\"];\n generateThreadNames?: CopilotIntelligenceRuntimeOptions[\"generateThreadNames\"];\n maxReconnectMs?: CopilotIntelligenceRuntimeOptions[\"maxReconnectMs\"];\n maxRejoinMs?: CopilotIntelligenceRuntimeOptions[\"maxRejoinMs\"];\n lockTtlSeconds?: CopilotIntelligenceRuntimeOptions[\"lockTtlSeconds\"];\n lockKeyPrefix?: CopilotIntelligenceRuntimeOptions[\"lockKeyPrefix\"];\n lockHeartbeatIntervalSeconds?: CopilotIntelligenceRuntimeOptions[\"lockHeartbeatIntervalSeconds\"];\n}\n\n/**\n * Central runtime object passed to all request handlers.\n * @deprecated The v1 SDK is deprecated. Use v2 instead. Use `CopilotRuntime` from `@copilotkit/runtime/v2` instead.\n *\n * ```tsx\n * import { CopilotRuntime } from \"@copilotkit/runtime/v2\";\n *\n * const runtime = new CopilotRuntime({ agents: {} });\n * ```\n * See https://docs.copilotkit.ai/runtime-server-adapter\n */\nexport class CopilotRuntime<const T extends Parameter[] | [] = []> {\n params?: CopilotRuntimeConstructorParams<T>;\n private observability?: CopilotObservabilityConfig;\n /**\n * The request-independent half of agent resolution: validation, and the\n * default agent built from the service adapter. Resolved once, because\n * re-running the misuse checks on every request would turn a configuration\n * error into a per-request throw.\n */\n private baseAgents?: Promise<Record<string, AbstractAgent>>;\n /**\n * The `agents` value as configured, captured before the per-request factory\n * replaces it, so that repeated `handleServiceAdapter` calls do not wrap the\n * factory in itself.\n */\n private configuredAgents?: CopilotRuntimeOptions[\"agents\"];\n private runtimeArgs: CopilotRuntimeOptions & RuntimeErrorReporterOptions;\n private _instance: CopilotRuntimeVNext;\n /** Runtime-bound telemetry identity and sampling authority. */\n public readonly telemetry: TelemetryCapture;\n\n constructor(params?: CopilotRuntimeConstructorParams<T>) {\n logRuntimeTelemetryDisclosure();\n\n const agents = params?.agents ?? {};\n const endpointAgents = this.assignEndpointsToAgents(\n params?.remoteEndpoints ?? [],\n );\n\n // Merge endpoint agents with user-provided agents.\n // When agents is a factory function, wrap it so endpoint agents are merged\n // at resolution time (spreading a function produces {} — silent data loss).\n let mergedAgents: AgentsConfig;\n if (typeof agents === \"function\") {\n mergedAgents = async (ctx) => {\n const resolved = await agents(ctx);\n return { ...endpointAgents, ...resolved };\n };\n } else {\n mergedAgents = Promise.resolve(agents).then((resolved) => ({\n ...endpointAgents,\n ...resolved,\n }));\n }\n\n // Resolve identity once and bind it to this compatibility Runtime. The\n // capture scope shares process-level sinks and settings without exposing\n // mutable identity to other live runtimes.\n const resolvedLicenseToken = firstNonBlankLicenseToken(\n params?.licenseToken,\n process.env.COPILOTKIT_LICENSE_TOKEN,\n );\n const resolvedTelemetryId = firstNonBlankTelemetryId(\n params?.telemetryId,\n process.env.CPK_TELEMETRY_ID,\n );\n const resolvedTelemetryIdentity =\n resolvedTelemetryId !== undefined\n ? { telemetryId: resolvedTelemetryId }\n : resolvedLicenseToken !== undefined\n ? { licenseToken: resolvedLicenseToken }\n : {};\n this.telemetry = telemetry.createScope(resolvedTelemetryIdentity);\n\n // No TelemetryAgentRunner wrap. The V2 SSE path already emits\n // `agent_execution_stream_*` for this runtime, and since it now emits\n // through this entrypoint's scope, wrapping would put two copies of\n // every stream event on the wire. The class stays exported for callers\n // who construct it themselves. The rawEvent enrichment it used to add\n // moved to `v2/runtime/handlers/shared/sse-response.ts`, so nothing is\n // lost and v2 callers gain it too.\n const runner = params?.runner ?? new InMemoryAgentRunner();\n\n const sharedRuntimeArgs = {\n agents: mergedAgents,\n telemetryId: resolvedTelemetryId,\n licenseToken: resolvedLicenseToken,\n // Emit through this entrypoint's own scope rather than letting the\n // delegated V2 runtime build its own. That scope writes to Segment\n // and stamps the v1 surface, so handing it down is what lets the v1\n // middleware below stop emitting the same events a second time.\n ɵtelemetry: this.telemetry,\n telemetryProperties: params?.telemetryProperties,\n debug: params?.debug,\n // TODO: add support for transcriptionService from CopilotRuntimeOptionsVNext once it is ready\n // transcriptionService: params?.transcriptionService,\n\n beforeRequestMiddleware:\n this.createOnBeforeRequestHandler(params).bind(this),\n ...(params?.afterRequestMiddleware || params?.middleware?.onAfterRequest\n ? {\n afterRequestMiddleware:\n this.createOnAfterRequestHandler(params).bind(this),\n }\n : {}),\n a2ui: params?.a2ui,\n mcpApps: params?.mcpApps,\n openGenerativeUI: params?.openGenerativeUI,\n [runtimeErrorReporterOption]: createRuntimeErrorReporter(params?.onError),\n forwardHeaders: params?.forwardHeaders,\n exposeMemoryRoutes: params?.exposeMemoryRoutes,\n };\n if (params?.intelligence !== undefined) {\n // The compatibility constructor keeps Intelligence identity optional at\n // compile time, while the v2 runtime checks that callers supply web\n // identity, Channels, or both. Preserve that runtime validation here.\n this.runtimeArgs = {\n ...sharedRuntimeArgs,\n intelligence: params.intelligence,\n identifyUser: params.identifyUser,\n memory: params.memory,\n channels: params.channels,\n ɵlearning: params.ɵlearning,\n generateThreadNames: params.generateThreadNames,\n maxReconnectMs: params.maxReconnectMs,\n maxRejoinMs: params.maxRejoinMs,\n lockTtlSeconds: params.lockTtlSeconds,\n lockKeyPrefix: params.lockKeyPrefix,\n lockHeartbeatIntervalSeconds: params.lockHeartbeatIntervalSeconds,\n } as CopilotRuntimeOptions;\n } else {\n this.runtimeArgs = {\n ...sharedRuntimeArgs,\n runner,\n };\n }\n this.params = params;\n this.observability = params?.observability_c;\n }\n\n get instance() {\n if (!this._instance) {\n this._instance = new CopilotRuntimeVNext(this.runtimeArgs);\n }\n\n return this._instance;\n }\n\n private assignEndpointsToAgents(\n endpoints: CopilotRuntimeConstructorParams<T>[\"remoteEndpoints\"],\n ): Record<string, AbstractAgent> {\n let result: Record<string, AbstractAgent> = {};\n\n if (\n endpoints.some(\n (endpoint) =>\n resolveEndpointType(endpoint) == EndpointType.LangGraphPlatform,\n )\n ) {\n throw new CopilotKitMisuseError({\n message:\n \"LangGraphPlatformEndpoint in remoteEndpoints is deprecated. \" +\n 'Please use the \"agents\" option instead with LangGraphAgent from \"@copilotkit/runtime/langgraph\". ' +\n 'Example: agents: { myAgent: new LangGraphAgent({ deploymentUrl: \"...\", graphId: \"...\" }) }',\n });\n }\n\n return result;\n }\n\n handleServiceAdapter(serviceAdapter: CopilotServiceAdapter) {\n // Capture the configured value before the factory below replaces it, so a\n // second call does not wrap the factory in itself.\n this.configuredAgents ??= this.runtimeArgs.agents ?? {};\n const configuredAgents = this.configuredAgents;\n\n // Resolve the request-independent half once. Calling this twice (the\n // endpoint factory runs on every request under the documented v1 route)\n // must not re-validate or rebuild the default agent.\n //\n // A caller who supplied their own agents factory has no request-independent\n // half: their record is whatever they return for this request, so the same\n // checks run per request further down.\n if (typeof configuredAgents !== \"function\") {\n this.baseAgents ??= Promise.resolve(configuredAgents).then((agents) =>\n this.ensureDefaultAgent(\n agents as Record<string, AbstractAgent>,\n serviceAdapter,\n ),\n );\n // A misconfigured adapter rejects that promise, and nothing awaits it\n // until the first request arrives. Attach an inert handler so a runtime\n // that is never called does not surface an unhandled rejection; the\n // factory below still sees the rejection when it awaits.\n this.baseAgents.catch(() => {});\n }\n\n // Install the per-request factory the v2 runtime has supported since\n // #2941. Resolving once was what kept a dynamic `actions` function from\n // ever seeing request properties, and kept every request sharing one MCP\n // client regardless of whose credentials built it (#7116, #2407).\n const resolvePerRequest = async ({ request }: { request: Request }) => {\n // A caller-supplied agents factory is called here, with this request.\n // Treating it as a record instead (a function has no enumerable keys)\n // meant the service adapter's default replaced it and the caller's\n // function was never invoked at all.\n const baseAgents =\n typeof configuredAgents === \"function\"\n ? this.ensureDefaultAgent(\n { ...(await configuredAgents({ request })) },\n serviceAdapter,\n )\n : await this.baseAgents!;\n const properties = await this.readRequestProperties(request);\n const actions = this.params?.actions;\n\n // `actions` and `mcpServers` are attached independently: a runtime may\n // configure MCP servers without any local actions.\n const mcpSources = await this.getToolsFromMCP({ properties });\n const actionTools = actions\n ? this.getToolsFromActions(actions, { properties, url: request.url })\n : [];\n // An MCP tool that shares a name with an action, or with another\n // server's tool, is prefixed rather than dropped or duplicated.\n const mcpNames = resolveMCPToolNames(\n new Set(actionTools.map((tool) => tool.name)),\n mcpSources.map(({ label, tools }) => ({\n label,\n names: tools.map((tool) => tool.name),\n })),\n \"\",\n );\n const mcpTools = mcpSources.flatMap(({ tools }, i) =>\n tools.map((tool, j) => ({ ...tool, name: mcpNames[i]![j]! })),\n );\n const tools = [...actionTools, ...mcpTools];\n\n // Nothing to attach means nothing to isolate: hand the record back\n // untouched, exactly as a runtime with no actions and no MCP behaved\n // before this became a factory.\n if (!tools.length) {\n return baseAgents;\n }\n\n // Clone before attaching. `assignToolsToAgents` writes `config` onto the\n // agent, so mutating the shared instances would let one request's tools\n // reach another request that is already in flight.\n const perRequestAgents: Record<string, AbstractAgent> = {};\n for (const [agentId, agent] of Object.entries(baseAgents)) {\n const clone = agent.clone() as AbstractAgent;\n // `BuiltInAgent.clone()` rebuilds from `this.config`, so its own tools\n // survive. An agent whose `clone()` does not know about `config` --\n // `HttpAgent`, and anything else a v1 user registered -- would arrive\n // here empty, and the tools it declares itself would be shadowed by a\n // v1 action of the same name. Carry the config across when the clone\n // did not.\n if (\n Reflect.get(clone, \"config\") === undefined &&\n Reflect.get(agent, \"config\") !== undefined\n ) {\n Reflect.set(clone, \"config\", Reflect.get(agent, \"config\"));\n }\n perRequestAgents[agentId] = clone;\n }\n\n return this.assignToolsToAgents(perRequestAgents, tools);\n };\n\n this.runtimeArgs.agents =\n resolvePerRequest as unknown as CopilotRuntimeOptions[\"agents\"];\n }\n\n /**\n * Fill in the default agent the service adapter implies, and reject a\n * configuration that names no model at all.\n */\n private ensureDefaultAgent(\n agentsList: Record<string, AbstractAgent>,\n serviceAdapter: CopilotServiceAdapter,\n ): Record<string, AbstractAgent> {\n const isAgentsListEmpty = !Object.keys(agentsList).length;\n const hasServiceAdapter = Boolean(serviceAdapter);\n const illegalServiceAdapterNames = [\"EmptyAdapter\"];\n const serviceAdapterCanBeUsedForAgent =\n !illegalServiceAdapterNames.includes(serviceAdapter.name);\n\n if (\n isAgentsListEmpty &&\n (!hasServiceAdapter || !serviceAdapterCanBeUsedForAgent)\n ) {\n throw new CopilotKitMisuseError({\n message:\n \"No default agent provided. Please provide a default agent in the runtime config.\",\n });\n }\n\n if (isAgentsListEmpty) {\n const languageModel = serviceAdapter.getLanguageModel?.();\n if (languageModel) {\n // Adapter exposes a pre-configured LanguageModel (e.g. OpenAI/Anthropic adapters)\n agentsList.default = new BuiltInAgent({ model: languageModel });\n } else if (serviceAdapter.provider && serviceAdapter.model) {\n // Adapter exposes provider/model strings\n agentsList.default = new BuiltInAgent({\n model: `${serviceAdapter.provider}/${serviceAdapter.model}`,\n });\n } else {\n throw new CopilotKitMisuseError({\n message:\n `Service adapter \"${serviceAdapter.name ?? \"unknown\"}\" does not provide model information. ` +\n `When using adapters like LangChainAdapter without an explicit agents list, ` +\n `please provide a default agent in the runtime config. Example:\\n` +\n ` new CopilotRuntime({\\n` +\n ` agents: { default: new BuiltInAgent({ model: \"openai/gpt-4o\" }) }\\n` +\n ` })`,\n });\n }\n }\n\n return agentsList;\n }\n\n /**\n * The `forwardedProps` the browser sent with this request, which is what a\n * v1 `actions` function and `mcpServers` overrides are documented to read.\n *\n * `readBody` clones, so the handler still gets an unconsumed body, and it\n * returns `undefined` for GET, which is how the `/info` route reaches here.\n */\n private async readRequestProperties(\n request: Request,\n ): Promise<Record<string, unknown>> {\n try {\n const body = (await readBody(request)) as RunAgentInput | undefined;\n const properties = body?.forwardedProps;\n return properties && typeof properties === \"object\"\n ? (properties as Record<string, unknown>)\n : {};\n } catch {\n // A malformed body is the request handler's problem to report, not a\n // reason to fail agent resolution.\n return {};\n }\n }\n\n // Receive this.params.action and turn it into the AbstractAgent tools\n private getToolsFromActions(\n actions: ActionsConfiguration<any>,\n ctx: { properties: Record<string, unknown>; url?: string },\n ): BuiltInAgentClassicConfig[\"tools\"] {\n // Resolve actions to an array (handle function case).\n //\n // The function form is documented to receive the request's properties and\n // url. It was called once at resolution time with `{ properties: {}, url:\n // undefined }`, so a runtime that keyed its action list on the tenant, the\n // user, or anything else request-shaped got the same empty context every\n // time (#7116).\n const actionsArray =\n typeof actions === \"function\"\n ? actions({ properties: ctx.properties, url: ctx.url })\n : actions;\n\n // Convert each Action to a ToolDefinition\n return actionsArray.map((action) => {\n // Convert JSON schema to Zod schema\n const zodSchema = getZodParameters(action.parameters || []);\n\n return {\n name: action.name,\n description: action.description || \"\",\n parameters: zodSchema,\n // `handler` is an in-process function and was never part of the remote\n // executor deleted in v1.50.0 — only the wiring to it was lost. Call it.\n //\n // The result must never be `undefined`: `JSON.stringify(undefined)` is\n // not a string, which strips the required `content` off\n // TOOL_CALL_RESULT and surfaces as a Zod error in the browser\n // (#2915, #3198). Both branches below return a string instead.\n execute: async (args: unknown) => {\n if (typeof action.handler !== \"function\") {\n return (\n `The tool \"${action.name}\" was advertised without a handler, so it ` +\n `has no implementation to run. Tell the user this tool is unavailable.`\n );\n }\n const result = await action.handler(args as any);\n return result === undefined\n ? `The tool \"${action.name}\" ran and returned no value.`\n : result;\n },\n };\n });\n }\n\n private assignToolsToAgents(\n agents: Record<string, AbstractAgent>,\n tools: BuiltInAgentClassicConfig[\"tools\"],\n ): Record<string, AbstractAgent> {\n if (!tools?.length) {\n return agents;\n }\n\n const enrichedAgents: Record<string, AbstractAgent> = { ...agents };\n\n for (const [agentId, agent] of Object.entries(enrichedAgents)) {\n const existingConfig = (Reflect.get(agent, \"config\") ?? {}) as Record<\n string,\n unknown\n >;\n\n // Skip factory-mode agents — they don't have a tools property\n if (\"factory\" in existingConfig) {\n continue;\n }\n\n const classicConfig =\n existingConfig as unknown as BuiltInAgentClassicConfig;\n const existingTools = classicConfig.tools ?? [];\n\n // The endpoint factory runs `handleServiceAdapter` every time it is\n // called, and the documented v1 route builds the endpoint inside the\n // request handler — so a module-scope runtime lands here once per\n // request. Appending unconditionally advertised N copies of every tool\n // to the model. Skip names the agent already carries, which also leaves\n // a tool the agent defines itself in place.\n const existingNames = new Set(existingTools.map((tool) => tool.name));\n const newTools = tools.filter((tool) => !existingNames.has(tool.name));\n if (newTools.length === 0) {\n continue;\n }\n\n const updatedConfig: BuiltInAgentClassicConfig = {\n ...classicConfig,\n tools: [...existingTools, ...newTools],\n };\n\n Reflect.set(agent, \"config\", updatedConfig);\n enrichedAgents[agentId] = agent;\n }\n\n return enrichedAgents;\n }\n\n private createOnBeforeRequestHandler(\n params?: CopilotRuntimeConstructorParams<T> &\n PartialBy<CopilotRuntimeOptions, \"agents\">,\n ) {\n return async (hookParams: BeforeRequestMiddlewareFnParameters[0]) => {\n const { request } = hookParams;\n\n // No `copilot_request_created` capture here. The V2 handlers this\n // runtime delegates to already emit it, through this runtime's own\n // scope, and they know the route — so `requestType` is \"run\" or\n // \"connect\" rather than the \"unknown\" this site reported for every\n // request that did not set `forwardedProps.metadata.requestType`.\n const body = (await readBody(request)) as RunAgentInput;\n\n // We do not process middleware for the internal GET requests\n if (request.method === \"GET\" || !body) return;\n\n // TODO: get public api key and run with expected data\n // if (this.observability?.enabled && this.params.publicApiKey) {\n // this.logObservabilityBeforeRequest()\n // }\n\n // TODO: replace hooksParams top argument type with BeforeRequestMiddlewareParameters when exported\n const middlewareResult =\n await params?.beforeRequestMiddleware?.(hookParams);\n\n if (params?.middleware?.onBeforeRequest) {\n const { request, runtime, path } = hookParams;\n const gqlMessages = (aguiToGQL(body.messages) as Message[]).reduce(\n (acc, msg) => {\n if (\"role\" in msg && msg.role === \"user\") {\n acc.inputMessages.push(msg);\n } else {\n acc.outputMessages.push(msg);\n }\n return acc;\n },\n { inputMessages: [] as Message[], outputMessages: [] as Message[] },\n );\n const { inputMessages, outputMessages } = gqlMessages;\n params.middleware.onBeforeRequest({\n threadId: body.threadId,\n runId: body.runId,\n inputMessages,\n properties: body.forwardedProps,\n url: request.url,\n } satisfies OnBeforeRequestOptions);\n }\n\n return middlewareResult;\n };\n }\n\n private createOnAfterRequestHandler(\n params?: CopilotRuntimeConstructorParams<T> &\n PartialBy<CopilotRuntimeOptions, \"agents\">,\n ) {\n return async (hookParams: AfterRequestMiddlewareFnParameters[0]) => {\n // TODO: get public api key and run with expected data\n // if (this.observability?.enabled && publicApiKey) {\n // this.logObservabilityAfterRequest()\n // }\n\n // TODO: replace hooksParams top argument type with AfterRequestMiddlewareParameters when exported\n params?.afterRequestMiddleware?.(hookParams);\n\n if (params?.middleware?.onAfterRequest) {\n const messages = hookParams.messages ?? [];\n params.middleware.onAfterRequest({\n threadId: hookParams.threadId ?? \"\",\n runId: hookParams.runId,\n inputMessages: messages.filter(\n (m): m is typeof m & { role: string } =>\n \"role\" in m && m.role === \"user\",\n ) as unknown as Message[],\n outputMessages: messages.filter(\n (m): m is typeof m & { role: string } =>\n \"role\" in m && m.role !== \"user\",\n ) as unknown as Message[],\n // TODO: forward actual properties once the after-request hook has access to the request body\n properties: {},\n url: hookParams.path,\n } satisfies OnAfterRequestOptions);\n }\n };\n }\n\n // Observability Methods\n\n /**\n * Log LLM request if observability is enabled\n */\n private async logObservabilityBeforeRequest(\n requestData: LLMRequestData,\n ): Promise<void> {\n try {\n await this.observability.hooks.handleRequest(requestData);\n } catch (error) {\n console.error(\"Error logging LLM request:\", error);\n }\n }\n\n /**\n * Log final LLM response after request completes\n */\n private logObservabilityAfterRequest(\n outputMessagesPromise: Promise<Message[]>,\n baseData: {\n threadId: string;\n runId?: string;\n model?: string;\n provider?: string;\n agentName?: string;\n nodeName?: string;\n },\n streamedChunks: any[],\n requestStartTime: number,\n publicApiKey?: string,\n ): void {\n try {\n outputMessagesPromise\n .then((outputMessages) => {\n const responseData: LLMResponseData = {\n threadId: baseData.threadId,\n runId: baseData.runId,\n model: baseData.model,\n // Use collected chunks for progressive mode or outputMessages for regular mode\n output: this.observability.progressive\n ? streamedChunks\n : outputMessages,\n latency: Date.now() - requestStartTime,\n timestamp: Date.now(),\n provider: baseData.provider,\n isFinalResponse: true,\n agentName: baseData.agentName,\n nodeName: baseData.nodeName,\n };\n\n try {\n this.observability.hooks.handleResponse(responseData);\n } catch (logError) {\n console.error(\"Error logging LLM response:\", logError);\n }\n })\n .catch((error) => {\n console.error(\"Failed to get output messages for logging:\", error);\n });\n } catch (error) {\n console.error(\"Error setting up logging for LLM response:\", error);\n }\n }\n\n // Resolve MCP tools to BuiltInAgent tool definitions\n // Optionally accepts request-scoped properties to merge request-provided mcpServers\n private async getToolsFromMCP(options?: {\n properties?: Record<string, unknown>;\n }): Promise<\n { label: string; tools: NonNullable<BuiltInAgentClassicConfig[\"tools\"]> }[]\n > {\n const runtimeMcpServers = (this.params?.mcpServers ??\n []) as MCPEndpointConfig[];\n const createMCPClient = this.params?.createMCPClient as\n | CreateMCPClientFunction\n | undefined;\n\n // If no runtime config and no request overrides, nothing to do\n const requestMcpServers = ((\n options?.properties as { mcpServers?: MCPEndpointConfig[] } | undefined\n )?.mcpServers ??\n (\n options?.properties as\n | { mcpEndpoints?: MCPEndpointConfig[] }\n | undefined\n )?.mcpEndpoints ??\n []) as MCPEndpointConfig[];\n\n const hasAnyServers =\n (runtimeMcpServers?.length ?? 0) > 0 ||\n (requestMcpServers?.length ?? 0) > 0;\n if (!hasAnyServers) {\n return [];\n }\n\n if (!createMCPClient) {\n // Mirror legacy behavior: when servers are provided without a factory, treat as misconfiguration\n throw new CopilotKitMisuseError({\n message:\n \"MCP Integration Error: `mcpServers` were provided, but the `createMCPClient` function was not passed to the CopilotRuntime constructor. Please provide an implementation for `createMCPClient`.\",\n });\n }\n\n // Merge and dedupe endpoints by URL; request-level overrides take precedence.\n //\n // `requestMcpServers` is caller-supplied: it arrives in `forwardedProps`\n // from the browser. Validating it here is not this shim's call — the\n // endpoint shape, the transport, and the auth all belong to the\n // application's `createMCPClient`, and a hardcoded allowlist would break\n // the multi-tenant case this per-request path exists to serve. The\n // constraint is documented on `mcpServers` instead: a deployment that does\n // not intend browser-chosen servers has to reject them in its factory.\n const effectiveEndpoints = (() => {\n const byUrl = new Map<string, MCPEndpointConfig>();\n for (const ep of runtimeMcpServers) {\n if (ep?.endpoint) byUrl.set(ep.endpoint, ep);\n }\n for (const ep of requestMcpServers) {\n if (ep?.endpoint) byUrl.set(ep.endpoint, ep);\n }\n return Array.from(byUrl.values());\n })();\n\n const sources: {\n label: string;\n tools: NonNullable<BuiltInAgentClassicConfig[\"tools\"]>;\n }[] = [];\n\n for (const [index, config] of effectiveEndpoints.entries()) {\n // Everything that leaves this process with the endpoint in it uses the\n // redacted form: the raw URL's query can carry the credential, which is\n // exactly what the #2407 workaround puts there.\n const endpointLabel = describeEndpoint(config.endpoint);\n\n try {\n // Keyed by the client factory plus the whole config, so two callers\n // with different credentials for one endpoint get one client each.\n // Keying on the URL alone is #2407: the first caller's client served\n // everyone, and the reporter's `?uid=<hash>` workaround existed only\n // to force distinct keys.\n const entry = await resolveMCPEntry<BuiltInAgentClassicConfig[\"tools\"]>(\n createMCPClient,\n config,\n async () => {\n const client = await createMCPClient(config);\n const toolsMap = await client.tools();\n\n const toolDefs: BuiltInAgentClassicConfig[\"tools\"] = Object.entries(\n toolsMap,\n ).map(([toolName, tool]: [string, MCPTool]) => {\n const params: Parameter[] = extractParametersFromSchema(tool);\n const zodSchema = getZodParameters(params);\n return {\n name: toolName,\n description:\n tool.description ||\n `MCP tool: ${toolName} (from ${endpointLabel})`,\n parameters: zodSchema,\n // `tool.execute` calls the server over the cached client. That\n // client outlives this request but not necessarily this tool\n // definition: eviction can close it while these defs are still\n // held by an already-resolved agent.\n execute: async (args: unknown) => {\n // Executing is the only evidence this runtime gets that a\n // connection is still in use. Without it the entry ages from\n // the moment the agent resolved, and a busy process evicts\n // and closes a client that a live run is still calling.\n touchMCPEntry(createMCPClient, config);\n return tool.execute(args);\n },\n };\n });\n\n return { client, tools: toolDefs };\n },\n );\n\n sources.push({ label: `mcp${index + 1}`, tools: entry.tools ?? [] });\n } catch (error) {\n console.error(\n `MCP: Failed to fetch tools from endpoint ${endpointLabel}. Skipping. Error:`,\n error,\n );\n // Deliberately not cached. Caching the empty result meant a server\n // that was briefly unreachable when the runtime first resolved stayed\n // toolless for the life of that runtime, even after it recovered.\n // `resolveMCPEntry` drops a rejected entry so a later request retries.\n }\n }\n\n return sources;\n }\n}\n\n// The two functions below are \"factory functions\", meant to create the action objects that adhere to the expected interfaces\nexport function copilotKitEndpoint(\n config: Omit<CopilotKitEndpoint, \"type\">,\n): CopilotKitEndpoint {\n return {\n ...config,\n type: EndpointType.CopilotKit,\n };\n}\n\nexport function langGraphPlatformEndpoint(\n config: Omit<LangGraphPlatformEndpoint, \"type\">,\n): LangGraphPlatformEndpoint {\n return {\n ...config,\n type: EndpointType.LangGraphPlatform,\n };\n}\n\nexport function resolveEndpointType(endpoint: EndpointDefinition) {\n if (!endpoint.type) {\n if (\"deploymentUrl\" in endpoint && \"agents\" in endpoint) {\n return EndpointType.LangGraphPlatform;\n } else {\n return EndpointType.CopilotKit;\n }\n }\n\n return endpoint.type;\n}\n"],"mappings":"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"}
|
package/dist/package.cjs
CHANGED
|
@@ -5,7 +5,7 @@ const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
|
5
5
|
var require_package = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => {
|
|
6
6
|
module.exports = {
|
|
7
7
|
"name": "@copilotkit/runtime",
|
|
8
|
-
"version": "1.
|
|
8
|
+
"version": "1.76.0",
|
|
9
9
|
"private": false,
|
|
10
10
|
"keywords": [
|
|
11
11
|
"ai",
|
|
@@ -83,9 +83,9 @@ var require_package = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, m
|
|
|
83
83
|
},
|
|
84
84
|
"dependencies": {
|
|
85
85
|
"@ag-ui/a2ui-middleware": "0.0.10",
|
|
86
|
-
"@ag-ui/client": "
|
|
87
|
-
"@ag-ui/core": "
|
|
88
|
-
"@ag-ui/encoder": "
|
|
86
|
+
"@ag-ui/client": "1.0.1",
|
|
87
|
+
"@ag-ui/core": "1.0.1",
|
|
88
|
+
"@ag-ui/encoder": "1.0.1",
|
|
89
89
|
"@ag-ui/langgraph": "0.0.43",
|
|
90
90
|
"@ag-ui/mcp-apps-middleware": "^0.1.1",
|
|
91
91
|
"@ag-ui/mcp-middleware": "0.0.2",
|
|
@@ -124,7 +124,7 @@ var require_package = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, m
|
|
|
124
124
|
"type-graphql": "2.0.0-rc.1",
|
|
125
125
|
"uuid": "^11.1.0",
|
|
126
126
|
"ws": "^8.18.0",
|
|
127
|
-
"zod": "^3.
|
|
127
|
+
"zod": "^3.25.18",
|
|
128
128
|
"yauzl": "2.10.0"
|
|
129
129
|
},
|
|
130
130
|
"devDependencies": {
|
|
@@ -175,8 +175,7 @@ var require_package = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, m
|
|
|
175
175
|
"@langchain/openai": { "optional": true },
|
|
176
176
|
"express": { "optional": true },
|
|
177
177
|
"groq-sdk": { "optional": true },
|
|
178
|
-
"langchain": { "optional": true }
|
|
179
|
-
"openai": { "optional": true }
|
|
178
|
+
"langchain": { "optional": true }
|
|
180
179
|
},
|
|
181
180
|
"nx": { "targets": { "build": { "dependsOn": ["generate-graphql-schema", "^build"] } } },
|
|
182
181
|
"engines": { "node": ">=20" }
|
package/dist/package.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { __commonJSMin } from "./_virtual/_rolldown/runtime.mjs";
|
|
|
5
5
|
var require_package = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
6
6
|
module.exports = {
|
|
7
7
|
"name": "@copilotkit/runtime",
|
|
8
|
-
"version": "1.
|
|
8
|
+
"version": "1.76.0",
|
|
9
9
|
"private": false,
|
|
10
10
|
"keywords": [
|
|
11
11
|
"ai",
|
|
@@ -83,9 +83,9 @@ var require_package = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
83
83
|
},
|
|
84
84
|
"dependencies": {
|
|
85
85
|
"@ag-ui/a2ui-middleware": "0.0.10",
|
|
86
|
-
"@ag-ui/client": "
|
|
87
|
-
"@ag-ui/core": "
|
|
88
|
-
"@ag-ui/encoder": "
|
|
86
|
+
"@ag-ui/client": "1.0.1",
|
|
87
|
+
"@ag-ui/core": "1.0.1",
|
|
88
|
+
"@ag-ui/encoder": "1.0.1",
|
|
89
89
|
"@ag-ui/langgraph": "0.0.43",
|
|
90
90
|
"@ag-ui/mcp-apps-middleware": "^0.1.1",
|
|
91
91
|
"@ag-ui/mcp-middleware": "0.0.2",
|
|
@@ -124,7 +124,7 @@ var require_package = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
124
124
|
"type-graphql": "2.0.0-rc.1",
|
|
125
125
|
"uuid": "^11.1.0",
|
|
126
126
|
"ws": "^8.18.0",
|
|
127
|
-
"zod": "^3.
|
|
127
|
+
"zod": "^3.25.18",
|
|
128
128
|
"yauzl": "2.10.0"
|
|
129
129
|
},
|
|
130
130
|
"devDependencies": {
|
|
@@ -175,8 +175,7 @@ var require_package = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
175
175
|
"@langchain/openai": { "optional": true },
|
|
176
176
|
"express": { "optional": true },
|
|
177
177
|
"groq-sdk": { "optional": true },
|
|
178
|
-
"langchain": { "optional": true }
|
|
179
|
-
"openai": { "optional": true }
|
|
178
|
+
"langchain": { "optional": true }
|
|
180
179
|
},
|
|
181
180
|
"nx": { "targets": { "build": { "dependsOn": ["generate-graphql-schema", "^build"] } } },
|
|
182
181
|
"engines": { "node": ">=20" }
|
|
@@ -33,6 +33,7 @@ async function handleIntelligenceConnect({ runtime, request, agentId, threadId }
|
|
|
33
33
|
return Response.json({
|
|
34
34
|
threadId: result.threadId,
|
|
35
35
|
joinToken: result.joinToken,
|
|
36
|
+
runId: result.runId,
|
|
36
37
|
realtime: buildRealtimeConnectionInfo({
|
|
37
38
|
clientUrl: runtime.intelligence.ɵgetClientWsUrl(),
|
|
38
39
|
threadId: result.threadId
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.cjs","names":["resolveIntelligenceUser","isHandlerResponse","getPlatformErrorStatus"],"sources":["../../../../../src/v2/runtime/handlers/intelligence/connect.ts"],"sourcesContent":["import type { CopilotIntelligenceRuntimeLike } from \"../../core/runtime\";\nimport { getPlatformErrorStatus } from \"../shared/intelligence-utils\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\nimport { isHandlerResponse } from \"../shared/json-response\";\n\n/**\n * Builds browser-facing realtime connection metadata owned by the runtime.\n */\nfunction buildRealtimeConnectionInfo(params: {\n clientUrl: string;\n threadId: string;\n}): { clientUrl: string; topic: string } {\n return {\n clientUrl: params.clientUrl,\n topic: `thread:${params.threadId}`,\n };\n}\n\ninterface HandleIntelligenceConnectParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n threadId: string;\n}\n\nexport async function handleIntelligenceConnect({\n runtime,\n request,\n agentId,\n threadId,\n}: HandleIntelligenceConnectParams): Promise<Response> {\n if (!runtime.intelligence) {\n return Response.json(\n {\n error: \"Intelligence not configured\",\n message: \"Intelligence mode requires a CopilotKitIntelligence\",\n },\n { status: 500 },\n );\n }\n\n try {\n const user = await resolveIntelligenceUser({ runtime, request });\n if (isHandlerResponse(user)) {\n return user;\n }\n\n const result = await runtime.intelligence.ɵconnectThread({\n threadId,\n userId: user.id,\n agentId,\n });\n\n if (result === null) {\n return new Response(null, {\n status: 204,\n });\n }\n\n return Response.json(\n {\n threadId: result.threadId,\n joinToken: result.joinToken,\n realtime: buildRealtimeConnectionInfo({\n clientUrl: runtime.intelligence.ɵgetClientWsUrl(),\n threadId: result.threadId,\n }),\n },\n {\n headers: { \"Cache-Control\": \"no-cache\", Connection: \"keep-alive\" },\n },\n );\n } catch (error) {\n const status = getPlatformErrorStatus(error);\n const message =\n error instanceof Error ? error.message : \"Connect request failed\";\n\n if (\n status === 400 ||\n status === 401 ||\n status === 403 ||\n status === 404 ||\n status === 409\n ) {\n return Response.json(\n {\n error: \"Connect request rejected\",\n message:\n error instanceof Error\n ? error.message\n : \"Intelligence platform rejected the connect request\",\n },\n { status },\n );\n }\n\n // The platform answered, but with a status we do not special-case above.\n // Pass it through rather than relabelling it: reporting a 503 as a 404 tells\n // the browser the thread does not exist, when the truth is that the platform\n // is temporarily unwell and the request is worth retrying.\n if (typeof status === \"number\") {\n console.error(`Connect request failed with status ${status}:`, error);\n return Response.json(\n { error: \"Connect request failed\", message },\n {\n status,\n },\n );\n }\n\n // No status at all, so this never reached the platform: a socket timeout, a\n // DNS failure, a connection reset, or a bug on our side. 502 says \"the thing\n // behind me is unreachable\", which is both true and actionable. It must not\n // be a 404, which asserts the thread does not exist and sends the caller off\n // to investigate the wrong thing entirely.\n console.error(\"Connect request could not reach Intelligence:\", error);\n return Response.json(\n {\n error: \"Connect request failed\",\n message,\n },\n { status: 502 },\n );\n }\n}\n"],"mappings":";;;;;;;;;AAQA,SAAS,4BAA4B,QAGI;AACvC,QAAO;EACL,WAAW,OAAO;EAClB,OAAO,UAAU,OAAO;EACzB;;AAUH,eAAsB,0BAA0B,EAC9C,SACA,SACA,SACA,YACqD;AACrD,KAAI,CAAC,QAAQ,aACX,QAAO,SAAS,KACd;EACE,OAAO;EACP,SAAS;EACV,EACD,EAAE,QAAQ,KAAK,CAChB;AAGH,KAAI;EACF,MAAM,OAAO,MAAMA,0DAAwB;GAAE;GAAS;GAAS,CAAC;AAChE,MAAIC,wCAAkB,KAAK,CACzB,QAAO;EAGT,MAAM,SAAS,MAAM,QAAQ,aAAa,eAAe;GACvD;GACA,QAAQ,KAAK;GACb;GACD,CAAC;AAEF,MAAI,WAAW,KACb,QAAO,IAAI,SAAS,MAAM,EACxB,QAAQ,KACT,CAAC;AAGJ,SAAO,SAAS,KACd;GACE,UAAU,OAAO;GACjB,WAAW,OAAO;GAClB,UAAU,4BAA4B;IACpC,WAAW,QAAQ,aAAa,iBAAiB;IACjD,UAAU,OAAO;IAClB,CAAC;GACH,EACD,EACE,SAAS;GAAE,iBAAiB;GAAY,YAAY;GAAc,EACnE,CACF;UACM,OAAO;EACd,MAAM,SAASC,kDAAuB,MAAM;EAC5C,MAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;AAE3C,MACE,WAAW,OACX,WAAW,OACX,WAAW,OACX,WAAW,OACX,WAAW,IAEX,QAAO,SAAS,KACd;GACE,OAAO;GACP,SACE,iBAAiB,QACb,MAAM,UACN;GACP,EACD,EAAE,QAAQ,CACX;AAOH,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAQ,MAAM,sCAAsC,OAAO,IAAI,MAAM;AACrE,UAAO,SAAS,KACd;IAAE,OAAO;IAA0B;IAAS,EAC5C,EACE,QACD,CACF;;AAQH,UAAQ,MAAM,iDAAiD,MAAM;AACrE,SAAO,SAAS,KACd;GACE,OAAO;GACP;GACD,EACD,EAAE,QAAQ,KAAK,CAChB"}
|
|
1
|
+
{"version":3,"file":"connect.cjs","names":["resolveIntelligenceUser","isHandlerResponse","getPlatformErrorStatus"],"sources":["../../../../../src/v2/runtime/handlers/intelligence/connect.ts"],"sourcesContent":["import type { CopilotIntelligenceRuntimeLike } from \"../../core/runtime\";\nimport { getPlatformErrorStatus } from \"../shared/intelligence-utils\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\nimport { isHandlerResponse } from \"../shared/json-response\";\n\n/**\n * Builds browser-facing realtime connection metadata owned by the runtime.\n */\nfunction buildRealtimeConnectionInfo(params: {\n clientUrl: string;\n threadId: string;\n}): { clientUrl: string; topic: string } {\n return {\n clientUrl: params.clientUrl,\n topic: `thread:${params.threadId}`,\n };\n}\n\ninterface HandleIntelligenceConnectParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n threadId: string;\n}\n\nexport async function handleIntelligenceConnect({\n runtime,\n request,\n agentId,\n threadId,\n}: HandleIntelligenceConnectParams): Promise<Response> {\n if (!runtime.intelligence) {\n return Response.json(\n {\n error: \"Intelligence not configured\",\n message: \"Intelligence mode requires a CopilotKitIntelligence\",\n },\n { status: 500 },\n );\n }\n\n try {\n const user = await resolveIntelligenceUser({ runtime, request });\n if (isHandlerResponse(user)) {\n return user;\n }\n\n const result = await runtime.intelligence.ɵconnectThread({\n threadId,\n userId: user.id,\n agentId,\n });\n\n if (result === null) {\n return new Response(null, {\n status: 204,\n });\n }\n\n return Response.json(\n {\n threadId: result.threadId,\n joinToken: result.joinToken,\n runId: result.runId,\n realtime: buildRealtimeConnectionInfo({\n clientUrl: runtime.intelligence.ɵgetClientWsUrl(),\n threadId: result.threadId,\n }),\n },\n {\n headers: { \"Cache-Control\": \"no-cache\", Connection: \"keep-alive\" },\n },\n );\n } catch (error) {\n const status = getPlatformErrorStatus(error);\n const message =\n error instanceof Error ? error.message : \"Connect request failed\";\n\n if (\n status === 400 ||\n status === 401 ||\n status === 403 ||\n status === 404 ||\n status === 409\n ) {\n return Response.json(\n {\n error: \"Connect request rejected\",\n message:\n error instanceof Error\n ? error.message\n : \"Intelligence platform rejected the connect request\",\n },\n { status },\n );\n }\n\n // The platform answered, but with a status we do not special-case above.\n // Pass it through rather than relabelling it: reporting a 503 as a 404 tells\n // the browser the thread does not exist, when the truth is that the platform\n // is temporarily unwell and the request is worth retrying.\n if (typeof status === \"number\") {\n console.error(`Connect request failed with status ${status}:`, error);\n return Response.json(\n { error: \"Connect request failed\", message },\n {\n status,\n },\n );\n }\n\n // No status at all, so this never reached the platform: a socket timeout, a\n // DNS failure, a connection reset, or a bug on our side. 502 says \"the thing\n // behind me is unreachable\", which is both true and actionable. It must not\n // be a 404, which asserts the thread does not exist and sends the caller off\n // to investigate the wrong thing entirely.\n console.error(\"Connect request could not reach Intelligence:\", error);\n return Response.json(\n {\n error: \"Connect request failed\",\n message,\n },\n { status: 502 },\n );\n }\n}\n"],"mappings":";;;;;;;;;AAQA,SAAS,4BAA4B,QAGI;AACvC,QAAO;EACL,WAAW,OAAO;EAClB,OAAO,UAAU,OAAO;EACzB;;AAUH,eAAsB,0BAA0B,EAC9C,SACA,SACA,SACA,YACqD;AACrD,KAAI,CAAC,QAAQ,aACX,QAAO,SAAS,KACd;EACE,OAAO;EACP,SAAS;EACV,EACD,EAAE,QAAQ,KAAK,CAChB;AAGH,KAAI;EACF,MAAM,OAAO,MAAMA,0DAAwB;GAAE;GAAS;GAAS,CAAC;AAChE,MAAIC,wCAAkB,KAAK,CACzB,QAAO;EAGT,MAAM,SAAS,MAAM,QAAQ,aAAa,eAAe;GACvD;GACA,QAAQ,KAAK;GACb;GACD,CAAC;AAEF,MAAI,WAAW,KACb,QAAO,IAAI,SAAS,MAAM,EACxB,QAAQ,KACT,CAAC;AAGJ,SAAO,SAAS,KACd;GACE,UAAU,OAAO;GACjB,WAAW,OAAO;GAClB,OAAO,OAAO;GACd,UAAU,4BAA4B;IACpC,WAAW,QAAQ,aAAa,iBAAiB;IACjD,UAAU,OAAO;IAClB,CAAC;GACH,EACD,EACE,SAAS;GAAE,iBAAiB;GAAY,YAAY;GAAc,EACnE,CACF;UACM,OAAO;EACd,MAAM,SAASC,kDAAuB,MAAM;EAC5C,MAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;AAE3C,MACE,WAAW,OACX,WAAW,OACX,WAAW,OACX,WAAW,OACX,WAAW,IAEX,QAAO,SAAS,KACd;GACE,OAAO;GACP,SACE,iBAAiB,QACb,MAAM,UACN;GACP,EACD,EAAE,QAAQ,CACX;AAOH,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAQ,MAAM,sCAAsC,OAAO,IAAI,MAAM;AACrE,UAAO,SAAS,KACd;IAAE,OAAO;IAA0B;IAAS,EAC5C,EACE,QACD,CACF;;AAQH,UAAQ,MAAM,iDAAiD,MAAM;AACrE,SAAO,SAAS,KACd;GACE,OAAO;GACP;GACD,EACD,EAAE,QAAQ,KAAK,CAChB"}
|
|
@@ -33,6 +33,7 @@ async function handleIntelligenceConnect({ runtime, request, agentId, threadId }
|
|
|
33
33
|
return Response.json({
|
|
34
34
|
threadId: result.threadId,
|
|
35
35
|
joinToken: result.joinToken,
|
|
36
|
+
runId: result.runId,
|
|
36
37
|
realtime: buildRealtimeConnectionInfo({
|
|
37
38
|
clientUrl: runtime.intelligence.ɵgetClientWsUrl(),
|
|
38
39
|
threadId: result.threadId
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/intelligence/connect.ts"],"sourcesContent":["import type { CopilotIntelligenceRuntimeLike } from \"../../core/runtime\";\nimport { getPlatformErrorStatus } from \"../shared/intelligence-utils\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\nimport { isHandlerResponse } from \"../shared/json-response\";\n\n/**\n * Builds browser-facing realtime connection metadata owned by the runtime.\n */\nfunction buildRealtimeConnectionInfo(params: {\n clientUrl: string;\n threadId: string;\n}): { clientUrl: string; topic: string } {\n return {\n clientUrl: params.clientUrl,\n topic: `thread:${params.threadId}`,\n };\n}\n\ninterface HandleIntelligenceConnectParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n threadId: string;\n}\n\nexport async function handleIntelligenceConnect({\n runtime,\n request,\n agentId,\n threadId,\n}: HandleIntelligenceConnectParams): Promise<Response> {\n if (!runtime.intelligence) {\n return Response.json(\n {\n error: \"Intelligence not configured\",\n message: \"Intelligence mode requires a CopilotKitIntelligence\",\n },\n { status: 500 },\n );\n }\n\n try {\n const user = await resolveIntelligenceUser({ runtime, request });\n if (isHandlerResponse(user)) {\n return user;\n }\n\n const result = await runtime.intelligence.ɵconnectThread({\n threadId,\n userId: user.id,\n agentId,\n });\n\n if (result === null) {\n return new Response(null, {\n status: 204,\n });\n }\n\n return Response.json(\n {\n threadId: result.threadId,\n joinToken: result.joinToken,\n realtime: buildRealtimeConnectionInfo({\n clientUrl: runtime.intelligence.ɵgetClientWsUrl(),\n threadId: result.threadId,\n }),\n },\n {\n headers: { \"Cache-Control\": \"no-cache\", Connection: \"keep-alive\" },\n },\n );\n } catch (error) {\n const status = getPlatformErrorStatus(error);\n const message =\n error instanceof Error ? error.message : \"Connect request failed\";\n\n if (\n status === 400 ||\n status === 401 ||\n status === 403 ||\n status === 404 ||\n status === 409\n ) {\n return Response.json(\n {\n error: \"Connect request rejected\",\n message:\n error instanceof Error\n ? error.message\n : \"Intelligence platform rejected the connect request\",\n },\n { status },\n );\n }\n\n // The platform answered, but with a status we do not special-case above.\n // Pass it through rather than relabelling it: reporting a 503 as a 404 tells\n // the browser the thread does not exist, when the truth is that the platform\n // is temporarily unwell and the request is worth retrying.\n if (typeof status === \"number\") {\n console.error(`Connect request failed with status ${status}:`, error);\n return Response.json(\n { error: \"Connect request failed\", message },\n {\n status,\n },\n );\n }\n\n // No status at all, so this never reached the platform: a socket timeout, a\n // DNS failure, a connection reset, or a bug on our side. 502 says \"the thing\n // behind me is unreachable\", which is both true and actionable. It must not\n // be a 404, which asserts the thread does not exist and sends the caller off\n // to investigate the wrong thing entirely.\n console.error(\"Connect request could not reach Intelligence:\", error);\n return Response.json(\n {\n error: \"Connect request failed\",\n message,\n },\n { status: 502 },\n );\n }\n}\n"],"mappings":";;;;;;;;;AAQA,SAAS,4BAA4B,QAGI;AACvC,QAAO;EACL,WAAW,OAAO;EAClB,OAAO,UAAU,OAAO;EACzB;;AAUH,eAAsB,0BAA0B,EAC9C,SACA,SACA,SACA,YACqD;AACrD,KAAI,CAAC,QAAQ,aACX,QAAO,SAAS,KACd;EACE,OAAO;EACP,SAAS;EACV,EACD,EAAE,QAAQ,KAAK,CAChB;AAGH,KAAI;EACF,MAAM,OAAO,MAAM,wBAAwB;GAAE;GAAS;GAAS,CAAC;AAChE,MAAI,kBAAkB,KAAK,CACzB,QAAO;EAGT,MAAM,SAAS,MAAM,QAAQ,aAAa,eAAe;GACvD;GACA,QAAQ,KAAK;GACb;GACD,CAAC;AAEF,MAAI,WAAW,KACb,QAAO,IAAI,SAAS,MAAM,EACxB,QAAQ,KACT,CAAC;AAGJ,SAAO,SAAS,KACd;GACE,UAAU,OAAO;GACjB,WAAW,OAAO;GAClB,UAAU,4BAA4B;IACpC,WAAW,QAAQ,aAAa,iBAAiB;IACjD,UAAU,OAAO;IAClB,CAAC;GACH,EACD,EACE,SAAS;GAAE,iBAAiB;GAAY,YAAY;GAAc,EACnE,CACF;UACM,OAAO;EACd,MAAM,SAAS,uBAAuB,MAAM;EAC5C,MAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;AAE3C,MACE,WAAW,OACX,WAAW,OACX,WAAW,OACX,WAAW,OACX,WAAW,IAEX,QAAO,SAAS,KACd;GACE,OAAO;GACP,SACE,iBAAiB,QACb,MAAM,UACN;GACP,EACD,EAAE,QAAQ,CACX;AAOH,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAQ,MAAM,sCAAsC,OAAO,IAAI,MAAM;AACrE,UAAO,SAAS,KACd;IAAE,OAAO;IAA0B;IAAS,EAC5C,EACE,QACD,CACF;;AAQH,UAAQ,MAAM,iDAAiD,MAAM;AACrE,SAAO,SAAS,KACd;GACE,OAAO;GACP;GACD,EACD,EAAE,QAAQ,KAAK,CAChB"}
|
|
1
|
+
{"version":3,"file":"connect.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/intelligence/connect.ts"],"sourcesContent":["import type { CopilotIntelligenceRuntimeLike } from \"../../core/runtime\";\nimport { getPlatformErrorStatus } from \"../shared/intelligence-utils\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\nimport { isHandlerResponse } from \"../shared/json-response\";\n\n/**\n * Builds browser-facing realtime connection metadata owned by the runtime.\n */\nfunction buildRealtimeConnectionInfo(params: {\n clientUrl: string;\n threadId: string;\n}): { clientUrl: string; topic: string } {\n return {\n clientUrl: params.clientUrl,\n topic: `thread:${params.threadId}`,\n };\n}\n\ninterface HandleIntelligenceConnectParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n threadId: string;\n}\n\nexport async function handleIntelligenceConnect({\n runtime,\n request,\n agentId,\n threadId,\n}: HandleIntelligenceConnectParams): Promise<Response> {\n if (!runtime.intelligence) {\n return Response.json(\n {\n error: \"Intelligence not configured\",\n message: \"Intelligence mode requires a CopilotKitIntelligence\",\n },\n { status: 500 },\n );\n }\n\n try {\n const user = await resolveIntelligenceUser({ runtime, request });\n if (isHandlerResponse(user)) {\n return user;\n }\n\n const result = await runtime.intelligence.ɵconnectThread({\n threadId,\n userId: user.id,\n agentId,\n });\n\n if (result === null) {\n return new Response(null, {\n status: 204,\n });\n }\n\n return Response.json(\n {\n threadId: result.threadId,\n joinToken: result.joinToken,\n runId: result.runId,\n realtime: buildRealtimeConnectionInfo({\n clientUrl: runtime.intelligence.ɵgetClientWsUrl(),\n threadId: result.threadId,\n }),\n },\n {\n headers: { \"Cache-Control\": \"no-cache\", Connection: \"keep-alive\" },\n },\n );\n } catch (error) {\n const status = getPlatformErrorStatus(error);\n const message =\n error instanceof Error ? error.message : \"Connect request failed\";\n\n if (\n status === 400 ||\n status === 401 ||\n status === 403 ||\n status === 404 ||\n status === 409\n ) {\n return Response.json(\n {\n error: \"Connect request rejected\",\n message:\n error instanceof Error\n ? error.message\n : \"Intelligence platform rejected the connect request\",\n },\n { status },\n );\n }\n\n // The platform answered, but with a status we do not special-case above.\n // Pass it through rather than relabelling it: reporting a 503 as a 404 tells\n // the browser the thread does not exist, when the truth is that the platform\n // is temporarily unwell and the request is worth retrying.\n if (typeof status === \"number\") {\n console.error(`Connect request failed with status ${status}:`, error);\n return Response.json(\n { error: \"Connect request failed\", message },\n {\n status,\n },\n );\n }\n\n // No status at all, so this never reached the platform: a socket timeout, a\n // DNS failure, a connection reset, or a bug on our side. 502 says \"the thing\n // behind me is unreachable\", which is both true and actionable. It must not\n // be a 404, which asserts the thread does not exist and sends the caller off\n // to investigate the wrong thing entirely.\n console.error(\"Connect request could not reach Intelligence:\", error);\n return Response.json(\n {\n error: \"Connect request failed\",\n message,\n },\n { status: 502 },\n );\n }\n}\n"],"mappings":";;;;;;;;;AAQA,SAAS,4BAA4B,QAGI;AACvC,QAAO;EACL,WAAW,OAAO;EAClB,OAAO,UAAU,OAAO;EACzB;;AAUH,eAAsB,0BAA0B,EAC9C,SACA,SACA,SACA,YACqD;AACrD,KAAI,CAAC,QAAQ,aACX,QAAO,SAAS,KACd;EACE,OAAO;EACP,SAAS;EACV,EACD,EAAE,QAAQ,KAAK,CAChB;AAGH,KAAI;EACF,MAAM,OAAO,MAAM,wBAAwB;GAAE;GAAS;GAAS,CAAC;AAChE,MAAI,kBAAkB,KAAK,CACzB,QAAO;EAGT,MAAM,SAAS,MAAM,QAAQ,aAAa,eAAe;GACvD;GACA,QAAQ,KAAK;GACb;GACD,CAAC;AAEF,MAAI,WAAW,KACb,QAAO,IAAI,SAAS,MAAM,EACxB,QAAQ,KACT,CAAC;AAGJ,SAAO,SAAS,KACd;GACE,UAAU,OAAO;GACjB,WAAW,OAAO;GAClB,OAAO,OAAO;GACd,UAAU,4BAA4B;IACpC,WAAW,QAAQ,aAAa,iBAAiB;IACjD,UAAU,OAAO;IAClB,CAAC;GACH,EACD,EACE,SAAS;GAAE,iBAAiB;GAAY,YAAY;GAAc,EACnE,CACF;UACM,OAAO;EACd,MAAM,SAAS,uBAAuB,MAAM;EAC5C,MAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;AAE3C,MACE,WAAW,OACX,WAAW,OACX,WAAW,OACX,WAAW,OACX,WAAW,IAEX,QAAO,SAAS,KACd;GACE,OAAO;GACP,SACE,iBAAiB,QACb,MAAM,UACN;GACP,EACD,EAAE,QAAQ,CACX;AAOH,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAQ,MAAM,sCAAsC,OAAO,IAAI,MAAM;AACrE,UAAO,SAAS,KACd;IAAE,OAAO;IAA0B;IAAS,EAC5C,EACE,QACD,CACF;;AAQH,UAAQ,MAAM,iDAAiD,MAAM;AACrE,SAAO,SAAS,KACd;GACE,OAAO;GACP;GACD,EACD,EAAE,QAAQ,KAAK,CAChB"}
|
|
@@ -8,8 +8,8 @@ const require_json_response = require('./json-response.cjs');
|
|
|
8
8
|
const require_resolve_intelligence_user = require('./resolve-intelligence-user.cjs');
|
|
9
9
|
const require_memory_policy = require('./memory-policy.cjs');
|
|
10
10
|
let _copilotkit_shared = require("@copilotkit/shared");
|
|
11
|
-
let _ag_ui_client = require("@ag-ui/client");
|
|
12
11
|
let _ag_ui_mcp_middleware = require("@ag-ui/mcp-middleware");
|
|
12
|
+
let _ag_ui_core_schemas = require("@ag-ui/core/schemas");
|
|
13
13
|
let _copilotkit_shared_event_transforms = require("@copilotkit/shared/event-transforms");
|
|
14
14
|
let _ag_ui_mcp_apps_middleware = require("@ag-ui/mcp-apps-middleware");
|
|
15
15
|
|
|
@@ -129,10 +129,96 @@ async function attachIntelligenceEnterpriseLearning(params) {
|
|
|
129
129
|
}
|
|
130
130
|
}]));
|
|
131
131
|
}
|
|
132
|
+
function warnCompatibility(what, replacement) {
|
|
133
|
+
if (typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.SUPPRESS_TRANSFORMATION_WARNINGS) return;
|
|
134
|
+
console.warn(`[ag-ui][compat] Converting deprecated ${what} to ${replacement}. The old shape leaves the protocol after its shim window — see the repo-root DEPRECATIONS.md. Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`);
|
|
135
|
+
}
|
|
136
|
+
function isRecord(value) {
|
|
137
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
138
|
+
}
|
|
139
|
+
function omitLegacyNull(value, field, context) {
|
|
140
|
+
if (!isRecord(value) || value[field] !== null) return value;
|
|
141
|
+
warnCompatibility(`${context}.${field}: null`, "an absent field");
|
|
142
|
+
const { [field]: _null, ...rest } = value;
|
|
143
|
+
return rest;
|
|
144
|
+
}
|
|
145
|
+
function mapProtocolArray(value, field, normalize) {
|
|
146
|
+
if (!isRecord(value) || !Array.isArray(value[field])) return value;
|
|
147
|
+
const original = value[field];
|
|
148
|
+
const entries = original.map(normalize);
|
|
149
|
+
return entries.some((entry, index) => entry !== original[index]) ? {
|
|
150
|
+
...value,
|
|
151
|
+
[field]: entries
|
|
152
|
+
} : value;
|
|
153
|
+
}
|
|
154
|
+
function mediaTypeFor(mimeType) {
|
|
155
|
+
if (mimeType.startsWith("image/")) return "image";
|
|
156
|
+
if (mimeType.startsWith("audio/")) return "audio";
|
|
157
|
+
if (mimeType.startsWith("video/")) return "video";
|
|
158
|
+
return "document";
|
|
159
|
+
}
|
|
160
|
+
function sameSource(part, converted) {
|
|
161
|
+
if (!isRecord(part) || part.type !== converted.type) return false;
|
|
162
|
+
const a = part.source;
|
|
163
|
+
const b = converted.source;
|
|
164
|
+
return isRecord(a) && a.type === b.type && a.value === b.value && a.mimeType === b.mimeType;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* The 0.x `{ type: "binary" }` part, which 1.0 retired and main accepted.
|
|
168
|
+
* Mirrors AG-UI's outgoing upgrade (client/src/middleware/legacy-content.ts):
|
|
169
|
+
* data or url becomes the media part its mime type names, and a binary part
|
|
170
|
+
* that only mirrors a modern part already in the message is dropped. A part
|
|
171
|
+
* with only an `id` has no 1.0 form; it is dropped with a warning instead of
|
|
172
|
+
* failing the whole request, which is what BuiltInAgent already did with it.
|
|
173
|
+
*/
|
|
174
|
+
function upgradeLegacyBinaryParts(content) {
|
|
175
|
+
return content.flatMap((part) => {
|
|
176
|
+
if (!isRecord(part) || part.type !== "binary" || typeof part.mimeType !== "string") return [part];
|
|
177
|
+
const kind = typeof part.data === "string" ? "data" : typeof part.url === "string" ? "url" : null;
|
|
178
|
+
if (kind === null) {
|
|
179
|
+
console.warn("[CopilotKit] Dropping a legacy binary content part that has no data or url; AG-UI 1.0 has no equivalent for it.");
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
182
|
+
warnCompatibility("binary input content", "the modern media content part");
|
|
183
|
+
const converted = {
|
|
184
|
+
type: mediaTypeFor(part.mimeType),
|
|
185
|
+
source: {
|
|
186
|
+
type: kind,
|
|
187
|
+
value: kind === "data" ? part.data : part.url,
|
|
188
|
+
mimeType: part.mimeType
|
|
189
|
+
},
|
|
190
|
+
...typeof part.filename === "string" ? { metadata: { filename: part.filename } } : {}
|
|
191
|
+
};
|
|
192
|
+
return content.some((other) => sameSource(other, converted)) ? [] : [converted];
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
function normalizeLegacyMessageContent(message) {
|
|
196
|
+
return mapProtocolArray(isRecord(message) && Array.isArray(message.content) && message.content.some((part) => isRecord(part) && part.type === "binary") ? {
|
|
197
|
+
...message,
|
|
198
|
+
content: upgradeLegacyBinaryParts(message.content)
|
|
199
|
+
} : message, "content", (part) => {
|
|
200
|
+
if (!isRecord(part)) return part;
|
|
201
|
+
switch (part.type) {
|
|
202
|
+
case "image":
|
|
203
|
+
case "audio":
|
|
204
|
+
case "video":
|
|
205
|
+
case "document": return omitLegacyNull(part, "metadata", `${part.type} input content`);
|
|
206
|
+
default: return part;
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
function normalizeLegacyRunAgentInput(input) {
|
|
211
|
+
let normalized = omitLegacyNull(input, "forwardedProps", "RunAgentInput");
|
|
212
|
+
normalized = mapProtocolArray(normalized, "tools", (tool) => omitLegacyNull(tool, "parameters", "Tool"));
|
|
213
|
+
normalized = mapProtocolArray(normalized, "resume", (entry) => omitLegacyNull(entry, "payload", "ResumeEntry"));
|
|
214
|
+
return mapProtocolArray(normalized, "messages", normalizeLegacyMessageContent);
|
|
215
|
+
}
|
|
216
|
+
function parseRunAgentInput(value) {
|
|
217
|
+
return _ag_ui_core_schemas.RunAgentInputSchema.parse(normalizeLegacyRunAgentInput(value));
|
|
218
|
+
}
|
|
132
219
|
async function parseRunRequest(request) {
|
|
133
220
|
try {
|
|
134
|
-
|
|
135
|
-
return _ag_ui_client.RunAgentInputSchema.parse(requestBody);
|
|
221
|
+
return parseRunAgentInput(await request.json());
|
|
136
222
|
} catch (error) {
|
|
137
223
|
_copilotkit_shared.logger.error("Invalid run request body:", error);
|
|
138
224
|
return new Response(JSON.stringify({
|
|
@@ -147,7 +233,7 @@ async function parseRunRequest(request) {
|
|
|
147
233
|
async function parseConnectRequest(request) {
|
|
148
234
|
try {
|
|
149
235
|
const requestBody = await request.json();
|
|
150
|
-
const input =
|
|
236
|
+
const input = parseRunAgentInput(requestBody);
|
|
151
237
|
let lastSeenEventId = null;
|
|
152
238
|
if ("lastSeenEventId" in requestBody && (typeof requestBody.lastSeenEventId === "string" || requestBody.lastSeenEventId === null)) lastSeenEventId = requestBody.lastSeenEventId ?? null;
|
|
153
239
|
return {
|