@copilotkit/runtime 1.3.16-mme-azure-openai.0 → 1.3.16-mme-sdk-js.2
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 +19 -3
- package/__snapshots__/schema/schema.graphql +1 -0
- package/dist/{chunk-MVG266E4.mjs → chunk-3N5PRHNJ.mjs} +37 -10
- package/dist/chunk-3N5PRHNJ.mjs.map +1 -0
- package/dist/{chunk-S5SYJ6JC.mjs → chunk-5IF2J3NL.mjs} +2 -2
- package/dist/{chunk-YVZORQSA.mjs → chunk-6UQXCIKF.mjs} +673 -151
- package/dist/chunk-6UQXCIKF.mjs.map +1 -0
- package/dist/{chunk-MYZHUCL6.mjs → chunk-B74M7FXG.mjs} +1 -1
- package/dist/chunk-B74M7FXG.mjs.map +1 -0
- package/dist/{chunk-MKZBH3Y6.mjs → chunk-HFTU4B7Q.mjs} +2 -2
- package/dist/{chunk-CRSCH25P.mjs → chunk-PA6U4BDE.mjs} +2 -2
- package/dist/{chunk-BHSRGDL6.mjs → chunk-XE3SYKK4.mjs} +1 -4
- package/dist/chunk-XE3SYKK4.mjs.map +1 -0
- package/dist/{copilot-runtime-df3527ad.d.ts → copilot-runtime-543a59ae.d.ts} +29 -7
- package/dist/graphql/types/converted/index.d.ts +1 -1
- package/dist/graphql/types/converted/index.js.map +1 -1
- package/dist/graphql/types/converted/index.mjs +1 -1
- package/dist/{groq-adapter-798aff23.d.ts → groq-adapter-7aa25931.d.ts} +1 -34
- package/dist/{index-cff31380.d.ts → index-83ee522f.d.ts} +3 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +745 -199
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +13 -9
- package/dist/index.mjs.map +1 -1
- package/dist/{langserve-a14a6849.d.ts → langserve-f00629d2.d.ts} +1 -1
- package/dist/lib/index.d.ts +4 -4
- package/dist/lib/index.js +745 -199
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +13 -9
- package/dist/lib/integrations/index.d.ts +4 -4
- package/dist/lib/integrations/index.js +4 -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 +4 -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 +4 -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 +4 -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.d.ts +4 -4
- package/dist/service-adapters/index.js +0 -3
- package/dist/service-adapters/index.js.map +1 -1
- package/dist/service-adapters/index.mjs +1 -1
- package/package.json +6 -4
- package/src/agents/langgraph/event-source.ts +62 -94
- package/src/agents/langgraph/events.ts +27 -17
- package/src/graphql/types/converted/index.ts +5 -1
- package/src/graphql/types/enums.ts +1 -0
- package/src/lib/runtime/copilot-runtime.ts +58 -11
- package/src/lib/runtime/remote-action-constructors.ts +284 -0
- package/src/lib/runtime/remote-actions.ts +65 -159
- package/src/lib/runtime/remote-lg-cloud-action.ts +612 -0
- package/src/service-adapters/openai/openai-adapter.ts +0 -37
- package/src/service-adapters/openai/utils.ts +13 -9
- package/dist/chunk-BHSRGDL6.mjs.map +0 -1
- package/dist/chunk-MVG266E4.mjs.map +0 -1
- package/dist/chunk-MYZHUCL6.mjs.map +0 -1
- package/dist/chunk-YVZORQSA.mjs.map +0 -1
- /package/dist/{chunk-S5SYJ6JC.mjs.map → chunk-5IF2J3NL.mjs.map} +0 -0
- /package/dist/{chunk-MKZBH3Y6.mjs.map → chunk-HFTU4B7Q.mjs.map} +0 -0
- /package/dist/{chunk-CRSCH25P.mjs.map → chunk-PA6U4BDE.mjs.map} +0 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CopilotKitEndpoint,
|
|
3
|
+
LangGraphAgentHandlerParams,
|
|
4
|
+
RemoteActionInfoResponse,
|
|
5
|
+
LangGraphCloudEndpoint,
|
|
6
|
+
} from "./remote-actions";
|
|
7
|
+
import { GraphQLContext } from "../integrations";
|
|
8
|
+
import { Logger } from "pino";
|
|
9
|
+
import { Message } from "../../graphql/types/converted";
|
|
10
|
+
import { AgentStateInput } from "../../graphql/inputs/agent-state.input";
|
|
11
|
+
import { Observable, ReplaySubject } from "rxjs";
|
|
12
|
+
import { RuntimeEvent } from "../../service-adapters/events";
|
|
13
|
+
import telemetry from "../telemetry-client";
|
|
14
|
+
import { RemoteLangGraphEventSource } from "../../agents/langgraph/event-source";
|
|
15
|
+
import { Action } from "@copilotkit/shared";
|
|
16
|
+
import { LangGraphEvent } from "../../agents/langgraph/events";
|
|
17
|
+
import { execute } from "./remote-lg-cloud-action";
|
|
18
|
+
|
|
19
|
+
export function constructLGCRemoteAction({
|
|
20
|
+
endpoint,
|
|
21
|
+
graphqlContext,
|
|
22
|
+
logger,
|
|
23
|
+
messages,
|
|
24
|
+
agentStates,
|
|
25
|
+
}: {
|
|
26
|
+
endpoint: LangGraphCloudEndpoint;
|
|
27
|
+
graphqlContext: GraphQLContext;
|
|
28
|
+
logger: Logger;
|
|
29
|
+
messages: Message[];
|
|
30
|
+
agentStates?: AgentStateInput[];
|
|
31
|
+
}) {
|
|
32
|
+
const agents = endpoint.agents.map((agent) => ({
|
|
33
|
+
name: agent.name,
|
|
34
|
+
description: agent.description,
|
|
35
|
+
parameters: [],
|
|
36
|
+
handler: async (_args: any) => {},
|
|
37
|
+
langGraphAgentHandler: async ({
|
|
38
|
+
name,
|
|
39
|
+
actionInputsWithoutAgents,
|
|
40
|
+
threadId,
|
|
41
|
+
nodeName,
|
|
42
|
+
}: LangGraphAgentHandlerParams): Promise<Observable<RuntimeEvent>> => {
|
|
43
|
+
logger.debug({ actionName: agent.name }, "Executing LangGraph Cloud agent");
|
|
44
|
+
|
|
45
|
+
telemetry.capture("oss.runtime.remote_action_executed", {});
|
|
46
|
+
|
|
47
|
+
let state = {};
|
|
48
|
+
if (agentStates) {
|
|
49
|
+
const jsonState = agentStates.find((state) => state.agentName === name)?.state;
|
|
50
|
+
if (jsonState) {
|
|
51
|
+
state = JSON.parse(jsonState);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
const response = await execute({
|
|
57
|
+
logger,
|
|
58
|
+
deploymentUrl: endpoint.deploymentUrl,
|
|
59
|
+
langsmithApiKey: endpoint.langsmithApiKey,
|
|
60
|
+
agent,
|
|
61
|
+
threadId,
|
|
62
|
+
nodeName,
|
|
63
|
+
messages,
|
|
64
|
+
state,
|
|
65
|
+
properties: graphqlContext.properties,
|
|
66
|
+
actions: actionInputsWithoutAgents.map((action) => ({
|
|
67
|
+
name: action.name,
|
|
68
|
+
description: action.description,
|
|
69
|
+
parameters: JSON.parse(action.jsonSchema) as string,
|
|
70
|
+
})),
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const eventSource = new RemoteLangGraphEventSource();
|
|
74
|
+
streamResponse(response, eventSource.eventStream$);
|
|
75
|
+
return eventSource.processLangGraphEvents();
|
|
76
|
+
} catch (error) {
|
|
77
|
+
logger.error(
|
|
78
|
+
{ url: endpoint.deploymentUrl, status: 500, body: error.message },
|
|
79
|
+
"Failed to execute LangGraph Cloud agent",
|
|
80
|
+
);
|
|
81
|
+
throw new Error("Failed to execute LangGraph Cloud agent");
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
}));
|
|
85
|
+
|
|
86
|
+
return [...agents];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function constructRemoteActions({
|
|
90
|
+
json,
|
|
91
|
+
url,
|
|
92
|
+
onBeforeRequest,
|
|
93
|
+
graphqlContext,
|
|
94
|
+
logger,
|
|
95
|
+
messages,
|
|
96
|
+
agentStates,
|
|
97
|
+
}: {
|
|
98
|
+
json: RemoteActionInfoResponse;
|
|
99
|
+
url: string;
|
|
100
|
+
onBeforeRequest?: CopilotKitEndpoint["onBeforeRequest"];
|
|
101
|
+
graphqlContext: GraphQLContext;
|
|
102
|
+
logger: Logger;
|
|
103
|
+
messages: Message[];
|
|
104
|
+
agentStates?: AgentStateInput[];
|
|
105
|
+
}): Action<any>[] {
|
|
106
|
+
const actions = json["actions"].map((action) => ({
|
|
107
|
+
name: action.name,
|
|
108
|
+
description: action.description,
|
|
109
|
+
parameters: action.parameters,
|
|
110
|
+
handler: async (args: any) => {
|
|
111
|
+
logger.debug({ actionName: action.name, args }, "Executing remote action");
|
|
112
|
+
|
|
113
|
+
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
114
|
+
telemetry.capture("oss.runtime.remote_action_executed", {});
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
const response = await fetch(`${url}/actions/execute`, {
|
|
118
|
+
method: "POST",
|
|
119
|
+
headers,
|
|
120
|
+
body: JSON.stringify({
|
|
121
|
+
name: action.name,
|
|
122
|
+
arguments: args,
|
|
123
|
+
properties: graphqlContext.properties,
|
|
124
|
+
}),
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
logger.error(
|
|
129
|
+
{ url, status: response.status, body: await response.text() },
|
|
130
|
+
"Failed to execute remote action",
|
|
131
|
+
);
|
|
132
|
+
return "Failed to execute remote action";
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const requestResult = await response.json();
|
|
136
|
+
|
|
137
|
+
const result = requestResult["result"];
|
|
138
|
+
logger.debug({ actionName: action.name, result }, "Executed remote action");
|
|
139
|
+
return result;
|
|
140
|
+
} catch (error) {
|
|
141
|
+
logger.error(
|
|
142
|
+
{ error: error.message ? error.message : error + "" },
|
|
143
|
+
"Failed to execute remote action",
|
|
144
|
+
);
|
|
145
|
+
return "Failed to execute remote action";
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
}));
|
|
149
|
+
|
|
150
|
+
const agents = json["agents"].map((agent) => ({
|
|
151
|
+
name: agent.name,
|
|
152
|
+
description: agent.description,
|
|
153
|
+
parameters: [],
|
|
154
|
+
handler: async (_args: any) => {},
|
|
155
|
+
|
|
156
|
+
langGraphAgentHandler: async ({
|
|
157
|
+
name,
|
|
158
|
+
actionInputsWithoutAgents,
|
|
159
|
+
threadId,
|
|
160
|
+
nodeName,
|
|
161
|
+
}: LangGraphAgentHandlerParams): Promise<Observable<RuntimeEvent>> => {
|
|
162
|
+
logger.debug({ actionName: agent.name }, "Executing remote agent");
|
|
163
|
+
|
|
164
|
+
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
165
|
+
telemetry.capture("oss.runtime.remote_action_executed", {});
|
|
166
|
+
|
|
167
|
+
let state = {};
|
|
168
|
+
if (agentStates) {
|
|
169
|
+
const jsonState = agentStates.find((state) => state.agentName === name)?.state;
|
|
170
|
+
if (jsonState) {
|
|
171
|
+
state = JSON.parse(jsonState);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const response = await fetch(`${url}/agents/execute`, {
|
|
176
|
+
method: "POST",
|
|
177
|
+
headers,
|
|
178
|
+
body: JSON.stringify({
|
|
179
|
+
name,
|
|
180
|
+
threadId,
|
|
181
|
+
nodeName,
|
|
182
|
+
messages,
|
|
183
|
+
state,
|
|
184
|
+
properties: graphqlContext.properties,
|
|
185
|
+
actions: actionInputsWithoutAgents.map((action) => ({
|
|
186
|
+
name: action.name,
|
|
187
|
+
description: action.description,
|
|
188
|
+
parameters: JSON.parse(action.jsonSchema),
|
|
189
|
+
})),
|
|
190
|
+
}),
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
if (!response.ok) {
|
|
194
|
+
logger.error(
|
|
195
|
+
{ url, status: response.status, body: await response.text() },
|
|
196
|
+
"Failed to execute remote agent",
|
|
197
|
+
);
|
|
198
|
+
throw new Error("Failed to execute remote agent");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const eventSource = new RemoteLangGraphEventSource();
|
|
202
|
+
streamResponse(response.body!, eventSource.eventStream$);
|
|
203
|
+
return eventSource.processLangGraphEvents();
|
|
204
|
+
},
|
|
205
|
+
}));
|
|
206
|
+
|
|
207
|
+
return [...actions, ...agents];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async function streamResponse(
|
|
211
|
+
response: ReadableStream<Uint8Array>,
|
|
212
|
+
eventStream$: ReplaySubject<LangGraphEvent>,
|
|
213
|
+
) {
|
|
214
|
+
const reader = response.getReader();
|
|
215
|
+
const decoder = new TextDecoder();
|
|
216
|
+
let buffer = [];
|
|
217
|
+
|
|
218
|
+
function flushBuffer() {
|
|
219
|
+
const currentBuffer = buffer.join("");
|
|
220
|
+
if (currentBuffer.trim().length === 0) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const parts = currentBuffer.split("\n");
|
|
224
|
+
if (parts.length === 0) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const lastPartIsComplete = currentBuffer.endsWith("\n");
|
|
229
|
+
|
|
230
|
+
// truncate buffer
|
|
231
|
+
buffer = [];
|
|
232
|
+
|
|
233
|
+
if (!lastPartIsComplete) {
|
|
234
|
+
// put back the last part
|
|
235
|
+
buffer.push(parts.pop());
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
parts
|
|
239
|
+
.map((part) => part.trim())
|
|
240
|
+
.filter((part) => part != "")
|
|
241
|
+
.forEach((part) => {
|
|
242
|
+
eventStream$.next(JSON.parse(part));
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
try {
|
|
247
|
+
while (true) {
|
|
248
|
+
const { done, value } = await reader.read();
|
|
249
|
+
|
|
250
|
+
if (!done) {
|
|
251
|
+
buffer.push(decoder.decode(value, { stream: true }));
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
flushBuffer();
|
|
255
|
+
|
|
256
|
+
if (done) {
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
} catch (error) {
|
|
261
|
+
console.error("Error in stream", error);
|
|
262
|
+
eventStream$.error(error);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
eventStream$.complete();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export function createHeaders(
|
|
269
|
+
onBeforeRequest: CopilotKitEndpoint["onBeforeRequest"],
|
|
270
|
+
graphqlContext: GraphQLContext,
|
|
271
|
+
) {
|
|
272
|
+
const headers = {
|
|
273
|
+
"Content-Type": "application/json",
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
if (onBeforeRequest) {
|
|
277
|
+
const { headers: additionalHeaders } = onBeforeRequest({ ctx: graphqlContext });
|
|
278
|
+
if (additionalHeaders) {
|
|
279
|
+
Object.assign(headers, additionalHeaders);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return headers;
|
|
284
|
+
}
|
|
@@ -1,20 +1,47 @@
|
|
|
1
1
|
import { Action } from "@copilotkit/shared";
|
|
2
2
|
import { GraphQLContext } from "../integrations/shared";
|
|
3
3
|
import { Logger } from "pino";
|
|
4
|
-
import telemetry from "../../lib/telemetry-client";
|
|
5
4
|
import { Message } from "../../graphql/types/converted";
|
|
6
|
-
import { RuntimeEvent
|
|
7
|
-
import { RemoteLangGraphEventSource } from "../../agents/langgraph/event-source";
|
|
5
|
+
import { RuntimeEvent } from "../../service-adapters/events";
|
|
8
6
|
import { Observable } from "rxjs";
|
|
9
7
|
import { ActionInput } from "../../graphql/inputs/action.input";
|
|
10
8
|
import { AgentStateInput } from "../../graphql/inputs/agent-state.input";
|
|
9
|
+
import {
|
|
10
|
+
constructLGCRemoteAction,
|
|
11
|
+
constructRemoteActions,
|
|
12
|
+
createHeaders,
|
|
13
|
+
} from "./remote-action-constructors";
|
|
11
14
|
|
|
12
|
-
export type
|
|
15
|
+
export type EndpointDefinition = CopilotKitEndpoint | LangGraphCloudEndpoint;
|
|
16
|
+
|
|
17
|
+
export enum EndpointType {
|
|
18
|
+
CopilotKit = "copilotKit",
|
|
19
|
+
LangGraphCloud = "langgraph-cloud",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface BaseEndpointDefinition<TActionType extends EndpointType> {
|
|
23
|
+
type?: TActionType;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface CopilotKitEndpoint extends BaseEndpointDefinition<EndpointType.CopilotKit> {
|
|
13
27
|
url: string;
|
|
14
28
|
onBeforeRequest?: ({ ctx }: { ctx: GraphQLContext }) => {
|
|
15
29
|
headers?: Record<string, string> | undefined;
|
|
16
30
|
};
|
|
17
|
-
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface LangGraphCloudAgent {
|
|
34
|
+
name: string;
|
|
35
|
+
description: string;
|
|
36
|
+
assistantId?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface LangGraphCloudEndpoint
|
|
40
|
+
extends BaseEndpointDefinition<EndpointType.LangGraphCloud> {
|
|
41
|
+
deploymentUrl: string;
|
|
42
|
+
langsmithApiKey: string;
|
|
43
|
+
agents: LangGraphCloudAgent[];
|
|
44
|
+
}
|
|
18
45
|
|
|
19
46
|
export type RemoteActionInfoResponse = {
|
|
20
47
|
actions: any[];
|
|
@@ -39,24 +66,6 @@ export function isLangGraphAgentAction(action: Action<any>): action is LangGraph
|
|
|
39
66
|
return typeof (action as LangGraphAgentAction).langGraphAgentHandler === "function";
|
|
40
67
|
}
|
|
41
68
|
|
|
42
|
-
function createHeaders(
|
|
43
|
-
onBeforeRequest: RemoteActionDefinition["onBeforeRequest"],
|
|
44
|
-
graphqlContext: GraphQLContext,
|
|
45
|
-
) {
|
|
46
|
-
const headers = {
|
|
47
|
-
"Content-Type": "application/json",
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
if (onBeforeRequest) {
|
|
51
|
-
const { headers: additionalHeaders } = onBeforeRequest({ ctx: graphqlContext });
|
|
52
|
-
if (additionalHeaders) {
|
|
53
|
-
Object.assign(headers, additionalHeaders);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return headers;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
69
|
async function fetchRemoteInfo({
|
|
61
70
|
url,
|
|
62
71
|
onBeforeRequest,
|
|
@@ -65,7 +74,7 @@ async function fetchRemoteInfo({
|
|
|
65
74
|
frontendUrl,
|
|
66
75
|
}: {
|
|
67
76
|
url: string;
|
|
68
|
-
onBeforeRequest?:
|
|
77
|
+
onBeforeRequest?: CopilotKitEndpoint["onBeforeRequest"];
|
|
69
78
|
graphqlContext: GraphQLContext;
|
|
70
79
|
logger: Logger;
|
|
71
80
|
frontendUrl?: string;
|
|
@@ -100,164 +109,61 @@ async function fetchRemoteInfo({
|
|
|
100
109
|
}
|
|
101
110
|
}
|
|
102
111
|
|
|
103
|
-
function constructRemoteActions({
|
|
104
|
-
json,
|
|
105
|
-
url,
|
|
106
|
-
onBeforeRequest,
|
|
107
|
-
graphqlContext,
|
|
108
|
-
logger,
|
|
109
|
-
messages,
|
|
110
|
-
agentStates,
|
|
111
|
-
}: {
|
|
112
|
-
json: RemoteActionInfoResponse;
|
|
113
|
-
url: string;
|
|
114
|
-
onBeforeRequest?: RemoteActionDefinition["onBeforeRequest"];
|
|
115
|
-
graphqlContext: GraphQLContext;
|
|
116
|
-
logger: Logger;
|
|
117
|
-
messages: Message[];
|
|
118
|
-
agentStates?: AgentStateInput[];
|
|
119
|
-
}): Action<any>[] {
|
|
120
|
-
const actions = json["actions"].map((action) => ({
|
|
121
|
-
name: action.name,
|
|
122
|
-
description: action.description,
|
|
123
|
-
parameters: action.parameters,
|
|
124
|
-
handler: async (args: any) => {
|
|
125
|
-
logger.debug({ actionName: action.name, args }, "Executing remote action");
|
|
126
|
-
|
|
127
|
-
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
128
|
-
telemetry.capture("oss.runtime.remote_action_executed", {});
|
|
129
|
-
|
|
130
|
-
try {
|
|
131
|
-
const response = await fetch(`${url}/actions/execute`, {
|
|
132
|
-
method: "POST",
|
|
133
|
-
headers,
|
|
134
|
-
body: JSON.stringify({
|
|
135
|
-
name: action.name,
|
|
136
|
-
arguments: args,
|
|
137
|
-
properties: graphqlContext.properties,
|
|
138
|
-
}),
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
if (!response.ok) {
|
|
142
|
-
logger.error(
|
|
143
|
-
{ url, status: response.status, body: await response.text() },
|
|
144
|
-
"Failed to execute remote action",
|
|
145
|
-
);
|
|
146
|
-
return "Failed to execute remote action";
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const requestResult = await response.json();
|
|
150
|
-
|
|
151
|
-
const result = requestResult["result"];
|
|
152
|
-
logger.debug({ actionName: action.name, result }, "Executed remote action");
|
|
153
|
-
return result;
|
|
154
|
-
} catch (error) {
|
|
155
|
-
logger.error(
|
|
156
|
-
{ error: error.message ? error.message : error + "" },
|
|
157
|
-
"Failed to execute remote action",
|
|
158
|
-
);
|
|
159
|
-
return "Failed to execute remote action";
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
}));
|
|
163
|
-
|
|
164
|
-
const agents = json["agents"].map((agent) => ({
|
|
165
|
-
name: agent.name,
|
|
166
|
-
description: agent.description,
|
|
167
|
-
parameters: [],
|
|
168
|
-
handler: async (_args: any) => {},
|
|
169
|
-
|
|
170
|
-
langGraphAgentHandler: async ({
|
|
171
|
-
name,
|
|
172
|
-
actionInputsWithoutAgents,
|
|
173
|
-
threadId,
|
|
174
|
-
nodeName,
|
|
175
|
-
}: LangGraphAgentHandlerParams): Promise<Observable<RuntimeEvent>> => {
|
|
176
|
-
logger.debug({ actionName: agent.name }, "Executing remote agent");
|
|
177
|
-
|
|
178
|
-
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
179
|
-
telemetry.capture("oss.runtime.remote_action_executed", {});
|
|
180
|
-
|
|
181
|
-
let state = {};
|
|
182
|
-
if (agentStates) {
|
|
183
|
-
const jsonState = agentStates.find((state) => state.agentName === name)?.state;
|
|
184
|
-
if (jsonState) {
|
|
185
|
-
state = JSON.parse(jsonState);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const response = await fetch(`${url}/agents/execute`, {
|
|
190
|
-
method: "POST",
|
|
191
|
-
headers,
|
|
192
|
-
body: JSON.stringify({
|
|
193
|
-
name,
|
|
194
|
-
threadId,
|
|
195
|
-
nodeName,
|
|
196
|
-
messages,
|
|
197
|
-
state,
|
|
198
|
-
properties: graphqlContext.properties,
|
|
199
|
-
actions: actionInputsWithoutAgents.map((action) => ({
|
|
200
|
-
name: action.name,
|
|
201
|
-
description: action.description,
|
|
202
|
-
parameters: JSON.parse(action.jsonSchema),
|
|
203
|
-
})),
|
|
204
|
-
}),
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
if (!response.ok) {
|
|
208
|
-
logger.error(
|
|
209
|
-
{ url, status: response.status, body: await response.text() },
|
|
210
|
-
"Failed to execute remote agent",
|
|
211
|
-
);
|
|
212
|
-
throw new Error("Failed to execute remote agent");
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const eventSource = new RemoteLangGraphEventSource();
|
|
216
|
-
eventSource.streamResponse(response);
|
|
217
|
-
return eventSource.processLangGraphEvents();
|
|
218
|
-
},
|
|
219
|
-
}));
|
|
220
|
-
|
|
221
|
-
return [...actions, ...agents];
|
|
222
|
-
}
|
|
223
|
-
|
|
224
112
|
export async function setupRemoteActions({
|
|
225
|
-
|
|
113
|
+
remoteEndpointDefinitions,
|
|
226
114
|
graphqlContext,
|
|
227
115
|
messages,
|
|
228
116
|
agentStates,
|
|
229
117
|
frontendUrl,
|
|
230
118
|
}: {
|
|
231
|
-
|
|
119
|
+
remoteEndpointDefinitions: EndpointDefinition[];
|
|
232
120
|
graphqlContext: GraphQLContext;
|
|
233
121
|
messages: Message[];
|
|
234
122
|
agentStates?: AgentStateInput[];
|
|
235
123
|
frontendUrl?: string;
|
|
236
124
|
}): Promise<Action[]> {
|
|
237
125
|
const logger = graphqlContext.logger.child({ component: "remote-actions.fetchRemoteActions" });
|
|
238
|
-
logger.debug({
|
|
126
|
+
logger.debug({ remoteEndpointDefinitions }, "Fetching from remote endpoints");
|
|
239
127
|
|
|
240
|
-
// Remove duplicates of
|
|
241
|
-
const filtered =
|
|
242
|
-
(value
|
|
243
|
-
|
|
128
|
+
// Remove duplicates of remoteEndpointDefinitions.url
|
|
129
|
+
const filtered = remoteEndpointDefinitions.filter((value, index, self) => {
|
|
130
|
+
if (value.type === EndpointType.LangGraphCloud) {
|
|
131
|
+
return value;
|
|
132
|
+
}
|
|
133
|
+
return index === self.findIndex((t: CopilotKitEndpoint) => t.url === value.url);
|
|
134
|
+
});
|
|
244
135
|
|
|
245
136
|
const result = await Promise.all(
|
|
246
|
-
filtered.map(async (
|
|
137
|
+
filtered.map(async (endpoint) => {
|
|
138
|
+
// Check for properties that can distinguish LG cloud from other actions
|
|
139
|
+
if (endpoint.type === EndpointType.LangGraphCloud) {
|
|
140
|
+
return constructLGCRemoteAction({
|
|
141
|
+
endpoint,
|
|
142
|
+
messages,
|
|
143
|
+
graphqlContext,
|
|
144
|
+
logger: logger.child({
|
|
145
|
+
component: "remote-actions.constructLGCRemoteAction",
|
|
146
|
+
endpoint,
|
|
147
|
+
}),
|
|
148
|
+
agentStates,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
247
152
|
const json = await fetchRemoteInfo({
|
|
248
|
-
url:
|
|
249
|
-
onBeforeRequest:
|
|
153
|
+
url: endpoint.url,
|
|
154
|
+
onBeforeRequest: endpoint.onBeforeRequest,
|
|
250
155
|
graphqlContext,
|
|
251
|
-
logger: logger.child({ component: "remote-actions.fetchActionsFromUrl",
|
|
156
|
+
logger: logger.child({ component: "remote-actions.fetchActionsFromUrl", endpoint }),
|
|
252
157
|
frontendUrl,
|
|
253
158
|
});
|
|
159
|
+
|
|
254
160
|
return constructRemoteActions({
|
|
255
161
|
json,
|
|
256
162
|
messages,
|
|
257
|
-
url:
|
|
258
|
-
onBeforeRequest:
|
|
163
|
+
url: endpoint.url,
|
|
164
|
+
onBeforeRequest: endpoint.onBeforeRequest,
|
|
259
165
|
graphqlContext,
|
|
260
|
-
logger: logger.child({ component: "remote-actions.constructActions",
|
|
166
|
+
logger: logger.child({ component: "remote-actions.constructActions", endpoint }),
|
|
261
167
|
agentStates,
|
|
262
168
|
});
|
|
263
169
|
}),
|