@copilotkit/runtime 1.50.0-beta.0 → 1.50.0-beta.10
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 +74 -0
- package/dist/chunk-2OZAGFV3.mjs +43 -0
- package/dist/chunk-2OZAGFV3.mjs.map +1 -0
- package/dist/chunk-62NE5S6M.mjs +226 -0
- package/dist/chunk-62NE5S6M.mjs.map +1 -0
- package/dist/chunk-6XRUR5UK.mjs +1 -0
- package/dist/chunk-6XRUR5UK.mjs.map +1 -0
- package/dist/chunk-AMUJQ6IR.mjs +50 -0
- package/dist/chunk-AMUJQ6IR.mjs.map +1 -0
- package/dist/chunk-BJEYMRDD.mjs +25 -0
- package/dist/chunk-BJEYMRDD.mjs.map +1 -0
- package/dist/chunk-DZV4ZIAR.mjs +3063 -0
- package/dist/chunk-DZV4ZIAR.mjs.map +1 -0
- package/dist/chunk-FHD4JECV.mjs +33 -0
- package/dist/chunk-FHD4JECV.mjs.map +1 -0
- package/dist/chunk-FMU55SEU.mjs +25 -0
- package/dist/chunk-FMU55SEU.mjs.map +1 -0
- package/dist/chunk-OWIGJONH.mjs +275 -0
- package/dist/chunk-OWIGJONH.mjs.map +1 -0
- package/dist/chunk-SBCOROE4.mjs +1112 -0
- package/dist/chunk-SBCOROE4.mjs.map +1 -0
- package/dist/chunk-TTUAEJLD.mjs +617 -0
- package/dist/chunk-TTUAEJLD.mjs.map +1 -0
- package/dist/chunk-XWBDEXDA.mjs +153 -0
- package/dist/chunk-XWBDEXDA.mjs.map +1 -0
- package/dist/chunk-Z752VE75.mjs +74 -0
- package/dist/chunk-Z752VE75.mjs.map +1 -0
- package/dist/graphql/message-conversion/index.d.ts +18 -0
- package/dist/graphql/message-conversion/index.js +725 -0
- package/dist/graphql/message-conversion/index.js.map +1 -0
- package/dist/graphql/message-conversion/index.mjs +245 -0
- package/dist/graphql/message-conversion/index.mjs.map +1 -0
- package/dist/graphql/types/base/index.d.ts +6 -0
- package/dist/graphql/types/base/index.js +63 -0
- package/dist/graphql/types/base/index.js.map +1 -0
- package/dist/graphql/types/base/index.mjs +8 -0
- package/dist/graphql/types/base/index.mjs.map +1 -0
- package/dist/graphql/types/converted/index.d.ts +2 -0
- package/dist/graphql/types/converted/index.js +294 -0
- package/dist/graphql/types/converted/index.js.map +1 -0
- package/dist/graphql/types/converted/index.mjs +20 -0
- package/dist/graphql/types/converted/index.mjs.map +1 -0
- package/dist/groq-adapter-50bc6e4a.d.ts +326 -0
- package/dist/index-adbd78f1.d.ts +154 -0
- package/dist/index.d.ts +136 -287
- package/dist/index.js +393 -287
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +385 -276
- package/dist/index.mjs.map +1 -1
- package/dist/langgraph.d.ts +284 -0
- package/dist/langgraph.js +211 -0
- package/dist/langgraph.js.map +1 -0
- package/dist/langgraph.mjs +206 -0
- package/dist/langgraph.mjs.map +1 -0
- package/dist/langserve-74a52292.d.ts +242 -0
- package/dist/lib/cloud/index.d.ts +6 -0
- package/dist/lib/cloud/index.js +18 -0
- package/dist/lib/cloud/index.js.map +1 -0
- package/dist/lib/cloud/index.mjs +1 -0
- package/dist/lib/cloud/index.mjs.map +1 -0
- package/dist/lib/index.d.ts +266 -0
- package/dist/lib/index.js +4944 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/index.mjs +74 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/integrations/index.d.ts +28 -0
- package/dist/lib/integrations/index.js +3024 -0
- package/dist/lib/integrations/index.js.map +1 -0
- package/dist/lib/integrations/index.mjs +36 -0
- package/dist/lib/integrations/index.mjs.map +1 -0
- package/dist/lib/integrations/nest/index.d.ts +16 -0
- package/dist/lib/integrations/nest/index.js +2937 -0
- package/dist/lib/integrations/nest/index.js.map +1 -0
- package/dist/lib/integrations/nest/index.mjs +13 -0
- package/dist/lib/integrations/nest/index.mjs.map +1 -0
- package/dist/lib/integrations/node-express/index.d.ts +16 -0
- package/dist/lib/integrations/node-express/index.js +2937 -0
- package/dist/lib/integrations/node-express/index.js.map +1 -0
- package/dist/lib/integrations/node-express/index.mjs +13 -0
- package/dist/lib/integrations/node-express/index.mjs.map +1 -0
- package/dist/lib/integrations/node-http/index.d.ts +16 -0
- package/dist/lib/integrations/node-http/index.js +2923 -0
- package/dist/lib/integrations/node-http/index.js.map +1 -0
- package/dist/lib/integrations/node-http/index.mjs +12 -0
- package/dist/lib/integrations/node-http/index.mjs.map +1 -0
- package/dist/service-adapters/index.d.ts +166 -0
- package/dist/service-adapters/index.js +1800 -0
- package/dist/service-adapters/index.js.map +1 -0
- package/dist/service-adapters/index.mjs +36 -0
- package/dist/service-adapters/index.mjs.map +1 -0
- package/dist/service-adapters/shared/index.d.ts +9 -0
- package/dist/service-adapters/shared/index.js +72 -0
- package/dist/service-adapters/shared/index.js.map +1 -0
- package/dist/service-adapters/shared/index.mjs +8 -0
- package/dist/service-adapters/shared/index.mjs.map +1 -0
- package/dist/shared-f6d43ef8.d.ts +446 -0
- package/dist/utils/index.d.ts +65 -0
- package/dist/utils/index.js +175 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +12 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/v2/index.d.ts +1 -0
- package/dist/v2/index.js +7 -0
- package/dist/v2/index.js.map +1 -1
- package/dist/v2/index.mjs +1 -0
- package/dist/v2/index.mjs.map +1 -1
- package/package.json +71 -33
- package/src/graphql/message-conversion/agui-to-gql.test.ts +2 -2
- package/src/graphql/message-conversion/gql-to-agui.test.ts +30 -28
- package/src/graphql/message-conversion/roundtrip-conversion.test.ts +8 -8
- package/src/langgraph.ts +1 -0
- package/src/lib/index.ts +42 -1
- package/src/lib/integrations/nextjs/app-router.ts +3 -1
- package/src/lib/integrations/node-http/index.ts +132 -11
- package/src/lib/integrations/shared.ts +2 -2
- package/src/lib/runtime/agent-integrations/{langgraph.agent.ts → langgraph/agent.ts} +5 -30
- package/src/lib/runtime/agent-integrations/langgraph/consts.ts +34 -0
- package/src/lib/runtime/agent-integrations/langgraph/index.ts +2 -0
- package/src/lib/runtime/copilot-runtime.ts +51 -68
- package/src/lib/runtime/telemetry-agent-runner.ts +134 -0
- package/src/service-adapters/anthropic/anthropic-adapter.ts +16 -3
- package/src/service-adapters/bedrock/bedrock-adapter.ts +4 -1
- package/src/service-adapters/experimental/ollama/ollama-adapter.ts +2 -1
- package/src/service-adapters/google/google-genai-adapter.ts +9 -4
- package/src/service-adapters/groq/groq-adapter.ts +16 -3
- package/src/service-adapters/langchain/langchain-adapter.ts +5 -3
- package/src/service-adapters/langchain/langserve.ts +2 -1
- package/src/service-adapters/openai/openai-adapter.ts +17 -3
- package/src/service-adapters/openai/openai-assistant-adapter.ts +26 -11
- package/src/service-adapters/unify/unify-adapter.ts +3 -1
- package/src/v2/index.ts +1 -0
- package/tsup.config.ts +5 -2
|
@@ -4,6 +4,8 @@ import { createCopilotEndpointSingleRoute } from "@copilotkitnext/runtime";
|
|
|
4
4
|
import { IncomingMessage, ServerResponse } from "http";
|
|
5
5
|
import { Readable } from "node:stream";
|
|
6
6
|
|
|
7
|
+
type IncomingWithBody = IncomingMessage & { body?: unknown; complete?: boolean };
|
|
8
|
+
|
|
7
9
|
export function readableStreamToNodeStream(webStream: ReadableStream): Readable {
|
|
8
10
|
const reader = webStream.getReader();
|
|
9
11
|
|
|
@@ -24,7 +26,10 @@ export function readableStreamToNodeStream(webStream: ReadableStream): Readable
|
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
function getFullUrl(req: IncomingMessage): string {
|
|
27
|
-
const
|
|
29
|
+
const expressPath =
|
|
30
|
+
(req as any).originalUrl ??
|
|
31
|
+
((req as any).baseUrl ? `${(req as any).baseUrl}${req.url ?? ""}` : undefined);
|
|
32
|
+
const path = expressPath || req.url || "/";
|
|
28
33
|
const host =
|
|
29
34
|
(req.headers["x-forwarded-host"] as string) || (req.headers.host as string) || "localhost";
|
|
30
35
|
const proto =
|
|
@@ -34,6 +39,61 @@ function getFullUrl(req: IncomingMessage): string {
|
|
|
34
39
|
return `${proto}://${host}${path}`;
|
|
35
40
|
}
|
|
36
41
|
|
|
42
|
+
function toHeaders(rawHeaders: IncomingMessage["headers"]): Headers {
|
|
43
|
+
const headers = new Headers();
|
|
44
|
+
|
|
45
|
+
for (const [key, value] of Object.entries(rawHeaders)) {
|
|
46
|
+
if (value === undefined) continue;
|
|
47
|
+
|
|
48
|
+
if (Array.isArray(value)) {
|
|
49
|
+
value.forEach((entry) => headers.append(key, entry));
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
headers.append(key, value);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return headers;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function isStreamConsumed(req: IncomingWithBody): boolean {
|
|
60
|
+
const readableState = (req as any)._readableState;
|
|
61
|
+
|
|
62
|
+
return Boolean(
|
|
63
|
+
req.readableEnded || req.complete || readableState?.ended || readableState?.endEmitted,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function synthesizeBodyFromParsedBody(
|
|
68
|
+
parsedBody: unknown,
|
|
69
|
+
headers: Headers,
|
|
70
|
+
): { body: BodyInit | null; contentType?: string } {
|
|
71
|
+
if (parsedBody === null || parsedBody === undefined) {
|
|
72
|
+
return { body: null };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (parsedBody instanceof Buffer || parsedBody instanceof Uint8Array) {
|
|
76
|
+
return { body: parsedBody };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (typeof parsedBody === "string") {
|
|
80
|
+
return { body: parsedBody, contentType: headers.get("content-type") ?? "text/plain" };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
body: JSON.stringify(parsedBody),
|
|
85
|
+
contentType: "application/json",
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function isDisturbedOrLockedError(error: unknown): boolean {
|
|
90
|
+
return (
|
|
91
|
+
error instanceof TypeError &&
|
|
92
|
+
typeof error.message === "string" &&
|
|
93
|
+
(error.message.includes("disturbed") || error.message.includes("locked"))
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
37
97
|
export function copilotRuntimeNodeHttpEndpoint(options: CreateCopilotRuntimeServerOptions) {
|
|
38
98
|
const commonConfig = getCommonConfig(options);
|
|
39
99
|
|
|
@@ -55,26 +115,87 @@ export function copilotRuntimeNodeHttpEndpoint(options: CreateCopilotRuntimeServ
|
|
|
55
115
|
logger.debug("Creating Node HTTP endpoint");
|
|
56
116
|
|
|
57
117
|
const serviceAdapter = options.serviceAdapter;
|
|
58
|
-
|
|
118
|
+
if (serviceAdapter) {
|
|
119
|
+
options.runtime.handleServiceAdapter(serviceAdapter);
|
|
120
|
+
}
|
|
59
121
|
|
|
60
122
|
const honoApp = createCopilotEndpointSingleRoute({
|
|
61
123
|
runtime: options.runtime.instance,
|
|
62
124
|
basePath: options.baseUrl ?? options.endpoint,
|
|
63
125
|
});
|
|
64
126
|
|
|
65
|
-
return async function handler(req:
|
|
127
|
+
return async function handler(req: IncomingWithBody, res: ServerResponse) {
|
|
66
128
|
const url = getFullUrl(req);
|
|
67
129
|
const hasBody = req.method !== "GET" && req.method !== "HEAD";
|
|
68
130
|
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
duplex: hasBody ? "half" : undefined,
|
|
75
|
-
} as any);
|
|
131
|
+
const baseHeaders = toHeaders(req.headers);
|
|
132
|
+
const parsedBody = req.body;
|
|
133
|
+
|
|
134
|
+
const streamConsumed = isStreamConsumed(req) || parsedBody !== undefined;
|
|
135
|
+
const canStream = hasBody && !streamConsumed;
|
|
76
136
|
|
|
77
|
-
|
|
137
|
+
let requestBody: BodyInit | null | undefined = undefined;
|
|
138
|
+
let useDuplex = false;
|
|
139
|
+
|
|
140
|
+
if (hasBody && canStream) {
|
|
141
|
+
requestBody = req as unknown as BodyInit;
|
|
142
|
+
useDuplex = true;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (hasBody && streamConsumed) {
|
|
146
|
+
if (parsedBody !== undefined) {
|
|
147
|
+
const synthesized = synthesizeBodyFromParsedBody(parsedBody, baseHeaders);
|
|
148
|
+
requestBody = synthesized.body ?? undefined;
|
|
149
|
+
baseHeaders.delete("content-length");
|
|
150
|
+
|
|
151
|
+
if (synthesized.contentType) {
|
|
152
|
+
baseHeaders.set("content-type", synthesized.contentType);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
logger.debug("Request stream already consumed; using parsed req.body to rebuild request.");
|
|
156
|
+
} else {
|
|
157
|
+
logger.warn("Request stream consumed with no available body; sending empty payload.");
|
|
158
|
+
requestBody = undefined;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const buildRequest = (body: BodyInit | null | undefined, headers: Headers, duplex: boolean) =>
|
|
163
|
+
new Request(url, {
|
|
164
|
+
method: req.method,
|
|
165
|
+
headers,
|
|
166
|
+
body,
|
|
167
|
+
duplex: duplex ? "half" : undefined,
|
|
168
|
+
} as RequestInit);
|
|
169
|
+
|
|
170
|
+
let response: Response;
|
|
171
|
+
try {
|
|
172
|
+
response = await honoApp.fetch(buildRequest(requestBody, baseHeaders, useDuplex));
|
|
173
|
+
} catch (error) {
|
|
174
|
+
if (isDisturbedOrLockedError(error) && hasBody) {
|
|
175
|
+
logger.warn(
|
|
176
|
+
"Encountered disturbed/locked request body; rebuilding request using parsed body or empty payload.",
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
const fallbackHeaders = new Headers(baseHeaders);
|
|
180
|
+
let fallbackBody: BodyInit | null | undefined;
|
|
181
|
+
|
|
182
|
+
if (parsedBody !== undefined) {
|
|
183
|
+
const synthesized = synthesizeBodyFromParsedBody(parsedBody, fallbackHeaders);
|
|
184
|
+
fallbackBody = synthesized.body ?? undefined;
|
|
185
|
+
fallbackHeaders.delete("content-length");
|
|
186
|
+
|
|
187
|
+
if (synthesized.contentType) {
|
|
188
|
+
fallbackHeaders.set("content-type", synthesized.contentType);
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
fallbackBody = undefined;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
response = await honoApp.fetch(buildRequest(fallbackBody, fallbackHeaders, false));
|
|
195
|
+
} else {
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
78
199
|
|
|
79
200
|
res.statusCode = response.status;
|
|
80
201
|
response.headers.forEach((value, key) => {
|
|
@@ -34,8 +34,8 @@ export type GraphQLContext = YogaInitialContext & {
|
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
export interface CreateCopilotRuntimeServerOptions {
|
|
37
|
-
runtime: CopilotRuntime
|
|
38
|
-
serviceAdapter
|
|
37
|
+
runtime: CopilotRuntime<any>;
|
|
38
|
+
serviceAdapter?: CopilotServiceAdapter;
|
|
39
39
|
endpoint: string;
|
|
40
40
|
baseUrl?: string;
|
|
41
41
|
cloud?: CopilotCloudOptions;
|
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
RunAgentInput,
|
|
3
|
-
EventType,
|
|
4
|
-
CustomEvent,
|
|
5
|
-
TextMessageStartEvent,
|
|
6
|
-
TextMessageContentEvent,
|
|
7
|
-
TextMessageEndEvent,
|
|
8
|
-
ToolCallStartEvent,
|
|
9
|
-
ToolCallArgsEvent,
|
|
10
|
-
ToolCallEndEvent,
|
|
11
|
-
} from "@ag-ui/client";
|
|
12
1
|
import { map } from "rxjs";
|
|
13
|
-
import { LangGraphEventTypes } from "
|
|
2
|
+
import { LangGraphEventTypes } from "../../../../agents/langgraph/events";
|
|
14
3
|
import { RawEvent } from "@ag-ui/core";
|
|
15
4
|
import {
|
|
16
5
|
LangGraphAgent as AGUILangGraphAgent,
|
|
@@ -31,25 +20,11 @@ interface CopilotKitStateEnrichment {
|
|
|
31
20
|
};
|
|
32
21
|
}
|
|
33
22
|
|
|
34
|
-
|
|
35
|
-
tool: string;
|
|
36
|
-
state_key: string;
|
|
37
|
-
tool_argument: string;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export type TextMessageEvents =
|
|
41
|
-
| TextMessageStartEvent
|
|
42
|
-
| TextMessageContentEvent
|
|
43
|
-
| TextMessageEndEvent;
|
|
23
|
+
import { RunAgentInput, EventType, CustomEvent } from "@ag-ui/client";
|
|
44
24
|
|
|
45
|
-
export
|
|
46
|
-
|
|
47
|
-
export
|
|
48
|
-
CopilotKitManuallyEmitMessage = "copilotkit_manually_emit_message",
|
|
49
|
-
CopilotKitManuallyEmitToolCall = "copilotkit_manually_emit_tool_call",
|
|
50
|
-
CopilotKitManuallyEmitIntermediateState = "copilotkit_manually_emit_intermediate_state",
|
|
51
|
-
CopilotKitExit = "copilotkit_exit",
|
|
52
|
-
}
|
|
25
|
+
// Import and re-export from separate file to maintain API compatibility
|
|
26
|
+
import { CustomEventNames, TextMessageEvents, ToolCallEvents, PredictStateTool } from "./consts";
|
|
27
|
+
export { CustomEventNames };
|
|
53
28
|
|
|
54
29
|
export class LangGraphAgent extends AGUILangGraphAgent {
|
|
55
30
|
constructor(config: LangGraphAgentConfig) {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for LangGraph integration.
|
|
3
|
+
* This file is separate from langgraph.agent.ts to avoid pulling in @ag-ui/langgraph
|
|
4
|
+
* when only these constants are needed.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
TextMessageStartEvent,
|
|
9
|
+
TextMessageContentEvent,
|
|
10
|
+
TextMessageEndEvent,
|
|
11
|
+
ToolCallStartEvent,
|
|
12
|
+
ToolCallArgsEvent,
|
|
13
|
+
ToolCallEndEvent,
|
|
14
|
+
} from "@ag-ui/client";
|
|
15
|
+
|
|
16
|
+
export type TextMessageEvents =
|
|
17
|
+
| TextMessageStartEvent
|
|
18
|
+
| TextMessageContentEvent
|
|
19
|
+
| TextMessageEndEvent;
|
|
20
|
+
|
|
21
|
+
export type ToolCallEvents = ToolCallStartEvent | ToolCallArgsEvent | ToolCallEndEvent;
|
|
22
|
+
|
|
23
|
+
export enum CustomEventNames {
|
|
24
|
+
CopilotKitManuallyEmitMessage = "copilotkit_manually_emit_message",
|
|
25
|
+
CopilotKitManuallyEmitToolCall = "copilotkit_manually_emit_tool_call",
|
|
26
|
+
CopilotKitManuallyEmitIntermediateState = "copilotkit_manually_emit_intermediate_state",
|
|
27
|
+
CopilotKitExit = "copilotkit_exit",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface PredictStateTool {
|
|
31
|
+
tool: string;
|
|
32
|
+
state_key: string;
|
|
33
|
+
tool_argument: string;
|
|
34
|
+
}
|
|
@@ -13,65 +13,47 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import {
|
|
16
|
-
Action,
|
|
17
|
-
CopilotErrorHandler,
|
|
16
|
+
type Action,
|
|
17
|
+
type CopilotErrorHandler,
|
|
18
18
|
CopilotKitMisuseError,
|
|
19
|
-
MaybePromise,
|
|
20
|
-
NonEmptyRecord,
|
|
21
|
-
Parameter,
|
|
19
|
+
type MaybePromise,
|
|
20
|
+
type NonEmptyRecord,
|
|
21
|
+
type Parameter,
|
|
22
22
|
readBody,
|
|
23
23
|
getZodParameters,
|
|
24
|
-
PartialBy,
|
|
24
|
+
type PartialBy,
|
|
25
25
|
} from "@copilotkit/shared";
|
|
26
|
-
import {
|
|
26
|
+
import type { RunAgentInput } from "@ag-ui/core";
|
|
27
27
|
import { aguiToGQL } from "../../graphql/message-conversion/agui-to-gql";
|
|
28
|
-
import { CopilotServiceAdapter, RemoteChainParameters } from "../../service-adapters";
|
|
28
|
+
import type { CopilotServiceAdapter, RemoteChainParameters } from "../../service-adapters";
|
|
29
29
|
import {
|
|
30
30
|
CopilotRuntime as CopilotRuntimeVNext,
|
|
31
|
-
CopilotRuntimeOptions,
|
|
32
|
-
CopilotRuntimeOptions as CopilotRuntimeOptionsVNext,
|
|
33
|
-
InMemoryAgentRunner as InMemoryAgentRunnerVNext,
|
|
31
|
+
type CopilotRuntimeOptions,
|
|
32
|
+
type CopilotRuntimeOptions as CopilotRuntimeOptionsVNext,
|
|
34
33
|
} from "@copilotkitnext/runtime";
|
|
34
|
+
import { TelemetryAgentRunner } from "./telemetry-agent-runner";
|
|
35
35
|
|
|
36
|
-
import { MessageInput } from "../../graphql/inputs/message.input";
|
|
37
|
-
import {
|
|
38
|
-
import { RuntimeEventSource } from "../../service-adapters/events";
|
|
39
|
-
import { Message } from "../../graphql/types/converted";
|
|
40
|
-
import { ForwardedParametersInput } from "../../graphql/inputs/forwarded-parameters.input";
|
|
36
|
+
import type { MessageInput } from "../../graphql/inputs/message.input";
|
|
37
|
+
import type { Message } from "../../graphql/types/converted";
|
|
41
38
|
|
|
42
39
|
import {
|
|
43
40
|
EndpointType,
|
|
44
|
-
EndpointDefinition,
|
|
45
|
-
CopilotKitEndpoint,
|
|
46
|
-
LangGraphPlatformEndpoint,
|
|
41
|
+
type EndpointDefinition,
|
|
42
|
+
type CopilotKitEndpoint,
|
|
43
|
+
type LangGraphPlatformEndpoint,
|
|
47
44
|
} from "./types";
|
|
48
45
|
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
51
|
-
import { AgentStateInput } from "../../graphql/inputs/agent-state.input";
|
|
52
|
-
import { Agent } from "../../graphql/types/agents-response.type";
|
|
53
|
-
import { ExtensionsInput } from "../../graphql/inputs/extensions.input";
|
|
54
|
-
import { ExtensionsResponse } from "../../graphql/types/extensions-response.type";
|
|
55
|
-
import { MetaEventInput } from "../../graphql/inputs/meta-event.input";
|
|
56
|
-
import {
|
|
57
|
-
CopilotObservabilityConfig,
|
|
58
|
-
LLMRequestData,
|
|
59
|
-
LLMResponseData,
|
|
60
|
-
LLMErrorData,
|
|
61
|
-
} from "../observability";
|
|
62
|
-
import { AbstractAgent } from "@ag-ui/client";
|
|
46
|
+
import type { CopilotObservabilityConfig, LLMRequestData, LLMResponseData } from "../observability";
|
|
47
|
+
import type { AbstractAgent } from "@ag-ui/client";
|
|
63
48
|
|
|
64
49
|
// +++ MCP Imports +++
|
|
65
50
|
import {
|
|
66
|
-
MCPClient,
|
|
67
|
-
MCPEndpointConfig,
|
|
68
|
-
MCPTool,
|
|
51
|
+
type MCPClient,
|
|
52
|
+
type MCPEndpointConfig,
|
|
53
|
+
type MCPTool,
|
|
69
54
|
extractParametersFromSchema,
|
|
70
|
-
convertMCPToolsToActions,
|
|
71
|
-
generateMcpToolInstructions,
|
|
72
55
|
} from "./mcp-tools-utils";
|
|
73
|
-
import {
|
|
74
|
-
import { BasicAgent, BasicAgentConfiguration } from "@copilotkitnext/agent";
|
|
56
|
+
import { BasicAgent, type BasicAgentConfiguration } from "@copilotkitnext/agent";
|
|
75
57
|
// Define the function type alias here or import if defined elsewhere
|
|
76
58
|
type CreateMCPClientFunction = (config: MCPEndpointConfig) => Promise<MCPClient>;
|
|
77
59
|
|
|
@@ -312,8 +294,8 @@ interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []>
|
|
|
312
294
|
/**
|
|
313
295
|
* Central runtime object passed to all request handlers.
|
|
314
296
|
*/
|
|
315
|
-
export class CopilotRuntime {
|
|
316
|
-
params?: CopilotRuntimeConstructorParams
|
|
297
|
+
export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
298
|
+
params?: CopilotRuntimeConstructorParams<T>;
|
|
317
299
|
private observability?: CopilotObservabilityConfig;
|
|
318
300
|
// Cache MCP tools per endpoint to avoid re-fetching repeatedly
|
|
319
301
|
private mcpToolsCache: Map<string, BasicAgentConfiguration["tools"]> = new Map();
|
|
@@ -321,12 +303,16 @@ export class CopilotRuntime {
|
|
|
321
303
|
private _instance: CopilotRuntimeVNext;
|
|
322
304
|
|
|
323
305
|
constructor(
|
|
324
|
-
params?: CopilotRuntimeConstructorParams & PartialBy<CopilotRuntimeOptions, "agents">,
|
|
306
|
+
params?: CopilotRuntimeConstructorParams<T> & PartialBy<CopilotRuntimeOptions, "agents">,
|
|
325
307
|
) {
|
|
326
308
|
const agents = params?.agents ?? {};
|
|
309
|
+
const endpointAgents = this.assignEndpointsToAgents(params?.remoteEndpoints ?? []);
|
|
310
|
+
|
|
327
311
|
this.runtimeArgs = {
|
|
328
|
-
agents: { ...
|
|
329
|
-
|
|
312
|
+
agents: { ...endpointAgents, ...agents },
|
|
313
|
+
// Use TelemetryAgentRunner by default to track agent execution telemetry
|
|
314
|
+
// Users can pass their own runner which will be wrapped for telemetry
|
|
315
|
+
runner: params?.runner ?? new TelemetryAgentRunner(),
|
|
330
316
|
// TODO: add support for transcriptionService from CopilotRuntimeOptionsVNext once it is ready
|
|
331
317
|
// transcriptionService: params?.transcriptionService,
|
|
332
318
|
|
|
@@ -345,28 +331,23 @@ export class CopilotRuntime {
|
|
|
345
331
|
return this._instance;
|
|
346
332
|
}
|
|
347
333
|
|
|
348
|
-
private assignEndpointsToAgents(
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
const lgEndpoint = endpoint as LangGraphPlatformEndpoint;
|
|
353
|
-
lgEndpoint.agents.forEach((agent) => {
|
|
354
|
-
const graphId = agent.assistantId ?? agent.name;
|
|
355
|
-
lgAgents[graphId] = new LangGraphAgent({
|
|
356
|
-
deploymentUrl: lgEndpoint.deploymentUrl,
|
|
357
|
-
langsmithApiKey: lgEndpoint.langsmithApiKey,
|
|
358
|
-
graphId,
|
|
359
|
-
});
|
|
360
|
-
});
|
|
334
|
+
private assignEndpointsToAgents(
|
|
335
|
+
endpoints: CopilotRuntimeConstructorParams<T>["remoteEndpoints"],
|
|
336
|
+
): Record<string, AbstractAgent> {
|
|
337
|
+
let result: Record<string, AbstractAgent> = {};
|
|
361
338
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
339
|
+
if (
|
|
340
|
+
endpoints.some((endpoint) => resolveEndpointType(endpoint) == EndpointType.LangGraphPlatform)
|
|
341
|
+
) {
|
|
342
|
+
throw new CopilotKitMisuseError({
|
|
343
|
+
message:
|
|
344
|
+
"LangGraphPlatformEndpoint in remoteEndpoints is deprecated. " +
|
|
345
|
+
'Please use the "agents" option instead with LangGraphAgent from "@copilotkit/runtime/langgraph". ' +
|
|
346
|
+
'Example: agents: { myAgent: new LangGraphAgent({ deploymentUrl: "...", graphId: "..." }) }',
|
|
347
|
+
});
|
|
348
|
+
}
|
|
367
349
|
|
|
368
|
-
|
|
369
|
-
}, {});
|
|
350
|
+
return result;
|
|
370
351
|
}
|
|
371
352
|
|
|
372
353
|
handleServiceAdapter(serviceAdapter: CopilotServiceAdapter) {
|
|
@@ -393,7 +374,7 @@ export class CopilotRuntime {
|
|
|
393
374
|
});
|
|
394
375
|
}
|
|
395
376
|
|
|
396
|
-
if (this.params.actions
|
|
377
|
+
if (this.params.actions) {
|
|
397
378
|
const mcpTools = await this.getToolsFromMCP();
|
|
398
379
|
agentsList = this.assignToolsToAgents(agents, [
|
|
399
380
|
...this.getToolsFromActions(this.params.actions),
|
|
@@ -423,6 +404,7 @@ export class CopilotRuntime {
|
|
|
423
404
|
name: action.name,
|
|
424
405
|
description: action.description || "",
|
|
425
406
|
parameters: zodSchema,
|
|
407
|
+
execute: () => Promise.resolve(),
|
|
426
408
|
};
|
|
427
409
|
});
|
|
428
410
|
}
|
|
@@ -454,7 +436,7 @@ export class CopilotRuntime {
|
|
|
454
436
|
}
|
|
455
437
|
|
|
456
438
|
private createOnBeforeRequestHandler(
|
|
457
|
-
params?: CopilotRuntimeConstructorParams & PartialBy<CopilotRuntimeOptions, "agents">,
|
|
439
|
+
params?: CopilotRuntimeConstructorParams<T> & PartialBy<CopilotRuntimeOptions, "agents">,
|
|
458
440
|
) {
|
|
459
441
|
return async (hookParams: BeforeRequestMiddlewareFnParameters[0]) => {
|
|
460
442
|
// TODO: get public api key and run with expected data
|
|
@@ -492,7 +474,7 @@ export class CopilotRuntime {
|
|
|
492
474
|
}
|
|
493
475
|
|
|
494
476
|
private createOnAfterRequestHandler(
|
|
495
|
-
params?: CopilotRuntimeConstructorParams & PartialBy<CopilotRuntimeOptions, "agents">,
|
|
477
|
+
params?: CopilotRuntimeConstructorParams<T> & PartialBy<CopilotRuntimeOptions, "agents">,
|
|
496
478
|
) {
|
|
497
479
|
return async (hookParams: AfterRequestMiddlewareFnParameters[0]) => {
|
|
498
480
|
// TODO: get public api key and run with expected data
|
|
@@ -636,6 +618,7 @@ export class CopilotRuntime {
|
|
|
636
618
|
name: toolName,
|
|
637
619
|
description: tool.description || `MCP tool: ${toolName} (from ${endpointUrl})`,
|
|
638
620
|
parameters: zodSchema,
|
|
621
|
+
execute: () => Promise.resolve(),
|
|
639
622
|
};
|
|
640
623
|
},
|
|
641
624
|
);
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TelemetryAgentRunner - A wrapper around AgentRunner that adds telemetry
|
|
3
|
+
* for agent execution streams.
|
|
4
|
+
*
|
|
5
|
+
* This captures the following telemetry events:
|
|
6
|
+
* - oss.runtime.agent_execution_stream_started - when an agent execution starts
|
|
7
|
+
* - oss.runtime.agent_execution_stream_ended - when an agent execution completes
|
|
8
|
+
* - oss.runtime.agent_execution_stream_errored - when an agent execution fails
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { type AgentRunner, InMemoryAgentRunner } from "@copilotkitnext/runtime";
|
|
12
|
+
import { createHash } from "node:crypto";
|
|
13
|
+
import { tap, catchError, finalize } from "rxjs";
|
|
14
|
+
import telemetry from "../telemetry-client";
|
|
15
|
+
import type { AgentExecutionResponseInfo } from "@copilotkit/shared/src/telemetry/events";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Configuration options for TelemetryAgentRunner
|
|
19
|
+
*/
|
|
20
|
+
export interface TelemetryAgentRunnerConfig {
|
|
21
|
+
/**
|
|
22
|
+
* The underlying runner to delegate to
|
|
23
|
+
* If not provided, defaults to InMemoryAgentRunner
|
|
24
|
+
*/
|
|
25
|
+
runner?: AgentRunner;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Optional LangSmith API key (will be hashed for telemetry)
|
|
29
|
+
*/
|
|
30
|
+
langsmithApiKey?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* An AgentRunner wrapper that adds telemetry tracking for agent executions.
|
|
35
|
+
*
|
|
36
|
+
* Usage:
|
|
37
|
+
* ```ts
|
|
38
|
+
* const runtime = new CopilotRuntime({
|
|
39
|
+
* runner: new TelemetryAgentRunner(),
|
|
40
|
+
* // or with custom runner:
|
|
41
|
+
* runner: new TelemetryAgentRunner({ runner: customRunner }),
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export class TelemetryAgentRunner implements AgentRunner {
|
|
46
|
+
private readonly _runner: AgentRunner;
|
|
47
|
+
private readonly hashedLgcKey: string | undefined;
|
|
48
|
+
|
|
49
|
+
constructor(config?: TelemetryAgentRunnerConfig) {
|
|
50
|
+
this._runner = config?.runner ?? new InMemoryAgentRunner();
|
|
51
|
+
this.hashedLgcKey = config?.langsmithApiKey
|
|
52
|
+
? createHash("sha256").update(config.langsmithApiKey).digest("hex")
|
|
53
|
+
: undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Runs an agent with telemetry tracking.
|
|
58
|
+
* Wraps the underlying runner's Observable stream with telemetry events.
|
|
59
|
+
*/
|
|
60
|
+
run(
|
|
61
|
+
...args: Parameters<AgentRunner["run"]>
|
|
62
|
+
): ReturnType<AgentRunner["run"]> {
|
|
63
|
+
const streamInfo: AgentExecutionResponseInfo = {
|
|
64
|
+
hashedLgcKey: this.hashedLgcKey,
|
|
65
|
+
};
|
|
66
|
+
let streamErrored = false;
|
|
67
|
+
|
|
68
|
+
// Capture stream started event
|
|
69
|
+
telemetry.capture("oss.runtime.agent_execution_stream_started", {
|
|
70
|
+
hashedLgcKey: this.hashedLgcKey,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Delegate to the underlying runner and wrap with telemetry
|
|
74
|
+
return this._runner.run(...args).pipe(
|
|
75
|
+
// Extract metadata from events if available
|
|
76
|
+
tap((event) => {
|
|
77
|
+
// Try to extract provider/model info from raw events
|
|
78
|
+
const rawEvent = (event as { rawEvent?: { metadata?: Record<string, unknown>; data?: Record<string, unknown> } }).rawEvent;
|
|
79
|
+
if (rawEvent?.data) {
|
|
80
|
+
const data = rawEvent.data as { output?: { model?: string } };
|
|
81
|
+
if (data?.output?.model) {
|
|
82
|
+
streamInfo.model = data.output.model;
|
|
83
|
+
streamInfo.provider = data.output.model;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (rawEvent?.metadata) {
|
|
87
|
+
const metadata = rawEvent.metadata as { langgraph_host?: string; langgraph_version?: string };
|
|
88
|
+
if (metadata?.langgraph_host) {
|
|
89
|
+
streamInfo.langGraphHost = metadata.langgraph_host;
|
|
90
|
+
}
|
|
91
|
+
if (metadata?.langgraph_version) {
|
|
92
|
+
streamInfo.langGraphVersion = metadata.langgraph_version;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}),
|
|
96
|
+
catchError((error) => {
|
|
97
|
+
// Capture stream error event
|
|
98
|
+
streamErrored = true;
|
|
99
|
+
telemetry.capture("oss.runtime.agent_execution_stream_errored", {
|
|
100
|
+
...streamInfo,
|
|
101
|
+
error: error instanceof Error ? error.message : String(error),
|
|
102
|
+
});
|
|
103
|
+
throw error;
|
|
104
|
+
}),
|
|
105
|
+
finalize(() => {
|
|
106
|
+
// Capture stream ended event (only if not errored)
|
|
107
|
+
if (!streamErrored) {
|
|
108
|
+
telemetry.capture("oss.runtime.agent_execution_stream_ended", streamInfo);
|
|
109
|
+
}
|
|
110
|
+
}),
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Delegates to the underlying runner's connect method
|
|
116
|
+
*/
|
|
117
|
+
connect(...args: Parameters<AgentRunner["connect"]>): ReturnType<AgentRunner["connect"]> {
|
|
118
|
+
return this._runner.connect(...args);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Delegates to the underlying runner's isRunning method
|
|
123
|
+
*/
|
|
124
|
+
isRunning(...args: Parameters<AgentRunner["isRunning"]>): ReturnType<AgentRunner["isRunning"]> {
|
|
125
|
+
return this._runner.isRunning(...args);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Delegates to the underlying runner's stop method
|
|
130
|
+
*/
|
|
131
|
+
stop(...args: Parameters<AgentRunner["stop"]>): ReturnType<AgentRunner["stop"]> {
|
|
132
|
+
return this._runner.stop(...args);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* });
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
import Anthropic from "@anthropic-ai/sdk";
|
|
25
|
+
import type Anthropic from "@anthropic-ai/sdk";
|
|
26
26
|
import {
|
|
27
27
|
CopilotServiceAdapter,
|
|
28
28
|
CopilotRuntimeChatCompletionRequest,
|
|
@@ -84,13 +84,25 @@ export class AnthropicAdapter implements CopilotServiceAdapter {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
constructor(params?: AnthropicAdapterParams) {
|
|
87
|
-
|
|
87
|
+
if (params?.anthropic) {
|
|
88
|
+
this._anthropic = params.anthropic;
|
|
89
|
+
}
|
|
90
|
+
// If no instance provided, we'll lazy-load in ensureAnthropic()
|
|
88
91
|
if (params?.model) {
|
|
89
92
|
this.model = params.model;
|
|
90
93
|
}
|
|
91
94
|
this.promptCaching = params?.promptCaching || { enabled: false };
|
|
92
95
|
}
|
|
93
96
|
|
|
97
|
+
private ensureAnthropic(): Anthropic {
|
|
98
|
+
if (!this._anthropic) {
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
100
|
+
const Anthropic = require("@anthropic-ai/sdk").default;
|
|
101
|
+
this._anthropic = new Anthropic({});
|
|
102
|
+
}
|
|
103
|
+
return this._anthropic;
|
|
104
|
+
}
|
|
105
|
+
|
|
94
106
|
/**
|
|
95
107
|
* Adds cache control to system prompt
|
|
96
108
|
*/
|
|
@@ -306,7 +318,8 @@ export class AnthropicAdapter implements CopilotServiceAdapter {
|
|
|
306
318
|
stream: true,
|
|
307
319
|
};
|
|
308
320
|
|
|
309
|
-
const
|
|
321
|
+
const anthropic = this.ensureAnthropic();
|
|
322
|
+
const stream = await anthropic.messages.create(createParams);
|
|
310
323
|
|
|
311
324
|
eventSource.stream(async (eventStream$) => {
|
|
312
325
|
let mode: "function" | "message" | null = null;
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import { ChatBedrockConverse } from "@langchain/aws";
|
|
23
22
|
import { LangChainAdapter } from "../langchain/langchain-adapter";
|
|
24
23
|
|
|
25
24
|
export interface BedrockAdapterParams {
|
|
@@ -52,6 +51,10 @@ export class BedrockAdapter extends LangChainAdapter {
|
|
|
52
51
|
constructor(options?: BedrockAdapterParams) {
|
|
53
52
|
super({
|
|
54
53
|
chainFn: async ({ messages, tools, threadId }) => {
|
|
54
|
+
// Lazy require for optional peer dependency
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
56
|
+
const { ChatBedrockConverse } = require("@langchain/aws");
|
|
57
|
+
|
|
55
58
|
this.model = options?.model ?? "amazon.nova-lite-v1:0";
|
|
56
59
|
const model = new ChatBedrockConverse({
|
|
57
60
|
model: this.model,
|