@copilotkit/runtime 1.3.16-mme-lgc-langgraph-package.11 → 1.3.16-mme-revert-rxjs-changes.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 +33 -95
- package/dist/{chunk-SMHGZXIT.mjs → chunk-3EIBEZQI.mjs} +4 -3
- package/dist/chunk-3EIBEZQI.mjs.map +1 -0
- package/dist/{chunk-TTVQTORT.mjs → chunk-4MX7GDLS.mjs} +4 -3
- package/dist/chunk-4MX7GDLS.mjs.map +1 -0
- package/dist/chunk-DFOKBSIS.mjs +1 -0
- package/dist/chunk-DFOKBSIS.mjs.map +1 -0
- package/dist/{chunk-HZ2XTQUC.mjs → chunk-UO2QXEDA.mjs} +5 -4
- package/dist/chunk-UO2QXEDA.mjs.map +1 -0
- package/dist/{chunk-BNQDVBQH.mjs → chunk-WHJ3DAYL.mjs} +251 -34
- package/dist/chunk-WHJ3DAYL.mjs.map +1 -0
- package/dist/{chunk-JTVWJUZP.mjs → chunk-YSCTOGKC.mjs} +419 -50
- package/dist/chunk-YSCTOGKC.mjs.map +1 -0
- package/dist/{copilot-runtime-8d3f40c7.d.ts → copilot-runtime-335a610d.d.ts} +10 -10
- package/dist/{groq-adapter-dbfba3eb.d.ts → groq-adapter-2f8fd767.d.ts} +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +215 -98
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -22
- package/dist/index.mjs.map +1 -1
- package/dist/{langserve-f00629d2.d.ts → langserve-cc06e76e.d.ts} +1 -0
- package/dist/lib/index.d.ts +3 -3
- package/dist/lib/index.js +215 -98
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +21 -21
- package/dist/lib/integrations/index.d.ts +3 -3
- package/dist/lib/integrations/index.js +153 -85
- 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 +2 -2
- package/dist/lib/integrations/nest/index.js +150 -82
- 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 +2 -2
- package/dist/lib/integrations/node-express/index.js +150 -82
- 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 +2 -2
- package/dist/lib/integrations/node-http/index.js +149 -81
- 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.d.ts +3 -3
- package/dist/service-adapters/index.js +31 -18
- package/dist/service-adapters/index.js.map +1 -1
- package/dist/service-adapters/index.mjs +1 -2
- package/package.json +4 -4
- package/src/agents/langgraph/event-source.ts +2 -2
- package/src/agents/langgraph/events.ts +2 -0
- package/src/lib/integrations/nest/index.ts +5 -2
- package/src/lib/integrations/nextjs/app-router.ts +5 -2
- package/src/lib/integrations/nextjs/pages-router.ts +5 -2
- package/src/lib/integrations/node-express/index.ts +5 -2
- package/src/lib/integrations/node-http/index.ts +5 -2
- package/src/lib/runtime/copilot-runtime.ts +53 -47
- package/src/lib/runtime/remote-action-constructors.ts +23 -9
- package/src/lib/runtime/remote-actions.ts +9 -9
- package/src/lib/runtime/{remote-lg-cloud-action.ts → remote-lg-action.ts} +59 -33
- package/src/lib/telemetry-client.ts +43 -0
- package/src/service-adapters/events.ts +13 -1
- package/src/service-adapters/google/google-genai-adapter.ts +2 -2
- package/src/service-adapters/langchain/langchain-adapter.ts +22 -16
- package/src/service-adapters/openai/openai-adapter.ts +5 -0
- package/dist/chunk-BNQDVBQH.mjs.map +0 -1
- package/dist/chunk-GWP2VADN.mjs +0 -288
- package/dist/chunk-GWP2VADN.mjs.map +0 -1
- package/dist/chunk-HZ2XTQUC.mjs.map +0 -1
- package/dist/chunk-JTVWJUZP.mjs.map +0 -1
- package/dist/chunk-MXXPWWBF.mjs +0 -218
- package/dist/chunk-MXXPWWBF.mjs.map +0 -1
- package/dist/chunk-SMHGZXIT.mjs.map +0 -1
- package/dist/chunk-TTVQTORT.mjs.map +0 -1
|
@@ -8,6 +8,8 @@ export enum LangGraphEventTypes {
|
|
|
8
8
|
OnToolStart = "on_tool_start",
|
|
9
9
|
OnToolEnd = "on_tool_end",
|
|
10
10
|
OnCopilotKitStateSync = "on_copilotkit_state_sync",
|
|
11
|
+
OnCopilotKitEmitMessage = "on_copilotkit_emit_message",
|
|
12
|
+
OnCopilotKitEmitToolCall = "on_copilotkit_emit_tool_call",
|
|
11
13
|
OnCustomEvent = "on_custom_event",
|
|
12
14
|
}
|
|
13
15
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CreateCopilotRuntimeServerOptions } from "../shared";
|
|
2
2
|
import { copilotRuntimeNodeHttpEndpoint } from "../node-http";
|
|
3
|
-
import telemetry from "../../telemetry-client";
|
|
3
|
+
import telemetry, { getRuntimeInstanceTelemetryInfo } from "../../telemetry-client";
|
|
4
4
|
|
|
5
5
|
export function copilotRuntimeNestEndpoint(options: CreateCopilotRuntimeServerOptions) {
|
|
6
6
|
telemetry.setGlobalProperties({
|
|
@@ -9,6 +9,9 @@ export function copilotRuntimeNestEndpoint(options: CreateCopilotRuntimeServerOp
|
|
|
9
9
|
},
|
|
10
10
|
});
|
|
11
11
|
|
|
12
|
-
telemetry.capture(
|
|
12
|
+
telemetry.capture(
|
|
13
|
+
"oss.runtime.instance_created",
|
|
14
|
+
getRuntimeInstanceTelemetryInfo(options.runtime),
|
|
15
|
+
);
|
|
13
16
|
return copilotRuntimeNodeHttpEndpoint(options);
|
|
14
17
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createYoga } from "graphql-yoga";
|
|
2
2
|
import { CreateCopilotRuntimeServerOptions, getCommonConfig } from "../shared";
|
|
3
|
-
import telemetry from "../../telemetry-client";
|
|
3
|
+
import telemetry, { getRuntimeInstanceTelemetryInfo } from "../../telemetry-client";
|
|
4
4
|
|
|
5
5
|
export function copilotRuntimeNextJSAppRouterEndpoint(options: CreateCopilotRuntimeServerOptions) {
|
|
6
6
|
const commonConfig = getCommonConfig(options);
|
|
@@ -17,7 +17,10 @@ export function copilotRuntimeNextJSAppRouterEndpoint(options: CreateCopilotRunt
|
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
telemetry.capture(
|
|
20
|
+
telemetry.capture(
|
|
21
|
+
"oss.runtime.instance_created",
|
|
22
|
+
getRuntimeInstanceTelemetryInfo(options.runtime),
|
|
23
|
+
);
|
|
21
24
|
|
|
22
25
|
const logger = commonConfig.logging;
|
|
23
26
|
logger.debug("Creating NextJS App Router endpoint");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { YogaServerInstance, createYoga } from "graphql-yoga";
|
|
2
2
|
import { CreateCopilotRuntimeServerOptions, GraphQLContext, getCommonConfig } from "../shared";
|
|
3
|
-
import telemetry from "../../telemetry-client";
|
|
3
|
+
import telemetry, { getRuntimeInstanceTelemetryInfo } from "../../telemetry-client";
|
|
4
4
|
|
|
5
5
|
export const config = {
|
|
6
6
|
api: {
|
|
@@ -32,7 +32,10 @@ export function copilotRuntimeNextJSPagesRouterEndpoint(
|
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
telemetry.capture(
|
|
35
|
+
telemetry.capture(
|
|
36
|
+
"oss.runtime.instance_created",
|
|
37
|
+
getRuntimeInstanceTelemetryInfo(options.runtime),
|
|
38
|
+
);
|
|
36
39
|
|
|
37
40
|
const logger = commonConfig.logging;
|
|
38
41
|
logger.debug("Creating NextJS Pages Router endpoint");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CreateCopilotRuntimeServerOptions } from "../shared";
|
|
2
2
|
import { copilotRuntimeNodeHttpEndpoint } from "../node-http";
|
|
3
|
-
import telemetry from "../../telemetry-client";
|
|
3
|
+
import telemetry, { getRuntimeInstanceTelemetryInfo } from "../../telemetry-client";
|
|
4
4
|
|
|
5
5
|
export function copilotRuntimeNodeExpressEndpoint(options: CreateCopilotRuntimeServerOptions) {
|
|
6
6
|
telemetry.setGlobalProperties({
|
|
@@ -9,6 +9,9 @@ export function copilotRuntimeNodeExpressEndpoint(options: CreateCopilotRuntimeS
|
|
|
9
9
|
},
|
|
10
10
|
});
|
|
11
11
|
|
|
12
|
-
telemetry.capture(
|
|
12
|
+
telemetry.capture(
|
|
13
|
+
"oss.runtime.instance_created",
|
|
14
|
+
getRuntimeInstanceTelemetryInfo(options.runtime),
|
|
15
|
+
);
|
|
13
16
|
return copilotRuntimeNodeHttpEndpoint(options);
|
|
14
17
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createYoga } from "graphql-yoga";
|
|
2
2
|
import { CreateCopilotRuntimeServerOptions, getCommonConfig } from "../shared";
|
|
3
|
-
import telemetry from "../../telemetry-client";
|
|
3
|
+
import telemetry, { getRuntimeInstanceTelemetryInfo } from "../../telemetry-client";
|
|
4
4
|
|
|
5
5
|
export function copilotRuntimeNodeHttpEndpoint(options: CreateCopilotRuntimeServerOptions) {
|
|
6
6
|
const commonConfig = getCommonConfig(options);
|
|
@@ -17,7 +17,10 @@ export function copilotRuntimeNodeHttpEndpoint(options: CreateCopilotRuntimeServ
|
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
telemetry.capture(
|
|
20
|
+
telemetry.capture(
|
|
21
|
+
"oss.runtime.instance_created",
|
|
22
|
+
getRuntimeInstanceTelemetryInfo(options.runtime),
|
|
23
|
+
);
|
|
21
24
|
|
|
22
25
|
const logger = commonConfig.logging;
|
|
23
26
|
logger.debug("Creating Node HTTP endpoint");
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { Action, actionParametersToJsonSchema, Parameter } from "@copilotkit/shared";
|
|
15
|
+
import { Action, actionParametersToJsonSchema, Parameter, randomId } from "@copilotkit/shared";
|
|
16
16
|
import { CopilotServiceAdapter, RemoteChain, RemoteChainParameters } from "../../service-adapters";
|
|
17
17
|
import { MessageInput } from "../../graphql/inputs/message.input";
|
|
18
18
|
import { ActionInput } from "../../graphql/inputs/action.input";
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
setupRemoteActions,
|
|
28
28
|
EndpointDefinition,
|
|
29
29
|
CopilotKitEndpoint,
|
|
30
|
-
|
|
30
|
+
LangGraphPlatformEndpoint,
|
|
31
31
|
} from "./remote-actions";
|
|
32
32
|
import { GraphQLContext } from "../integrations/shared";
|
|
33
33
|
import { AgentSessionInput } from "../../graphql/inputs/agent-session.input";
|
|
@@ -142,7 +142,7 @@ export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []
|
|
|
142
142
|
|
|
143
143
|
export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
144
144
|
public actions: ActionsConfiguration<T>;
|
|
145
|
-
|
|
145
|
+
public remoteEndpointDefinitions: EndpointDefinition[];
|
|
146
146
|
private langserve: Promise<Action<any>>[] = [];
|
|
147
147
|
private onBeforeRequest?: OnBeforeRequestHandler;
|
|
148
148
|
private onAfterRequest?: OnAfterRequestHandler;
|
|
@@ -155,7 +155,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
155
155
|
this.langserve.push(remoteChain.toAction());
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
this.remoteEndpointDefinitions = params?.remoteEndpoints
|
|
158
|
+
this.remoteEndpointDefinitions = params?.remoteEndpoints ?? params?.remoteActions ?? [];
|
|
159
159
|
|
|
160
160
|
this.onBeforeRequest = params?.middleware?.onBeforeRequest;
|
|
161
161
|
this.onAfterRequest = params?.middleware?.onAfterRequest;
|
|
@@ -175,36 +175,36 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
175
175
|
url,
|
|
176
176
|
} = request;
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
return this.processAgentRequest(request);
|
|
180
|
-
}
|
|
178
|
+
const eventSource = new RuntimeEventSource();
|
|
181
179
|
|
|
182
|
-
|
|
180
|
+
try {
|
|
181
|
+
if (agentSession) {
|
|
182
|
+
return await this.processAgentRequest(request);
|
|
183
|
+
}
|
|
183
184
|
|
|
184
|
-
|
|
185
|
-
const serverSideActions = await this.getServerSideActions(request);
|
|
185
|
+
const messages = rawMessages.filter((message) => !message.agentStateMessage);
|
|
186
186
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
description: action.description,
|
|
190
|
-
jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters)),
|
|
191
|
-
}));
|
|
187
|
+
const inputMessages = convertGqlInputToMessages(messages);
|
|
188
|
+
const serverSideActions = await this.getServerSideActions(request);
|
|
192
189
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
190
|
+
const serverSideActionsInput: ActionInput[] = serverSideActions.map((action) => ({
|
|
191
|
+
name: action.name,
|
|
192
|
+
description: action.description,
|
|
193
|
+
jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters)),
|
|
194
|
+
}));
|
|
197
195
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
properties: graphqlContext.properties,
|
|
203
|
-
url,
|
|
204
|
-
});
|
|
196
|
+
const actionInputs = flattenToolCallsNoDuplicates([
|
|
197
|
+
...serverSideActionsInput,
|
|
198
|
+
...clientSideActionsInput,
|
|
199
|
+
]);
|
|
205
200
|
|
|
206
|
-
|
|
207
|
-
|
|
201
|
+
await this.onBeforeRequest?.({
|
|
202
|
+
threadId,
|
|
203
|
+
runId,
|
|
204
|
+
inputMessages,
|
|
205
|
+
properties: graphqlContext.properties,
|
|
206
|
+
url,
|
|
207
|
+
});
|
|
208
208
|
|
|
209
209
|
const result = await serviceAdapter.process({
|
|
210
210
|
messages: inputMessages,
|
|
@@ -244,7 +244,14 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
244
244
|
};
|
|
245
245
|
} catch (error) {
|
|
246
246
|
console.error("Error getting response:", error);
|
|
247
|
-
|
|
247
|
+
eventSource.sendErrorMessageToChat();
|
|
248
|
+
return {
|
|
249
|
+
threadId: threadId || randomId(),
|
|
250
|
+
runId: runId || randomId(),
|
|
251
|
+
eventSource,
|
|
252
|
+
serverSideActions: [],
|
|
253
|
+
actionInputsWithoutAgents: [],
|
|
254
|
+
};
|
|
248
255
|
}
|
|
249
256
|
}
|
|
250
257
|
|
|
@@ -344,7 +351,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
344
351
|
(endpoint) =>
|
|
345
352
|
({
|
|
346
353
|
...endpoint,
|
|
347
|
-
type:
|
|
354
|
+
type: resolveEndpointType(endpoint),
|
|
348
355
|
}) as EndpointDefinition,
|
|
349
356
|
);
|
|
350
357
|
|
|
@@ -363,19 +370,6 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
363
370
|
|
|
364
371
|
return [...configuredActions, ...langserveFunctions, ...remoteActions];
|
|
365
372
|
}
|
|
366
|
-
|
|
367
|
-
private resolveEndpointType(endpoint: EndpointDefinition) {
|
|
368
|
-
if (
|
|
369
|
-
!endpoint.type &&
|
|
370
|
-
"langsmithApiKey" in endpoint &&
|
|
371
|
-
"deploymentUrl" in endpoint &&
|
|
372
|
-
"agents" in endpoint
|
|
373
|
-
) {
|
|
374
|
-
return EndpointType.LangGraphCloud;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
return endpoint.type;
|
|
378
|
-
}
|
|
379
373
|
}
|
|
380
374
|
|
|
381
375
|
export function flattenToolCallsNoDuplicates(toolsByPriority: ActionInput[]): ActionInput[] {
|
|
@@ -398,11 +392,23 @@ export function copilotKitEndpoint(config: Omit<CopilotKitEndpoint, "type">): Co
|
|
|
398
392
|
};
|
|
399
393
|
}
|
|
400
394
|
|
|
401
|
-
export function
|
|
402
|
-
config: Omit<
|
|
403
|
-
):
|
|
395
|
+
export function langGraphPlatformEndpoint(
|
|
396
|
+
config: Omit<LangGraphPlatformEndpoint, "type">,
|
|
397
|
+
): LangGraphPlatformEndpoint {
|
|
404
398
|
return {
|
|
405
399
|
...config,
|
|
406
|
-
type: EndpointType.
|
|
400
|
+
type: EndpointType.LangGraphPlatform,
|
|
407
401
|
};
|
|
408
402
|
}
|
|
403
|
+
|
|
404
|
+
export function resolveEndpointType(endpoint: EndpointDefinition) {
|
|
405
|
+
if (!endpoint.type) {
|
|
406
|
+
if ("langsmithApiKey" in endpoint && "deploymentUrl" in endpoint && "agents" in endpoint) {
|
|
407
|
+
return EndpointType.LangGraphPlatform;
|
|
408
|
+
} else {
|
|
409
|
+
return EndpointType.CopilotKit;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
return endpoint.type;
|
|
414
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
1
2
|
import {
|
|
2
3
|
CopilotKitEndpoint,
|
|
3
4
|
LangGraphAgentHandlerParams,
|
|
4
5
|
RemoteActionInfoResponse,
|
|
5
|
-
|
|
6
|
+
LangGraphPlatformEndpoint,
|
|
6
7
|
} from "./remote-actions";
|
|
7
8
|
import { GraphQLContext } from "../integrations";
|
|
8
9
|
import { Logger } from "pino";
|
|
@@ -14,7 +15,7 @@ import telemetry from "../telemetry-client";
|
|
|
14
15
|
import { RemoteLangGraphEventSource } from "../../agents/langgraph/event-source";
|
|
15
16
|
import { Action } from "@copilotkit/shared";
|
|
16
17
|
import { LangGraphEvent } from "../../agents/langgraph/events";
|
|
17
|
-
import { execute } from "./remote-lg-
|
|
18
|
+
import { execute } from "./remote-lg-action";
|
|
18
19
|
|
|
19
20
|
export function constructLGCRemoteAction({
|
|
20
21
|
endpoint,
|
|
@@ -23,7 +24,7 @@ export function constructLGCRemoteAction({
|
|
|
23
24
|
messages,
|
|
24
25
|
agentStates,
|
|
25
26
|
}: {
|
|
26
|
-
endpoint:
|
|
27
|
+
endpoint: LangGraphPlatformEndpoint;
|
|
27
28
|
graphqlContext: GraphQLContext;
|
|
28
29
|
logger: Logger;
|
|
29
30
|
messages: Message[];
|
|
@@ -40,9 +41,14 @@ export function constructLGCRemoteAction({
|
|
|
40
41
|
threadId,
|
|
41
42
|
nodeName,
|
|
42
43
|
}: LangGraphAgentHandlerParams): Promise<Observable<RuntimeEvent>> => {
|
|
43
|
-
logger.debug({ actionName: agent.name }, "Executing LangGraph
|
|
44
|
+
logger.debug({ actionName: agent.name }, "Executing LangGraph Platform agent");
|
|
44
45
|
|
|
45
|
-
telemetry.capture("oss.runtime.remote_action_executed", {
|
|
46
|
+
telemetry.capture("oss.runtime.remote_action_executed", {
|
|
47
|
+
agentExecution: true,
|
|
48
|
+
type: "langgraph-platform",
|
|
49
|
+
agentsAmount: endpoint.agents.length,
|
|
50
|
+
hashedLgcKey: createHash("sha256").update(endpoint.langsmithApiKey).digest("hex"),
|
|
51
|
+
});
|
|
46
52
|
|
|
47
53
|
let state = {};
|
|
48
54
|
if (agentStates) {
|
|
@@ -76,9 +82,9 @@ export function constructLGCRemoteAction({
|
|
|
76
82
|
} catch (error) {
|
|
77
83
|
logger.error(
|
|
78
84
|
{ url: endpoint.deploymentUrl, status: 500, body: error.message },
|
|
79
|
-
"Failed to execute LangGraph
|
|
85
|
+
"Failed to execute LangGraph Platform agent",
|
|
80
86
|
);
|
|
81
|
-
throw new Error("Failed to execute LangGraph
|
|
87
|
+
throw new Error("Failed to execute LangGraph Platform agent");
|
|
82
88
|
}
|
|
83
89
|
},
|
|
84
90
|
}));
|
|
@@ -111,7 +117,11 @@ export function constructRemoteActions({
|
|
|
111
117
|
logger.debug({ actionName: action.name, args }, "Executing remote action");
|
|
112
118
|
|
|
113
119
|
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
114
|
-
telemetry.capture("oss.runtime.remote_action_executed", {
|
|
120
|
+
telemetry.capture("oss.runtime.remote_action_executed", {
|
|
121
|
+
agentExecution: false,
|
|
122
|
+
type: "self-hosted",
|
|
123
|
+
agentsAmount: json["agents"].length,
|
|
124
|
+
});
|
|
115
125
|
|
|
116
126
|
try {
|
|
117
127
|
const response = await fetch(`${url}/actions/execute`, {
|
|
@@ -162,7 +172,11 @@ export function constructRemoteActions({
|
|
|
162
172
|
logger.debug({ actionName: agent.name }, "Executing remote agent");
|
|
163
173
|
|
|
164
174
|
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
165
|
-
telemetry.capture("oss.runtime.remote_action_executed", {
|
|
175
|
+
telemetry.capture("oss.runtime.remote_action_executed", {
|
|
176
|
+
agentExecution: true,
|
|
177
|
+
type: "self-hosted",
|
|
178
|
+
agentsAmount: json["agents"].length,
|
|
179
|
+
});
|
|
166
180
|
|
|
167
181
|
let state = {};
|
|
168
182
|
if (agentStates) {
|
|
@@ -12,11 +12,11 @@ import {
|
|
|
12
12
|
createHeaders,
|
|
13
13
|
} from "./remote-action-constructors";
|
|
14
14
|
|
|
15
|
-
export type EndpointDefinition = CopilotKitEndpoint |
|
|
15
|
+
export type EndpointDefinition = CopilotKitEndpoint | LangGraphPlatformEndpoint;
|
|
16
16
|
|
|
17
17
|
export enum EndpointType {
|
|
18
18
|
CopilotKit = "copilotKit",
|
|
19
|
-
|
|
19
|
+
LangGraphPlatform = "langgraph-platform",
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export interface BaseEndpointDefinition<TActionType extends EndpointType> {
|
|
@@ -30,17 +30,17 @@ export interface CopilotKitEndpoint extends BaseEndpointDefinition<EndpointType.
|
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export interface
|
|
33
|
+
export interface LangGraphPlatformAgent {
|
|
34
34
|
name: string;
|
|
35
35
|
description: string;
|
|
36
36
|
assistantId?: string;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export interface
|
|
40
|
-
extends BaseEndpointDefinition<EndpointType.
|
|
39
|
+
export interface LangGraphPlatformEndpoint
|
|
40
|
+
extends BaseEndpointDefinition<EndpointType.LangGraphPlatform> {
|
|
41
41
|
deploymentUrl: string;
|
|
42
42
|
langsmithApiKey: string;
|
|
43
|
-
agents:
|
|
43
|
+
agents: LangGraphPlatformAgent[];
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export type RemoteActionInfoResponse = {
|
|
@@ -127,7 +127,7 @@ export async function setupRemoteActions({
|
|
|
127
127
|
|
|
128
128
|
// Remove duplicates of remoteEndpointDefinitions.url
|
|
129
129
|
const filtered = remoteEndpointDefinitions.filter((value, index, self) => {
|
|
130
|
-
if (value.type === EndpointType.
|
|
130
|
+
if (value.type === EndpointType.LangGraphPlatform) {
|
|
131
131
|
return value;
|
|
132
132
|
}
|
|
133
133
|
return index === self.findIndex((t: CopilotKitEndpoint) => t.url === value.url);
|
|
@@ -135,8 +135,8 @@ export async function setupRemoteActions({
|
|
|
135
135
|
|
|
136
136
|
const result = await Promise.all(
|
|
137
137
|
filtered.map(async (endpoint) => {
|
|
138
|
-
// Check for properties that can distinguish LG
|
|
139
|
-
if (endpoint.type === EndpointType.
|
|
138
|
+
// Check for properties that can distinguish LG platform from other actions
|
|
139
|
+
if (endpoint.type === EndpointType.LangGraphPlatform) {
|
|
140
140
|
return constructLGCRemoteAction({
|
|
141
141
|
endpoint,
|
|
142
142
|
messages,
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import { Client } from "@langchain/langgraph-sdk";
|
|
2
|
-
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
3
3
|
import { parse as parsePartialJson } from "partial-json";
|
|
4
4
|
import { Logger } from "pino";
|
|
5
5
|
import { ActionInput } from "../../graphql/inputs/action.input";
|
|
6
|
-
import {
|
|
6
|
+
import { LangGraphPlatformAgent, LangGraphPlatformEndpoint } from "./remote-actions";
|
|
7
7
|
import { CopilotRequestContextProperties } from "../integrations";
|
|
8
8
|
import { Message, MessageType } from "../../graphql/types/converted";
|
|
9
9
|
import { MessageRole } from "../../graphql/types/enums";
|
|
10
10
|
import { CustomEventNames, LangGraphEventTypes } from "../../agents/langgraph/events";
|
|
11
|
+
import telemetry from "../telemetry-client";
|
|
11
12
|
|
|
12
13
|
type State = Record<string, any>;
|
|
13
14
|
|
|
14
15
|
type ExecutionAction = Pick<ActionInput, "name" | "description"> & { parameters: string };
|
|
15
16
|
|
|
16
|
-
interface ExecutionArgs extends Omit<
|
|
17
|
-
agent:
|
|
17
|
+
interface ExecutionArgs extends Omit<LangGraphPlatformEndpoint, "agents"> {
|
|
18
|
+
agent: LangGraphPlatformAgent;
|
|
18
19
|
threadId: string;
|
|
19
20
|
nodeName: string;
|
|
20
21
|
messages: Message[];
|
|
@@ -24,14 +25,14 @@ interface ExecutionArgs extends Omit<LangGraphCloudEndpoint, "agents"> {
|
|
|
24
25
|
logger: Logger;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
// The following types are our own definition to the messages accepted by LangGraph
|
|
28
|
+
// The following types are our own definition to the messages accepted by LangGraph Platform, enhanced with some of our extra data.
|
|
28
29
|
interface ToolCall {
|
|
29
30
|
id: string;
|
|
30
31
|
name: string;
|
|
31
32
|
args: Record<string, unknown>;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
type
|
|
35
|
+
type BaseLangGraphPlatformMessage = Omit<
|
|
35
36
|
Message,
|
|
36
37
|
| "isResultMessage"
|
|
37
38
|
| "isTextMessage"
|
|
@@ -46,19 +47,19 @@ type BaseLangGraphCloudMessage = Omit<
|
|
|
46
47
|
type: MessageType;
|
|
47
48
|
};
|
|
48
49
|
|
|
49
|
-
interface
|
|
50
|
+
interface LangGraphPlatformResultMessage extends BaseLangGraphPlatformMessage {
|
|
50
51
|
tool_call_id: string;
|
|
51
52
|
name: string;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
interface
|
|
55
|
+
interface LangGraphPlatformActionExecutionMessage extends BaseLangGraphPlatformMessage {
|
|
55
56
|
tool_calls: ToolCall[];
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
type
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
|
|
|
59
|
+
type LangGraphPlatformMessage =
|
|
60
|
+
| LangGraphPlatformActionExecutionMessage
|
|
61
|
+
| LangGraphPlatformResultMessage
|
|
62
|
+
| BaseLangGraphPlatformMessage;
|
|
62
63
|
|
|
63
64
|
export async function execute(args: ExecutionArgs): Promise<ReadableStream<Uint8Array>> {
|
|
64
65
|
return new ReadableStream({
|
|
@@ -88,7 +89,6 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
88
89
|
let state = initialState;
|
|
89
90
|
const { name, assistantId: initialAssistantId } = agent;
|
|
90
91
|
|
|
91
|
-
// TODO: deploymentUrl is not required in local development
|
|
92
92
|
const client = new Client({ apiUrl: deploymentUrl, apiKey: langsmithApiKey });
|
|
93
93
|
let initialThreadId = agrsInitialThreadId;
|
|
94
94
|
const wasInitiatedWithExistingThread = !!initialThreadId;
|
|
@@ -128,7 +128,7 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
128
128
|
if (!assistantId) {
|
|
129
129
|
console.error(`
|
|
130
130
|
No agent found for the agent name specified in CopilotKit provider
|
|
131
|
-
Please check your available agents or provide an agent ID in the LangGraph
|
|
131
|
+
Please check your available agents or provide an agent ID in the LangGraph Platform endpoint definition.\n
|
|
132
132
|
|
|
133
133
|
These are the available agents: [${assistants.map((a) => `${a.name} (ID: ${a.assistant_id})`).join(", ")}]
|
|
134
134
|
`);
|
|
@@ -152,8 +152,22 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
152
152
|
|
|
153
153
|
let latestStateValues = {};
|
|
154
154
|
let updatedState = state;
|
|
155
|
+
// If a manual emittance happens, it is the ultimate source of truth of state, unless a node has exited.
|
|
156
|
+
// Therefore, this value should either hold null, or the only edition of state that should be used.
|
|
157
|
+
let manuallyEmittedState = null;
|
|
158
|
+
let streamInfo: {
|
|
159
|
+
provider?: string;
|
|
160
|
+
langGraphHost?: string;
|
|
161
|
+
langGraphVersion?: string;
|
|
162
|
+
hashedLgcKey: string;
|
|
163
|
+
} = {
|
|
164
|
+
hashedLgcKey: createHash("sha256").update(langsmithApiKey).digest("hex"),
|
|
165
|
+
};
|
|
155
166
|
|
|
156
167
|
try {
|
|
168
|
+
telemetry.capture("oss.runtime.agent_execution_stream_started", {
|
|
169
|
+
hashedLgcKey: streamInfo.hashedLgcKey,
|
|
170
|
+
});
|
|
157
171
|
for await (const chunk of streamResponse) {
|
|
158
172
|
if (!["events", "values", "error"].includes(chunk.event)) continue;
|
|
159
173
|
|
|
@@ -174,6 +188,16 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
174
188
|
externalRunId = runId;
|
|
175
189
|
const metadata = event.metadata;
|
|
176
190
|
|
|
191
|
+
if (event.data?.output?.model != null && event.data?.output?.model != "") {
|
|
192
|
+
streamInfo.provider = event.data?.output?.model;
|
|
193
|
+
}
|
|
194
|
+
if (metadata.langgraph_host != null && metadata.langgraph_host != "") {
|
|
195
|
+
streamInfo.langGraphHost = metadata.langgraph_host;
|
|
196
|
+
}
|
|
197
|
+
if (metadata.langgraph_version != null && metadata.langgraph_version != "") {
|
|
198
|
+
streamInfo.langGraphVersion = metadata.langgraph_version;
|
|
199
|
+
}
|
|
200
|
+
|
|
177
201
|
shouldExit =
|
|
178
202
|
shouldExit ||
|
|
179
203
|
(eventType === LangGraphEventTypes.OnCustomEvent &&
|
|
@@ -184,33 +208,36 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
184
208
|
eventType === LangGraphEventTypes.OnCustomEvent &&
|
|
185
209
|
event.name === CustomEventNames.CopilotKitManuallyEmitIntermediateState;
|
|
186
210
|
|
|
211
|
+
const exitingNode =
|
|
212
|
+
nodeName === currentNodeName && eventType === LangGraphEventTypes.OnChainEnd;
|
|
213
|
+
|
|
214
|
+
// See manuallyEmittedState for explanation
|
|
215
|
+
if (exitingNode) {
|
|
216
|
+
manuallyEmittedState = null;
|
|
217
|
+
}
|
|
218
|
+
|
|
187
219
|
// we only want to update the node name under certain conditions
|
|
188
220
|
// since we don't need any internal node names to be sent to the frontend
|
|
189
221
|
if (graphInfo["nodes"].some((node) => node.id === currentNodeName)) {
|
|
190
222
|
nodeName = currentNodeName;
|
|
191
|
-
|
|
192
|
-
// only update state from values when entering or exiting a known node
|
|
193
|
-
if (
|
|
194
|
-
eventType === LangGraphEventTypes.OnChainStart ||
|
|
195
|
-
eventType === LangGraphEventTypes.OnChainEnd
|
|
196
|
-
) {
|
|
197
|
-
updatedState = latestStateValues;
|
|
198
|
-
}
|
|
199
223
|
}
|
|
200
224
|
|
|
225
|
+
updatedState = manuallyEmittedState ?? latestStateValues;
|
|
226
|
+
|
|
201
227
|
if (!nodeName) {
|
|
202
228
|
continue;
|
|
203
229
|
}
|
|
204
230
|
|
|
205
231
|
if (manuallyEmitIntermediateState) {
|
|
206
|
-
|
|
232
|
+
// See manuallyEmittedState for explanation
|
|
233
|
+
manuallyEmittedState = event.data;
|
|
207
234
|
emit(
|
|
208
235
|
getStateSyncEvent({
|
|
209
236
|
threadId,
|
|
210
237
|
runId,
|
|
211
238
|
agentName: agent.name,
|
|
212
239
|
nodeName,
|
|
213
|
-
state:
|
|
240
|
+
state: manuallyEmittedState,
|
|
214
241
|
running: true,
|
|
215
242
|
active: true,
|
|
216
243
|
}),
|
|
@@ -247,9 +274,6 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
247
274
|
emitIntermediateStateUntilEnd = null;
|
|
248
275
|
}
|
|
249
276
|
|
|
250
|
-
const exitingNode =
|
|
251
|
-
nodeName === currentNodeName && eventType === LangGraphEventTypes.OnChainEnd;
|
|
252
|
-
|
|
253
277
|
if (
|
|
254
278
|
JSON.stringify(updatedState) !== JSON.stringify(state) ||
|
|
255
279
|
prevNodeName != nodeName ||
|
|
@@ -277,6 +301,8 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
277
301
|
const isEndNode = state.next.length === 0;
|
|
278
302
|
nodeName = Object.keys(state.metadata.writes)[0];
|
|
279
303
|
|
|
304
|
+
telemetry.capture("oss.runtime.agent_execution_stream_ended", streamInfo);
|
|
305
|
+
|
|
280
306
|
emit(
|
|
281
307
|
getStateSyncEvent({
|
|
282
308
|
threadId,
|
|
@@ -413,7 +439,7 @@ class StreamingStateExtractor {
|
|
|
413
439
|
// Start of Selection
|
|
414
440
|
function langGraphDefaultMergeState(
|
|
415
441
|
state: State,
|
|
416
|
-
messages:
|
|
442
|
+
messages: LangGraphPlatformMessage[],
|
|
417
443
|
actions: ExecutionAction[],
|
|
418
444
|
agentName: string,
|
|
419
445
|
): State {
|
|
@@ -423,7 +449,7 @@ function langGraphDefaultMergeState(
|
|
|
423
449
|
}
|
|
424
450
|
|
|
425
451
|
// merge with existing messages
|
|
426
|
-
const mergedMessages:
|
|
452
|
+
const mergedMessages: LangGraphPlatformMessage[] = state.messages || [];
|
|
427
453
|
const existingMessageIds = new Set(mergedMessages.map((message) => message.id));
|
|
428
454
|
const existingToolCallResults = new Set<string>();
|
|
429
455
|
|
|
@@ -489,7 +515,7 @@ function langGraphDefaultMergeState(
|
|
|
489
515
|
}
|
|
490
516
|
|
|
491
517
|
// try to auto-correct and log alignment issues
|
|
492
|
-
const correctedMessages:
|
|
518
|
+
const correctedMessages: LangGraphPlatformMessage[] = [];
|
|
493
519
|
|
|
494
520
|
for (let i = 0; i < mergedMessages.length; i++) {
|
|
495
521
|
const currentMessage = mergedMessages[i];
|
|
@@ -560,7 +586,7 @@ function langGraphDefaultMergeState(
|
|
|
560
586
|
};
|
|
561
587
|
}
|
|
562
588
|
|
|
563
|
-
function formatMessages(messages: Message[]):
|
|
589
|
+
function formatMessages(messages: Message[]): LangGraphPlatformMessage[] {
|
|
564
590
|
return messages.map((message) => {
|
|
565
591
|
if (message.isTextMessage() && message.role === "assistant") {
|
|
566
592
|
return message;
|
|
@@ -583,7 +609,7 @@ function formatMessages(messages: Message[]): LangGraphCloudMessage[] {
|
|
|
583
609
|
tool_calls: [toolCall],
|
|
584
610
|
role: MessageRole.assistant,
|
|
585
611
|
id: message.id,
|
|
586
|
-
} satisfies
|
|
612
|
+
} satisfies LangGraphPlatformActionExecutionMessage;
|
|
587
613
|
}
|
|
588
614
|
if (message.isResultMessage()) {
|
|
589
615
|
return {
|
|
@@ -593,7 +619,7 @@ function formatMessages(messages: Message[]): LangGraphCloudMessage[] {
|
|
|
593
619
|
tool_call_id: message.actionExecutionId,
|
|
594
620
|
name: message.actionName,
|
|
595
621
|
role: MessageRole.tool,
|
|
596
|
-
} satisfies
|
|
622
|
+
} satisfies LangGraphPlatformResultMessage;
|
|
597
623
|
}
|
|
598
624
|
|
|
599
625
|
throw new Error(`Unknown message type ${message.type}`);
|