@copilotkit/runtime 1.8.5-next.2 → 1.8.5-next.4
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/CHANGELOG.md +14 -0
- package/dist/{chunk-PJX3FQOX.mjs → chunk-574FKWP5.mjs} +2 -2
- package/dist/{chunk-FZJAYGIR.mjs → chunk-DNI7KA7Y.mjs} +2 -2
- package/dist/{chunk-A7E5UM7B.mjs → chunk-GGXHVDCG.mjs} +2 -2
- package/dist/{chunk-A4MGCX6X.mjs → chunk-PKO7BUPS.mjs} +186 -14
- package/dist/chunk-PKO7BUPS.mjs.map +1 -0
- package/dist/chunk-Q6JA6YY3.mjs +1 -0
- package/dist/{chunk-7VNWCLG4.mjs → chunk-WQZQTGHT.mjs} +2 -2
- package/dist/index.d.ts +8 -8
- package/dist/index.js +4042 -3862
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -6
- package/dist/index.mjs.map +1 -1
- package/dist/lib/index.d.ts +7 -7
- package/dist/lib/index.js +3890 -3710
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +10 -6
- package/dist/lib/integrations/index.d.ts +4 -4
- package/dist/lib/integrations/index.js +1 -1
- package/dist/lib/integrations/index.js.map +1 -1
- package/dist/lib/integrations/index.mjs +5 -5
- package/dist/lib/integrations/nest/index.d.ts +3 -3
- package/dist/lib/integrations/nest/index.js +1 -1
- package/dist/lib/integrations/nest/index.js.map +1 -1
- package/dist/lib/integrations/nest/index.mjs +3 -3
- package/dist/lib/integrations/node-express/index.d.ts +3 -3
- package/dist/lib/integrations/node-express/index.js +1 -1
- package/dist/lib/integrations/node-express/index.js.map +1 -1
- package/dist/lib/integrations/node-express/index.mjs +3 -3
- package/dist/lib/integrations/node-http/index.d.ts +3 -3
- package/dist/lib/integrations/node-http/index.js +1 -1
- package/dist/lib/integrations/node-http/index.js.map +1 -1
- package/dist/lib/integrations/node-http/index.mjs +2 -2
- package/dist/service-adapters/index.mjs +1 -1
- package/dist/{copilot-runtime-9347bd66.d.ts → shared-86ec42e7.d.ts} +130 -45
- package/package.json +2 -2
- package/src/lib/index.ts +2 -1
- package/src/lib/runtime/copilot-runtime.ts +218 -11
- package/src/lib/runtime/mcp-tools-utils.ts +117 -0
- package/src/lib/runtime/remote-lg-action.ts +24 -2
- package/dist/chunk-A4MGCX6X.mjs.map +0 -1
- package/dist/chunk-PTC5JN3P.mjs +0 -1
- /package/dist/{chunk-PJX3FQOX.mjs.map → chunk-574FKWP5.mjs.map} +0 -0
- /package/dist/{chunk-FZJAYGIR.mjs.map → chunk-DNI7KA7Y.mjs.map} +0 -0
- /package/dist/{chunk-A7E5UM7B.mjs.map → chunk-GGXHVDCG.mjs.map} +0 -0
- /package/dist/{chunk-PTC5JN3P.mjs.map → chunk-Q6JA6YY3.mjs.map} +0 -0
- /package/dist/{chunk-7VNWCLG4.mjs.map → chunk-WQZQTGHT.mjs.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
copilotRuntimeNodeHttpEndpoint
|
|
3
|
-
} from "../../../chunk-
|
|
4
|
-
import "../../../chunk-
|
|
3
|
+
} from "../../../chunk-PKO7BUPS.mjs";
|
|
4
|
+
import "../../../chunk-DNI7KA7Y.mjs";
|
|
5
5
|
import "../../../chunk-5BIEM2UU.mjs";
|
|
6
6
|
import "../../../chunk-RTFJTJMA.mjs";
|
|
7
7
|
import "../../../chunk-2OZAGFV3.mjs";
|
|
@@ -1,52 +1,11 @@
|
|
|
1
|
-
import { Parameter, Action } from '@copilotkit/shared';
|
|
2
|
-
import { b as CopilotServiceAdapter, R as RemoteChainParameters, A as ActionInput, d as AgentSessionInput, e as AgentStateInput, F as ForwardedParametersInput, E as ExtensionsInput, f as RuntimeEventSource, g as ExtensionsResponse } from './langserve-6f7af8d3.js';
|
|
3
|
-
import { M as MessageInput, a as Message } from './index-5bec5424.js';
|
|
4
1
|
import * as graphql from 'graphql';
|
|
5
2
|
import * as pino from 'pino';
|
|
6
3
|
import { YogaInitialContext, createYoga } from 'graphql-yoga';
|
|
4
|
+
import { Parameter, Action } from '@copilotkit/shared';
|
|
5
|
+
import { b as CopilotServiceAdapter, A as ActionInput, d as AgentSessionInput, e as AgentStateInput, F as ForwardedParametersInput, E as ExtensionsInput, R as RemoteChainParameters, f as RuntimeEventSource, g as ExtensionsResponse } from './langserve-6f7af8d3.js';
|
|
6
|
+
import { M as MessageInput, a as Message } from './index-5bec5424.js';
|
|
7
7
|
import { CopilotCloudOptions } from './lib/cloud/index.js';
|
|
8
8
|
|
|
9
|
-
type LogLevel = "debug" | "info" | "warn" | "error";
|
|
10
|
-
type CopilotRuntimeLogger = ReturnType<typeof createLogger>;
|
|
11
|
-
declare function createLogger(options?: {
|
|
12
|
-
level?: LogLevel;
|
|
13
|
-
component?: string;
|
|
14
|
-
}): pino.Logger<never>;
|
|
15
|
-
|
|
16
|
-
declare const logger: pino.Logger<never>;
|
|
17
|
-
declare const addCustomHeaderPlugin: {
|
|
18
|
-
onResponse({ response }: {
|
|
19
|
-
response: any;
|
|
20
|
-
}): void;
|
|
21
|
-
};
|
|
22
|
-
type AnyPrimitive = string | boolean | number | null;
|
|
23
|
-
type CopilotRequestContextProperties = Record<string, AnyPrimitive | Record<string, AnyPrimitive>>;
|
|
24
|
-
type GraphQLContext = YogaInitialContext & {
|
|
25
|
-
_copilotkit: CreateCopilotRuntimeServerOptions;
|
|
26
|
-
properties: CopilotRequestContextProperties;
|
|
27
|
-
logger: typeof logger;
|
|
28
|
-
};
|
|
29
|
-
interface CreateCopilotRuntimeServerOptions {
|
|
30
|
-
runtime: CopilotRuntime<any>;
|
|
31
|
-
serviceAdapter: CopilotServiceAdapter;
|
|
32
|
-
endpoint: string;
|
|
33
|
-
baseUrl?: string;
|
|
34
|
-
cloud?: CopilotCloudOptions;
|
|
35
|
-
properties?: CopilotRequestContextProperties;
|
|
36
|
-
logLevel?: LogLevel;
|
|
37
|
-
}
|
|
38
|
-
declare function createContext(initialContext: YogaInitialContext, copilotKitContext: CreateCopilotRuntimeServerOptions, contextLogger: typeof logger, properties?: CopilotRequestContextProperties): Promise<Partial<GraphQLContext>>;
|
|
39
|
-
declare function buildSchema(options?: {
|
|
40
|
-
emitSchemaFile?: string;
|
|
41
|
-
}): graphql.GraphQLSchema;
|
|
42
|
-
type CommonConfig = {
|
|
43
|
-
logging: typeof logger;
|
|
44
|
-
schema: ReturnType<typeof buildSchema>;
|
|
45
|
-
plugins: Parameters<typeof createYoga>[0]["plugins"];
|
|
46
|
-
context: (ctx: YogaInitialContext) => Promise<Partial<GraphQLContext>>;
|
|
47
|
-
};
|
|
48
|
-
declare function getCommonConfig(options: CreateCopilotRuntimeServerOptions): CommonConfig;
|
|
49
|
-
|
|
50
9
|
declare enum MetaEventName {
|
|
51
10
|
LangGraphInterruptEvent = "LangGraphInterruptEvent",
|
|
52
11
|
CopilotKitLangGraphInterruptEvent = "CopilotKitLangGraphInterruptEvent"
|
|
@@ -167,6 +126,53 @@ interface CopilotObservabilityConfig {
|
|
|
167
126
|
hooks: CopilotObservabilityHooks;
|
|
168
127
|
}
|
|
169
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Represents a tool provided by an MCP server.
|
|
131
|
+
*/
|
|
132
|
+
interface MCPTool {
|
|
133
|
+
description?: string;
|
|
134
|
+
/** Schema defining parameters, mirroring the MCP structure. */
|
|
135
|
+
schema?: {
|
|
136
|
+
parameters?: {
|
|
137
|
+
properties?: Record<string, any>;
|
|
138
|
+
required?: string[];
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
/** The function to call to execute the tool on the MCP server. */
|
|
142
|
+
execute(options: {
|
|
143
|
+
params: any;
|
|
144
|
+
}): Promise<any>;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Defines the contract for *any* MCP client implementation the user might provide.
|
|
148
|
+
*/
|
|
149
|
+
interface MCPClient {
|
|
150
|
+
/** A method that returns a map of tool names to MCPTool objects available from the connected MCP server. */
|
|
151
|
+
tools(): Promise<Record<string, MCPTool>>;
|
|
152
|
+
/** An optional method for cleanup if the underlying client requires explicit disconnection. */
|
|
153
|
+
close?(): Promise<void>;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Configuration for connecting to an MCP endpoint.
|
|
157
|
+
*/
|
|
158
|
+
interface MCPEndpointConfig {
|
|
159
|
+
endpoint: string;
|
|
160
|
+
apiKey?: string;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Extracts CopilotKit-compatible parameters from an MCP tool schema.
|
|
164
|
+
* @param toolSchema The schema object from an MCPTool.
|
|
165
|
+
* @returns An array of Parameter objects.
|
|
166
|
+
*/
|
|
167
|
+
declare function extractParametersFromSchema(toolSchema?: MCPTool["schema"]): Parameter[];
|
|
168
|
+
/**
|
|
169
|
+
* Converts a map of MCPTools into an array of CopilotKit Actions.
|
|
170
|
+
* @param mcpTools A record mapping tool names to MCPTool objects.
|
|
171
|
+
* @param mcpEndpoint The endpoint URL from which these tools were fetched.
|
|
172
|
+
* @returns An array of Action<any> objects.
|
|
173
|
+
*/
|
|
174
|
+
declare function convertMCPToolsToActions(mcpTools: Record<string, MCPTool>, mcpEndpoint: string): Action<any>[];
|
|
175
|
+
|
|
170
176
|
/**
|
|
171
177
|
* <Callout type="info">
|
|
172
178
|
* This is the reference for the `CopilotRuntime` class. For more information and example code snippets, please see [Concept: Copilot Runtime](/concepts/copilot-runtime).
|
|
@@ -181,6 +187,7 @@ interface CopilotObservabilityConfig {
|
|
|
181
187
|
* ```
|
|
182
188
|
*/
|
|
183
189
|
|
|
190
|
+
type CreateMCPClientFunction = (config: MCPEndpointConfig) => Promise<MCPClient>;
|
|
184
191
|
interface CopilotRuntimeRequest {
|
|
185
192
|
serviceAdapter: CopilotServiceAdapter;
|
|
186
193
|
messages: MessageInput[];
|
|
@@ -290,6 +297,39 @@ interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []> {
|
|
|
290
297
|
* ```
|
|
291
298
|
*/
|
|
292
299
|
observability_c?: CopilotObservabilityConfig;
|
|
300
|
+
/**
|
|
301
|
+
* Configuration for connecting to Model Context Protocol (MCP) servers.
|
|
302
|
+
* Allows fetching and using tools defined on external MCP-compliant servers.
|
|
303
|
+
* Requires providing the `createMCPClient` function during instantiation.
|
|
304
|
+
* @experimental
|
|
305
|
+
*/
|
|
306
|
+
mcpEndpoints?: MCPEndpointConfig[];
|
|
307
|
+
/**
|
|
308
|
+
* A function that creates an MCP client instance for a given endpoint configuration.
|
|
309
|
+
* This function is responsible for using the appropriate MCP client library
|
|
310
|
+
* (e.g., `@copilotkit/runtime`, `ai`) to establish a connection.
|
|
311
|
+
* Required if `mcpEndpoints` is provided.
|
|
312
|
+
*
|
|
313
|
+
* ```typescript
|
|
314
|
+
* import { experimental_createMCPClient } from "ai"; // Import from vercel ai library
|
|
315
|
+
* // ...
|
|
316
|
+
* const runtime = new CopilotRuntime({
|
|
317
|
+
* mcpEndpoints: [{ endpoint: "..." }],
|
|
318
|
+
* async createMCPClient(config) {
|
|
319
|
+
* return await experimental_createMCPClient({
|
|
320
|
+
* transport: {
|
|
321
|
+
* type: "sse",
|
|
322
|
+
* url: config.endpoint,
|
|
323
|
+
* headers: config.apiKey
|
|
324
|
+
* ? { Authorization: `Bearer ${config.apiKey}` }
|
|
325
|
+
* : undefined,
|
|
326
|
+
* },
|
|
327
|
+
* });
|
|
328
|
+
* }
|
|
329
|
+
* });
|
|
330
|
+
* ```
|
|
331
|
+
*/
|
|
332
|
+
createMCPClient?: CreateMCPClientFunction;
|
|
293
333
|
}
|
|
294
334
|
declare class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
295
335
|
actions: ActionsConfiguration<T>;
|
|
@@ -300,7 +340,11 @@ declare class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
300
340
|
private delegateAgentProcessingToServiceAdapter;
|
|
301
341
|
private observability?;
|
|
302
342
|
private availableAgents;
|
|
343
|
+
private readonly mcpEndpointsConfig?;
|
|
344
|
+
private mcpActionCache;
|
|
345
|
+
private readonly createMCPClientImpl?;
|
|
303
346
|
constructor(params?: CopilotRuntimeConstructorParams<T>);
|
|
347
|
+
private injectMCPToolInstructions;
|
|
304
348
|
processRuntimeRequest(request: CopilotRuntimeRequest): Promise<CopilotRuntimeResponse>;
|
|
305
349
|
discoverAgentsFromEndpoints(graphqlContext: GraphQLContext): Promise<AgentWithEndpoint[]>;
|
|
306
350
|
loadAgentState(graphqlContext: GraphQLContext, threadId: string, agentName: string): Promise<LoadAgentStateResponse>;
|
|
@@ -313,4 +357,45 @@ declare function copilotKitEndpoint(config: Omit<CopilotKitEndpoint, "type">): C
|
|
|
313
357
|
declare function langGraphPlatformEndpoint(config: Omit<LangGraphPlatformEndpoint, "type">): LangGraphPlatformEndpoint;
|
|
314
358
|
declare function resolveEndpointType(endpoint: EndpointDefinition): EndpointType;
|
|
315
359
|
|
|
316
|
-
|
|
360
|
+
type LogLevel = "debug" | "info" | "warn" | "error";
|
|
361
|
+
type CopilotRuntimeLogger = ReturnType<typeof createLogger>;
|
|
362
|
+
declare function createLogger(options?: {
|
|
363
|
+
level?: LogLevel;
|
|
364
|
+
component?: string;
|
|
365
|
+
}): pino.Logger<never>;
|
|
366
|
+
|
|
367
|
+
declare const logger: pino.Logger<never>;
|
|
368
|
+
declare const addCustomHeaderPlugin: {
|
|
369
|
+
onResponse({ response }: {
|
|
370
|
+
response: any;
|
|
371
|
+
}): void;
|
|
372
|
+
};
|
|
373
|
+
type AnyPrimitive = string | boolean | number | null;
|
|
374
|
+
type CopilotRequestContextProperties = Record<string, AnyPrimitive | Record<string, AnyPrimitive>>;
|
|
375
|
+
type GraphQLContext = YogaInitialContext & {
|
|
376
|
+
_copilotkit: CreateCopilotRuntimeServerOptions;
|
|
377
|
+
properties: CopilotRequestContextProperties;
|
|
378
|
+
logger: typeof logger;
|
|
379
|
+
};
|
|
380
|
+
interface CreateCopilotRuntimeServerOptions {
|
|
381
|
+
runtime: CopilotRuntime<any>;
|
|
382
|
+
serviceAdapter: CopilotServiceAdapter;
|
|
383
|
+
endpoint: string;
|
|
384
|
+
baseUrl?: string;
|
|
385
|
+
cloud?: CopilotCloudOptions;
|
|
386
|
+
properties?: CopilotRequestContextProperties;
|
|
387
|
+
logLevel?: LogLevel;
|
|
388
|
+
}
|
|
389
|
+
declare function createContext(initialContext: YogaInitialContext, copilotKitContext: CreateCopilotRuntimeServerOptions, contextLogger: typeof logger, properties?: CopilotRequestContextProperties): Promise<Partial<GraphQLContext>>;
|
|
390
|
+
declare function buildSchema(options?: {
|
|
391
|
+
emitSchemaFile?: string;
|
|
392
|
+
}): graphql.GraphQLSchema;
|
|
393
|
+
type CommonConfig = {
|
|
394
|
+
logging: typeof logger;
|
|
395
|
+
schema: ReturnType<typeof buildSchema>;
|
|
396
|
+
plugins: Parameters<typeof createYoga>[0]["plugins"];
|
|
397
|
+
context: (ctx: YogaInitialContext) => Promise<Partial<GraphQLContext>>;
|
|
398
|
+
};
|
|
399
|
+
declare function getCommonConfig(options: CreateCopilotRuntimeServerOptions): CommonConfig;
|
|
400
|
+
|
|
401
|
+
export { CopilotRequestContextProperties as C, GraphQLContext as G, LogLevel as L, MCPTool as M, addCustomHeaderPlugin as a, CreateCopilotRuntimeServerOptions as b, createContext as c, buildSchema as d, CommonConfig as e, CopilotRuntimeLogger as f, getCommonConfig as g, createLogger as h, CopilotRuntimeRequest as i, CopilotRuntimeConstructorParams as j, CopilotRuntime as k, flattenToolCallsNoDuplicates as l, copilotKitEndpoint as m, langGraphPlatformEndpoint as n, MCPClient as o, MCPEndpointConfig as p, extractParametersFromSchema as q, resolveEndpointType as r, convertMCPToolsToActions as s };
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"publishConfig": {
|
|
10
10
|
"access": "public"
|
|
11
11
|
},
|
|
12
|
-
"version": "1.8.5-next.
|
|
12
|
+
"version": "1.8.5-next.4",
|
|
13
13
|
"sideEffects": false,
|
|
14
14
|
"main": "./dist/index.js",
|
|
15
15
|
"module": "./dist/index.mjs",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"rxjs": "^7.8.1",
|
|
60
60
|
"type-graphql": "2.0.0-rc.1",
|
|
61
61
|
"zod": "^3.23.3",
|
|
62
|
-
"@copilotkit/shared": "1.8.5-next.
|
|
62
|
+
"@copilotkit/shared": "1.8.5-next.4"
|
|
63
63
|
},
|
|
64
64
|
"keywords": [
|
|
65
65
|
"copilotkit",
|
package/src/lib/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from "./runtime/copilot-runtime";
|
|
2
1
|
export * from "../service-adapters/openai/openai-adapter";
|
|
3
2
|
export * from "../service-adapters/langchain/langchain-adapter";
|
|
4
3
|
export * from "../service-adapters/google/google-genai-adapter";
|
|
@@ -7,3 +6,5 @@ export * from "../service-adapters/unify/unify-adapter";
|
|
|
7
6
|
export * from "../service-adapters/groq/groq-adapter";
|
|
8
7
|
export * from "./integrations";
|
|
9
8
|
export * from "./logger";
|
|
9
|
+
export * from "./runtime/copilot-runtime";
|
|
10
|
+
export * from "./runtime/mcp-tools-utils";
|
|
@@ -67,8 +67,15 @@ import {
|
|
|
67
67
|
LLMResponseData,
|
|
68
68
|
LLMErrorData,
|
|
69
69
|
} from "../observability";
|
|
70
|
+
import { MessageRole } from "../../graphql/types/enums";
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
// +++ MCP Imports +++
|
|
73
|
+
import { MCPClient, MCPEndpointConfig, convertMCPToolsToActions } from "./mcp-tools-utils";
|
|
74
|
+
// Define the function type alias here or import if defined elsewhere
|
|
75
|
+
type CreateMCPClientFunction = (config: MCPEndpointConfig) => Promise<MCPClient>;
|
|
76
|
+
// --- MCP Imports ---
|
|
77
|
+
|
|
78
|
+
export interface CopilotRuntimeRequest {
|
|
72
79
|
serviceAdapter: CopilotServiceAdapter;
|
|
73
80
|
messages: MessageInput[];
|
|
74
81
|
actions: ActionInput[];
|
|
@@ -208,6 +215,41 @@ export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []
|
|
|
208
215
|
* ```
|
|
209
216
|
*/
|
|
210
217
|
observability_c?: CopilotObservabilityConfig;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Configuration for connecting to Model Context Protocol (MCP) servers.
|
|
221
|
+
* Allows fetching and using tools defined on external MCP-compliant servers.
|
|
222
|
+
* Requires providing the `createMCPClient` function during instantiation.
|
|
223
|
+
* @experimental
|
|
224
|
+
*/
|
|
225
|
+
mcpEndpoints?: MCPEndpointConfig[];
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* A function that creates an MCP client instance for a given endpoint configuration.
|
|
229
|
+
* This function is responsible for using the appropriate MCP client library
|
|
230
|
+
* (e.g., `@copilotkit/runtime`, `ai`) to establish a connection.
|
|
231
|
+
* Required if `mcpEndpoints` is provided.
|
|
232
|
+
*
|
|
233
|
+
* ```typescript
|
|
234
|
+
* import { experimental_createMCPClient } from "ai"; // Import from vercel ai library
|
|
235
|
+
* // ...
|
|
236
|
+
* const runtime = new CopilotRuntime({
|
|
237
|
+
* mcpEndpoints: [{ endpoint: "..." }],
|
|
238
|
+
* async createMCPClient(config) {
|
|
239
|
+
* return await experimental_createMCPClient({
|
|
240
|
+
* transport: {
|
|
241
|
+
* type: "sse",
|
|
242
|
+
* url: config.endpoint,
|
|
243
|
+
* headers: config.apiKey
|
|
244
|
+
* ? { Authorization: `Bearer ${config.apiKey}` }
|
|
245
|
+
* : undefined,
|
|
246
|
+
* },
|
|
247
|
+
* });
|
|
248
|
+
* }
|
|
249
|
+
* });
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
createMCPClient?: CreateMCPClientFunction;
|
|
211
253
|
}
|
|
212
254
|
|
|
213
255
|
export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
@@ -220,6 +262,15 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
220
262
|
private observability?: CopilotObservabilityConfig;
|
|
221
263
|
private availableAgents: Pick<AgentWithEndpoint, "name" | "id">[];
|
|
222
264
|
|
|
265
|
+
// +++ MCP Properties +++
|
|
266
|
+
private readonly mcpEndpointsConfig?: MCPEndpointConfig[];
|
|
267
|
+
private mcpActionCache = new Map<string, Action<any>[]>();
|
|
268
|
+
// --- MCP Properties ---
|
|
269
|
+
|
|
270
|
+
// +++ MCP Client Factory +++
|
|
271
|
+
private readonly createMCPClientImpl?: CreateMCPClientFunction;
|
|
272
|
+
// --- MCP Client Factory ---
|
|
273
|
+
|
|
223
274
|
constructor(params?: CopilotRuntimeConstructorParams<T>) {
|
|
224
275
|
if (
|
|
225
276
|
params?.actions &&
|
|
@@ -243,7 +294,98 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
243
294
|
this.delegateAgentProcessingToServiceAdapter =
|
|
244
295
|
params?.delegateAgentProcessingToServiceAdapter || false;
|
|
245
296
|
this.observability = params?.observability_c;
|
|
297
|
+
|
|
298
|
+
// +++ MCP Initialization +++
|
|
299
|
+
this.mcpEndpointsConfig = params?.mcpEndpoints;
|
|
300
|
+
this.createMCPClientImpl = params?.createMCPClient;
|
|
301
|
+
|
|
302
|
+
// Validate: If mcpEndpoints are provided, createMCPClient must also be provided
|
|
303
|
+
if (
|
|
304
|
+
this.mcpEndpointsConfig &&
|
|
305
|
+
this.mcpEndpointsConfig.length > 0 &&
|
|
306
|
+
!this.createMCPClientImpl
|
|
307
|
+
) {
|
|
308
|
+
throw new CopilotKitMisuseError({
|
|
309
|
+
message:
|
|
310
|
+
"MCP Integration Error: `mcpEndpoints` were provided, but the `createMCPClient` function was not passed to the CopilotRuntime constructor. " +
|
|
311
|
+
"Please provide an implementation for `createMCPClient`.",
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Warning if actions are defined alongside LangGraph platform (potentially MCP too?)
|
|
316
|
+
if (
|
|
317
|
+
params?.actions &&
|
|
318
|
+
(params?.remoteEndpoints?.some((e) => e.type === EndpointType.LangGraphPlatform) ||
|
|
319
|
+
this.mcpEndpointsConfig?.length)
|
|
320
|
+
) {
|
|
321
|
+
console.warn(
|
|
322
|
+
"Local 'actions' defined in CopilotRuntime might not be available to remote agents (LangGraph, MCP). Consider defining actions closer to the agent implementation if needed.",
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// +++ MCP Instruction Injection Method +++
|
|
328
|
+
private injectMCPToolInstructions(
|
|
329
|
+
messages: MessageInput[],
|
|
330
|
+
currentActions: Action<any>[],
|
|
331
|
+
): MessageInput[] {
|
|
332
|
+
// Filter the *passed-in* actions for MCP tools
|
|
333
|
+
const mcpActionsForRequest = currentActions.filter((action) => (action as any)._isMCPTool);
|
|
334
|
+
|
|
335
|
+
if (!mcpActionsForRequest || mcpActionsForRequest.length === 0) {
|
|
336
|
+
return messages; // No MCP tools for this specific request
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Filter only MCP actions and format instructions
|
|
340
|
+
const mcpToolInstructions = mcpActionsForRequest
|
|
341
|
+
.map((action) => {
|
|
342
|
+
const paramsString =
|
|
343
|
+
action.parameters && action.parameters.length > 0
|
|
344
|
+
? ` Parameters: ${action.parameters
|
|
345
|
+
.map((p) => `${p.name}${p.required ? "*" : ""}(${p.type})`)
|
|
346
|
+
.join(", ")}`
|
|
347
|
+
: "";
|
|
348
|
+
return `- ${action.name}:${paramsString} ${action.description || ""}`;
|
|
349
|
+
})
|
|
350
|
+
.join("\n");
|
|
351
|
+
|
|
352
|
+
if (!mcpToolInstructions) {
|
|
353
|
+
return messages; // No MCP tools to describe
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const instructions =
|
|
357
|
+
"You have access to the following tools provided by external Model Context Protocol (MCP) servers:\n" +
|
|
358
|
+
mcpToolInstructions +
|
|
359
|
+
"\nUse them when appropriate to fulfill the user's request.";
|
|
360
|
+
|
|
361
|
+
const systemMessageIndex = messages.findIndex((msg) => msg.textMessage?.role === "system");
|
|
362
|
+
|
|
363
|
+
const newMessages = [...messages]; // Create a mutable copy
|
|
364
|
+
|
|
365
|
+
if (systemMessageIndex !== -1) {
|
|
366
|
+
const existingMsg = newMessages[systemMessageIndex];
|
|
367
|
+
if (existingMsg.textMessage) {
|
|
368
|
+
existingMsg.textMessage.content =
|
|
369
|
+
(existingMsg.textMessage.content ? existingMsg.textMessage.content + "\n\n" : "") +
|
|
370
|
+
instructions;
|
|
371
|
+
}
|
|
372
|
+
} else {
|
|
373
|
+
newMessages.unshift({
|
|
374
|
+
id: randomId(),
|
|
375
|
+
createdAt: new Date(),
|
|
376
|
+
textMessage: {
|
|
377
|
+
role: MessageRole.system,
|
|
378
|
+
content: instructions,
|
|
379
|
+
},
|
|
380
|
+
actionExecutionMessage: undefined,
|
|
381
|
+
resultMessage: undefined,
|
|
382
|
+
agentStateMessage: undefined,
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return newMessages;
|
|
246
387
|
}
|
|
388
|
+
// --- MCP Instruction Injection Method ---
|
|
247
389
|
|
|
248
390
|
async processRuntimeRequest(request: CopilotRuntimeRequest): Promise<CopilotRuntimeResponse> {
|
|
249
391
|
const {
|
|
@@ -280,9 +422,20 @@ please use an LLM adapter instead.`,
|
|
|
280
422
|
});
|
|
281
423
|
}
|
|
282
424
|
|
|
283
|
-
|
|
284
|
-
const inputMessages = convertGqlInputToMessages(messages);
|
|
425
|
+
// +++ Get Server Side Actions (including dynamic MCP) EARLY +++
|
|
285
426
|
const serverSideActions = await this.getServerSideActions(request);
|
|
427
|
+
// --- Get Server Side Actions (including dynamic MCP) EARLY ---
|
|
428
|
+
|
|
429
|
+
// Filter raw messages *before* injection
|
|
430
|
+
const filteredRawMessages = rawMessages.filter((message) => !message.agentStateMessage);
|
|
431
|
+
|
|
432
|
+
// +++ Inject MCP Instructions based on current actions +++
|
|
433
|
+
const messagesWithInjectedInstructions = this.injectMCPToolInstructions(
|
|
434
|
+
filteredRawMessages,
|
|
435
|
+
serverSideActions,
|
|
436
|
+
);
|
|
437
|
+
const inputMessages = convertGqlInputToMessages(messagesWithInjectedInstructions);
|
|
438
|
+
// --- Inject MCP Instructions based on current actions ---
|
|
286
439
|
|
|
287
440
|
// Log LLM request if logging is enabled
|
|
288
441
|
if (this.observability?.enabled && publicApiKey) {
|
|
@@ -913,10 +1066,11 @@ please use an LLM adapter instead.`,
|
|
|
913
1066
|
}
|
|
914
1067
|
|
|
915
1068
|
private async getServerSideActions(request: CopilotRuntimeRequest): Promise<Action<any>[]> {
|
|
916
|
-
const { messages: rawMessages,
|
|
1069
|
+
const { graphqlContext, messages: rawMessages, agentStates, url } = request;
|
|
1070
|
+
|
|
1071
|
+
// --- Standard Action Fetching (unchanged) ---
|
|
917
1072
|
const inputMessages = convertGqlInputToMessages(rawMessages);
|
|
918
1073
|
const langserveFunctions: Action<any>[] = [];
|
|
919
|
-
|
|
920
1074
|
for (const chainPromise of this.langserve) {
|
|
921
1075
|
try {
|
|
922
1076
|
const chain = await chainPromise;
|
|
@@ -927,11 +1081,7 @@ please use an LLM adapter instead.`,
|
|
|
927
1081
|
}
|
|
928
1082
|
|
|
929
1083
|
const remoteEndpointDefinitions = this.remoteEndpointDefinitions.map(
|
|
930
|
-
(endpoint) =>
|
|
931
|
-
({
|
|
932
|
-
...endpoint,
|
|
933
|
-
type: resolveEndpointType(endpoint),
|
|
934
|
-
}) as EndpointDefinition,
|
|
1084
|
+
(endpoint) => ({ ...endpoint, type: resolveEndpointType(endpoint) }) as EndpointDefinition,
|
|
935
1085
|
);
|
|
936
1086
|
|
|
937
1087
|
const remoteActions = await setupRemoteActions({
|
|
@@ -946,8 +1096,65 @@ please use an LLM adapter instead.`,
|
|
|
946
1096
|
typeof this.actions === "function"
|
|
947
1097
|
? this.actions({ properties: graphqlContext.properties, url })
|
|
948
1098
|
: this.actions;
|
|
1099
|
+
// --- Standard Action Fetching (unchanged) ---
|
|
1100
|
+
|
|
1101
|
+
// +++ Dynamic MCP Action Fetching +++
|
|
1102
|
+
const requestSpecificMCPActions: Action<any>[] = [];
|
|
1103
|
+
if (this.createMCPClientImpl) {
|
|
1104
|
+
// 1. Determine effective MCP endpoints for this request
|
|
1105
|
+
const baseEndpoints = this.mcpEndpointsConfig || [];
|
|
1106
|
+
// Assuming frontend passes config via properties.mcpEndpoints
|
|
1107
|
+
const requestEndpoints = (graphqlContext.properties?.mcpEndpoints ||
|
|
1108
|
+
[]) as MCPEndpointConfig[];
|
|
1109
|
+
|
|
1110
|
+
// Merge and deduplicate endpoints based on URL
|
|
1111
|
+
const effectiveEndpointsMap = new Map<string, MCPEndpointConfig>();
|
|
1112
|
+
[...baseEndpoints, ...requestEndpoints].forEach((ep) => {
|
|
1113
|
+
if (ep && ep.endpoint) {
|
|
1114
|
+
// Basic validation
|
|
1115
|
+
effectiveEndpointsMap.set(ep.endpoint, ep);
|
|
1116
|
+
}
|
|
1117
|
+
});
|
|
1118
|
+
const effectiveEndpoints = Array.from(effectiveEndpointsMap.values());
|
|
949
1119
|
|
|
950
|
-
|
|
1120
|
+
// 2. Fetch/Cache actions for effective endpoints
|
|
1121
|
+
for (const config of effectiveEndpoints) {
|
|
1122
|
+
const endpointUrl = config.endpoint;
|
|
1123
|
+
let actionsForEndpoint: Action<any>[] | undefined = this.mcpActionCache.get(endpointUrl);
|
|
1124
|
+
|
|
1125
|
+
if (!actionsForEndpoint) {
|
|
1126
|
+
// Not cached, fetch now
|
|
1127
|
+
let client: MCPClient | null = null;
|
|
1128
|
+
try {
|
|
1129
|
+
console.log(`MCP: Cache miss. Fetching tools for endpoint: ${endpointUrl}`);
|
|
1130
|
+
client = await this.createMCPClientImpl(config);
|
|
1131
|
+
const tools = await client.tools();
|
|
1132
|
+
actionsForEndpoint = convertMCPToolsToActions(tools, endpointUrl);
|
|
1133
|
+
this.mcpActionCache.set(endpointUrl, actionsForEndpoint); // Store in cache
|
|
1134
|
+
console.log(
|
|
1135
|
+
`MCP: Fetched and cached ${actionsForEndpoint.length} tools for ${endpointUrl}`,
|
|
1136
|
+
);
|
|
1137
|
+
} catch (error) {
|
|
1138
|
+
console.error(
|
|
1139
|
+
`MCP: Failed to fetch tools from endpoint ${endpointUrl}. Skipping. Error:`,
|
|
1140
|
+
error,
|
|
1141
|
+
);
|
|
1142
|
+
actionsForEndpoint = []; // Assign empty array on error to prevent re-fetching constantly
|
|
1143
|
+
this.mcpActionCache.set(endpointUrl, actionsForEndpoint); // Cache the failure (empty array)
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
requestSpecificMCPActions.push(...(actionsForEndpoint || []));
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
// --- Dynamic MCP Action Fetching ---
|
|
1150
|
+
|
|
1151
|
+
// Combine all action sources, including the dynamically fetched MCP actions
|
|
1152
|
+
return [
|
|
1153
|
+
...configuredActions,
|
|
1154
|
+
...langserveFunctions,
|
|
1155
|
+
...remoteActions,
|
|
1156
|
+
...requestSpecificMCPActions,
|
|
1157
|
+
];
|
|
951
1158
|
}
|
|
952
1159
|
|
|
953
1160
|
// Add helper method to detect provider
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Action, Parameter } from "@copilotkit/shared";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a tool provided by an MCP server.
|
|
5
|
+
*/
|
|
6
|
+
export interface MCPTool {
|
|
7
|
+
description?: string;
|
|
8
|
+
/** Schema defining parameters, mirroring the MCP structure. */
|
|
9
|
+
schema?: {
|
|
10
|
+
parameters?: {
|
|
11
|
+
properties?: Record<string, any>;
|
|
12
|
+
required?: string[];
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
/** The function to call to execute the tool on the MCP server. */
|
|
16
|
+
execute(options: { params: any }): Promise<any>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Defines the contract for *any* MCP client implementation the user might provide.
|
|
21
|
+
*/
|
|
22
|
+
export interface MCPClient {
|
|
23
|
+
/** A method that returns a map of tool names to MCPTool objects available from the connected MCP server. */
|
|
24
|
+
tools(): Promise<Record<string, MCPTool>>;
|
|
25
|
+
/** An optional method for cleanup if the underlying client requires explicit disconnection. */
|
|
26
|
+
close?(): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Configuration for connecting to an MCP endpoint.
|
|
31
|
+
*/
|
|
32
|
+
export interface MCPEndpointConfig {
|
|
33
|
+
endpoint: string;
|
|
34
|
+
apiKey?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Extracts CopilotKit-compatible parameters from an MCP tool schema.
|
|
39
|
+
* @param toolSchema The schema object from an MCPTool.
|
|
40
|
+
* @returns An array of Parameter objects.
|
|
41
|
+
*/
|
|
42
|
+
export function extractParametersFromSchema(toolSchema?: MCPTool["schema"]): Parameter[] {
|
|
43
|
+
const parameters: Parameter[] = [];
|
|
44
|
+
const properties = toolSchema?.parameters?.properties;
|
|
45
|
+
const requiredParams = new Set(toolSchema?.parameters?.required || []);
|
|
46
|
+
|
|
47
|
+
if (!properties) {
|
|
48
|
+
return parameters;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
for (const paramName in properties) {
|
|
52
|
+
if (Object.prototype.hasOwnProperty.call(properties, paramName)) {
|
|
53
|
+
const paramDef = properties[paramName];
|
|
54
|
+
parameters.push({
|
|
55
|
+
name: paramName,
|
|
56
|
+
// Infer type, default to string. MCP schemas might have more complex types.
|
|
57
|
+
// This might need refinement based on common MCP schema practices.
|
|
58
|
+
type: paramDef.type || "string",
|
|
59
|
+
description: paramDef.description,
|
|
60
|
+
required: requiredParams.has(paramName),
|
|
61
|
+
// Attributes might not directly map, handle if necessary
|
|
62
|
+
// attributes: paramDef.attributes || undefined,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return parameters;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Converts a map of MCPTools into an array of CopilotKit Actions.
|
|
72
|
+
* @param mcpTools A record mapping tool names to MCPTool objects.
|
|
73
|
+
* @param mcpEndpoint The endpoint URL from which these tools were fetched.
|
|
74
|
+
* @returns An array of Action<any> objects.
|
|
75
|
+
*/
|
|
76
|
+
export function convertMCPToolsToActions(
|
|
77
|
+
mcpTools: Record<string, MCPTool>,
|
|
78
|
+
mcpEndpoint: string,
|
|
79
|
+
): Action<any>[] {
|
|
80
|
+
const actions: Action<any>[] = [];
|
|
81
|
+
|
|
82
|
+
for (const [toolName, tool] of Object.entries(mcpTools)) {
|
|
83
|
+
const parameters = extractParametersFromSchema(tool.schema);
|
|
84
|
+
|
|
85
|
+
const handler = async (params: any): Promise<any> => {
|
|
86
|
+
try {
|
|
87
|
+
const result = await tool.execute({ params });
|
|
88
|
+
// Ensure the result is a string or stringify it, as required by many LLMs.
|
|
89
|
+
// This might need adjustment depending on how different LLMs handle tool results.
|
|
90
|
+
return typeof result === "string" ? result : JSON.stringify(result);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error(
|
|
93
|
+
`Error executing MCP tool '${toolName}' from endpoint ${mcpEndpoint}:`,
|
|
94
|
+
error,
|
|
95
|
+
);
|
|
96
|
+
// Re-throw or format the error for the LLM
|
|
97
|
+
throw new Error(
|
|
98
|
+
`Execution failed for MCP tool '${toolName}': ${
|
|
99
|
+
error instanceof Error ? error.message : String(error)
|
|
100
|
+
}`,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
actions.push({
|
|
106
|
+
name: toolName,
|
|
107
|
+
description: tool.description || `MCP tool: ${toolName} (from ${mcpEndpoint})`,
|
|
108
|
+
parameters: parameters,
|
|
109
|
+
handler: handler,
|
|
110
|
+
// Add metadata for easier identification/debugging
|
|
111
|
+
_isMCPTool: true,
|
|
112
|
+
_mcpEndpoint: mcpEndpoint,
|
|
113
|
+
} as Action<any> & { _isMCPTool: boolean; _mcpEndpoint: string }); // Type assertion for metadata
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return actions;
|
|
117
|
+
}
|