@copilotkit/runtime 1.3.12-lgc-alpha-1.0 → 1.3.12

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.
Files changed (56) hide show
  1. package/CHANGELOG.md +4 -3
  2. package/dist/{chunk-7MQDBRXJ.mjs → chunk-24WEOOFX.mjs} +2 -2
  3. package/dist/{chunk-E6ZFCM3B.mjs → chunk-F2KJWMGD.mjs} +133 -561
  4. package/dist/chunk-F2KJWMGD.mjs.map +1 -0
  5. package/dist/{chunk-6HXQC7IT.mjs → chunk-IXVCESAR.mjs} +9 -36
  6. package/dist/chunk-IXVCESAR.mjs.map +1 -0
  7. package/dist/{chunk-TM7ZRU3M.mjs → chunk-IZP72K7I.mjs} +2 -2
  8. package/dist/{chunk-6B3NPPSR.mjs → chunk-PRG6VWHR.mjs} +2 -2
  9. package/dist/{chunk-XMDH5MKI.mjs → chunk-WBLYFYMZ.mjs} +2 -2
  10. package/dist/{chunk-V7SK6QZN.mjs → chunk-ZEHCLFJ2.mjs} +9 -6
  11. package/dist/chunk-ZEHCLFJ2.mjs.map +1 -0
  12. package/dist/{copilot-runtime-aba7d4b4.d.ts → copilot-runtime-df3527ad.d.ts} +5 -27
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.js +186 -638
  15. package/dist/index.js.map +1 -1
  16. package/dist/index.mjs +9 -13
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/lib/index.d.ts +1 -1
  19. package/dist/lib/index.js +186 -638
  20. package/dist/lib/index.js.map +1 -1
  21. package/dist/lib/index.mjs +9 -13
  22. package/dist/lib/integrations/index.d.ts +2 -2
  23. package/dist/lib/integrations/index.js +4 -5
  24. package/dist/lib/integrations/index.js.map +1 -1
  25. package/dist/lib/integrations/index.mjs +5 -5
  26. package/dist/lib/integrations/nest/index.d.ts +1 -1
  27. package/dist/lib/integrations/nest/index.js +4 -5
  28. package/dist/lib/integrations/nest/index.js.map +1 -1
  29. package/dist/lib/integrations/nest/index.mjs +3 -3
  30. package/dist/lib/integrations/node-express/index.d.ts +1 -1
  31. package/dist/lib/integrations/node-express/index.js +4 -5
  32. package/dist/lib/integrations/node-express/index.js.map +1 -1
  33. package/dist/lib/integrations/node-express/index.mjs +3 -3
  34. package/dist/lib/integrations/node-http/index.d.ts +1 -1
  35. package/dist/lib/integrations/node-http/index.js +4 -5
  36. package/dist/lib/integrations/node-http/index.js.map +1 -1
  37. package/dist/lib/integrations/node-http/index.mjs +2 -2
  38. package/dist/service-adapters/index.js +8 -5
  39. package/dist/service-adapters/index.js.map +1 -1
  40. package/dist/service-adapters/index.mjs +2 -2
  41. package/package.json +6 -7
  42. package/src/agents/langgraph/event-source.ts +67 -22
  43. package/src/lib/runtime/copilot-runtime.ts +11 -58
  44. package/src/lib/runtime/remote-actions.ts +159 -65
  45. package/src/service-adapters/events.ts +5 -1
  46. package/src/service-adapters/langchain/utils.test.ts +169 -0
  47. package/src/service-adapters/langchain/utils.ts +10 -5
  48. package/dist/chunk-6HXQC7IT.mjs.map +0 -1
  49. package/dist/chunk-E6ZFCM3B.mjs.map +0 -1
  50. package/dist/chunk-V7SK6QZN.mjs.map +0 -1
  51. package/src/lib/runtime/remote-action-constructors.ts +0 -283
  52. package/src/lib/runtime/remote-lg-cloud-action.ts +0 -441
  53. /package/dist/{chunk-7MQDBRXJ.mjs.map → chunk-24WEOOFX.mjs.map} +0 -0
  54. /package/dist/{chunk-TM7ZRU3M.mjs.map → chunk-IZP72K7I.mjs.map} +0 -0
  55. /package/dist/{chunk-6B3NPPSR.mjs.map → chunk-PRG6VWHR.mjs.map} +0 -0
  56. /package/dist/{chunk-XMDH5MKI.mjs.map → chunk-WBLYFYMZ.mjs.map} +0 -0
@@ -15,7 +15,63 @@ interface LangGraphEventWithState {
15
15
  }
16
16
 
17
17
  export class RemoteLangGraphEventSource {
18
- public eventStream$ = new ReplaySubject<LangGraphEvent>();
18
+ private eventStream$ = new ReplaySubject<LangGraphEvent>();
19
+
20
+ async streamResponse(response: Response) {
21
+ const reader = response.body!.getReader();
22
+ const decoder = new TextDecoder();
23
+ let buffer = [];
24
+ const eventStream$ = this.eventStream$;
25
+
26
+ function flushBuffer() {
27
+ const currentBuffer = buffer.join("");
28
+ if (currentBuffer.trim().length === 0) {
29
+ return;
30
+ }
31
+ const parts = currentBuffer.split("\n");
32
+ if (parts.length === 0) {
33
+ return;
34
+ }
35
+
36
+ const lastPartIsComplete = currentBuffer.endsWith("\n");
37
+
38
+ // truncate buffer
39
+ buffer = [];
40
+
41
+ if (!lastPartIsComplete) {
42
+ // put back the last part
43
+ buffer.push(parts.pop());
44
+ }
45
+
46
+ parts
47
+ .map((part) => part.trim())
48
+ .filter((part) => part != "")
49
+ .forEach((part) => {
50
+ eventStream$.next(JSON.parse(part));
51
+ });
52
+ }
53
+
54
+ try {
55
+ while (true) {
56
+ const { done, value } = await reader.read();
57
+
58
+ if (!done) {
59
+ buffer.push(decoder.decode(value, { stream: true }));
60
+ }
61
+
62
+ flushBuffer();
63
+
64
+ if (done) {
65
+ break;
66
+ }
67
+ }
68
+ } catch (error) {
69
+ console.error("Error in stream", error);
70
+ eventStream$.error(error);
71
+ return;
72
+ }
73
+ eventStream$.complete();
74
+ }
19
75
 
20
76
  private shouldEmitToolCall(
21
77
  shouldEmitToolCalls: string | string[] | boolean,
@@ -37,7 +93,7 @@ export class RemoteLangGraphEventSource {
37
93
  scan(
38
94
  (acc, event) => {
39
95
  if (event.event === LangGraphEventTypes.OnChatModelStream) {
40
- // @ts-expect-error -- LangGraph Cloud implementation stores data outside of kwargs
96
+ // @ts-ignore
41
97
  const content = event.data?.chunk?.kwargs?.content ?? event.data?.chunk?.content;
42
98
 
43
99
  if (typeof content === "string") {
@@ -48,28 +104,20 @@ export class RemoteLangGraphEventSource {
48
104
  acc.content = null;
49
105
  }
50
106
 
51
- const toolCallChunks =
52
- // @ts-expect-error -- LangGraph Cloud implementation stores data outside of kwargs
53
- event.data?.chunk?.kwargs?.tool_call_chunks ?? event.data?.chunk?.tool_call_chunks;
54
-
55
- const toolCallMessageId =
56
- event.data?.chunk?.kwargs?.id ??
57
- (event.data?.chunk?.id as unknown as string | undefined);
58
-
59
- if (toolCallChunks && toolCallChunks.length > 0) {
107
+ if (event.data?.chunk?.kwargs?.tool_call_chunks) {
60
108
  acc.prevToolCallMessageId = acc.toolCallMessageId;
61
- acc.toolCallMessageId = toolCallMessageId;
62
- if (toolCallChunks[0]?.name) {
63
- acc.toolCallName = toolCallChunks[0].name;
109
+ acc.toolCallMessageId = event.data.chunk.kwargs?.id;
110
+ if (event.data.chunk.kwargs.tool_call_chunks[0]?.name) {
111
+ acc.toolCallName = event.data.chunk.kwargs.tool_call_chunks[0].name;
64
112
  }
65
- if (toolCallChunks[0]?.id) {
66
- acc.toolCallId = toolCallChunks[0].id;
113
+ if (event.data.chunk.kwargs.tool_call_chunks[0]?.id) {
114
+ acc.toolCallId = event.data.chunk.kwargs.tool_call_chunks[0].id;
67
115
  }
68
116
  acc.prevMessageId = acc.messageId;
69
- acc.messageId = toolCallMessageId;
117
+ acc.messageId = event.data?.chunk?.kwargs?.id;
70
118
  } else if (acc.content && acc.content != "") {
71
119
  acc.prevMessageId = acc.messageId;
72
- acc.messageId = toolCallMessageId;
120
+ acc.messageId = event.data?.chunk?.kwargs?.id;
73
121
  } else {
74
122
  acc.prevToolCallMessageId = acc.toolCallMessageId;
75
123
  acc.prevMessageId = acc.messageId;
@@ -218,10 +266,7 @@ export class RemoteLangGraphEventSource {
218
266
  }
219
267
  }
220
268
 
221
- const args =
222
- eventWithState.event.data?.chunk?.kwargs?.tool_call_chunks?.[0]?.args ??
223
- // @ts-expect-error -- sdf
224
- eventWithState.event.data?.chunk?.tool_call_chunks?.[0]?.args;
269
+ const args = eventWithState.event.data?.chunk?.kwargs?.tool_call_chunks?.[0]?.args;
225
270
  const content = eventWithState.content;
226
271
 
227
272
  // Tool call args: emit ActionExecutionArgs
@@ -12,22 +12,19 @@
12
12
  * ```
13
13
  */
14
14
 
15
- import { Action, actionParametersToJsonSchema, Parameter } from "@copilotkit/shared";
16
- import { CopilotServiceAdapter, RemoteChain, RemoteChainParameters } from "../../service-adapters";
15
+ import { Action, actionParametersToJsonSchema, Parameter, randomId } from "@copilotkit/shared";
16
+ import { RemoteChain, RemoteChainParameters, CopilotServiceAdapter } from "../../service-adapters";
17
17
  import { MessageInput } from "../../graphql/inputs/message.input";
18
18
  import { ActionInput } from "../../graphql/inputs/action.input";
19
19
  import { RuntimeEventSource } from "../../service-adapters/events";
20
20
  import { convertGqlInputToMessages } from "../../service-adapters/conversion";
21
- import { Message } from "../../graphql/types/converted";
21
+ import { AgentStateMessage, Message } from "../../graphql/types/converted";
22
22
  import { ForwardedParametersInput } from "../../graphql/inputs/forwarded-parameters.input";
23
23
  import {
24
- isLangGraphAgentAction,
25
- LangGraphAgentAction,
26
- EndpointType,
27
24
  setupRemoteActions,
28
- EndpointDefinition,
29
- CopilotKitEndpoint,
30
- LangGraphCloudEndpoint,
25
+ RemoteActionDefinition,
26
+ LangGraphAgentAction,
27
+ isLangGraphAgentAction,
31
28
  } from "./remote-actions";
32
29
  import { GraphQLContext } from "../integrations/shared";
33
30
  import { AgentSessionInput } from "../../graphql/inputs/agent-session.input";
@@ -124,15 +121,10 @@ export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []
124
121
  */
125
122
  actions?: ActionsConfiguration<T>;
126
123
 
127
- /*
128
- * Deprecated: See `remoteEndpoints`.
129
- */
130
- remoteActions?: EndpointDefinition[];
131
-
132
124
  /*
133
125
  * A list of remote actions that can be executed.
134
126
  */
135
- remoteEndpoints?: EndpointDefinition[];
127
+ remoteActions?: RemoteActionDefinition[];
136
128
 
137
129
  /*
138
130
  * An array of LangServer URLs.
@@ -142,7 +134,7 @@ export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []
142
134
 
143
135
  export class CopilotRuntime<const T extends Parameter[] | [] = []> {
144
136
  public actions: ActionsConfiguration<T>;
145
- private remoteEndpointDefinitions: EndpointDefinition[];
137
+ private remoteActionDefinitions: RemoteActionDefinition[];
146
138
  private langserve: Promise<Action<any>>[] = [];
147
139
  private onBeforeRequest?: OnBeforeRequestHandler;
148
140
  private onAfterRequest?: OnAfterRequestHandler;
@@ -155,7 +147,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
155
147
  this.langserve.push(remoteChain.toAction());
156
148
  }
157
149
 
158
- this.remoteEndpointDefinitions = params?.remoteEndpoints || [];
150
+ this.remoteActionDefinitions = params?.remoteActions || [];
159
151
 
160
152
  this.onBeforeRequest = params?.middleware?.onBeforeRequest;
161
153
  this.onAfterRequest = params?.middleware?.onAfterRequest;
@@ -252,7 +244,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
252
244
  request: CopilotRuntimeRequest,
253
245
  ): Promise<CopilotRuntimeResponse> {
254
246
  const { messages: rawMessages, outputMessagesPromise, graphqlContext, agentSession } = request;
255
- const { threadId, agentName, nodeName } = agentSession;
247
+ const { threadId = randomId(), agentName, nodeName } = agentSession;
256
248
  const serverSideActions = await this.getServerSideActions(request);
257
249
 
258
250
  const messages = convertGqlInputToMessages(rawMessages);
@@ -339,17 +331,8 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
339
331
  console.error("Error loading langserve chain:", error);
340
332
  }
341
333
  }
342
-
343
- const remoteEndpointDefinitions = this.remoteEndpointDefinitions.map(
344
- (endpoint) =>
345
- ({
346
- ...endpoint,
347
- type: this.resolveEndpointType(endpoint),
348
- }) as EndpointDefinition,
349
- );
350
-
351
334
  const remoteActions = await setupRemoteActions({
352
- remoteEndpointDefinitions,
335
+ remoteActionDefinitions: this.remoteActionDefinitions,
353
336
  graphqlContext,
354
337
  messages: inputMessages,
355
338
  agentStates,
@@ -363,19 +346,6 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
363
346
 
364
347
  return [...configuredActions, ...langserveFunctions, ...remoteActions];
365
348
  }
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
349
  }
380
350
 
381
351
  export function flattenToolCallsNoDuplicates(toolsByPriority: ActionInput[]): ActionInput[] {
@@ -389,20 +359,3 @@ export function flattenToolCallsNoDuplicates(toolsByPriority: ActionInput[]): Ac
389
359
  }
390
360
  return allTools;
391
361
  }
392
-
393
- // The two functions below are "factory functions", meant to create the action objects that adhere to the expected interfaces
394
- export function copilotKitEndpoint(config: Omit<CopilotKitEndpoint, "type">): CopilotKitEndpoint {
395
- return {
396
- ...config,
397
- type: EndpointType.CopilotKit,
398
- };
399
- }
400
-
401
- export function langGraphCloudEndpoint(
402
- config: Omit<LangGraphCloudEndpoint, "type">,
403
- ): LangGraphCloudEndpoint {
404
- return {
405
- ...config,
406
- type: EndpointType.LangGraphCloud,
407
- };
408
- }
@@ -1,47 +1,20 @@
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";
4
5
  import { Message } from "../../graphql/types/converted";
5
- import { RuntimeEvent } from "../../service-adapters/events";
6
+ import { RuntimeEvent, RuntimeEventSubject } from "../../service-adapters/events";
7
+ import { RemoteLangGraphEventSource } from "../../agents/langgraph/event-source";
6
8
  import { Observable } from "rxjs";
7
9
  import { ActionInput } from "../../graphql/inputs/action.input";
8
10
  import { AgentStateInput } from "../../graphql/inputs/agent-state.input";
9
- import {
10
- constructLGCRemoteAction,
11
- constructRemoteActions,
12
- createHeaders,
13
- } from "./remote-action-constructors";
14
11
 
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> {
12
+ export type RemoteActionDefinition = {
27
13
  url: string;
28
14
  onBeforeRequest?: ({ ctx }: { ctx: GraphQLContext }) => {
29
15
  headers?: Record<string, string> | undefined;
30
16
  };
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
- }
17
+ };
45
18
 
46
19
  export type RemoteActionInfoResponse = {
47
20
  actions: any[];
@@ -66,6 +39,24 @@ export function isLangGraphAgentAction(action: Action<any>): action is LangGraph
66
39
  return typeof (action as LangGraphAgentAction).langGraphAgentHandler === "function";
67
40
  }
68
41
 
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
+
69
60
  async function fetchRemoteInfo({
70
61
  url,
71
62
  onBeforeRequest,
@@ -74,7 +65,7 @@ async function fetchRemoteInfo({
74
65
  frontendUrl,
75
66
  }: {
76
67
  url: string;
77
- onBeforeRequest?: CopilotKitEndpoint["onBeforeRequest"];
68
+ onBeforeRequest?: RemoteActionDefinition["onBeforeRequest"];
78
69
  graphqlContext: GraphQLContext;
79
70
  logger: Logger;
80
71
  frontendUrl?: string;
@@ -109,61 +100,164 @@ async function fetchRemoteInfo({
109
100
  }
110
101
  }
111
102
 
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
+
112
224
  export async function setupRemoteActions({
113
- remoteEndpointDefinitions,
225
+ remoteActionDefinitions,
114
226
  graphqlContext,
115
227
  messages,
116
228
  agentStates,
117
229
  frontendUrl,
118
230
  }: {
119
- remoteEndpointDefinitions: EndpointDefinition[];
231
+ remoteActionDefinitions: RemoteActionDefinition[];
120
232
  graphqlContext: GraphQLContext;
121
233
  messages: Message[];
122
234
  agentStates?: AgentStateInput[];
123
235
  frontendUrl?: string;
124
236
  }): Promise<Action[]> {
125
237
  const logger = graphqlContext.logger.child({ component: "remote-actions.fetchRemoteActions" });
126
- logger.debug({ remoteEndpointDefinitions }, "Fetching from remote endpoints");
238
+ logger.debug({ remoteActionDefinitions }, "Fetching remote actions");
127
239
 
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
- });
240
+ // Remove duplicates of remoteActionDefinitions.url
241
+ const filtered = remoteActionDefinitions.filter(
242
+ (value, index, self) => index === self.findIndex((t) => t.url === value.url),
243
+ );
135
244
 
136
245
  const result = await Promise.all(
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
-
246
+ filtered.map(async (actionDefinition) => {
152
247
  const json = await fetchRemoteInfo({
153
- url: endpoint.url,
154
- onBeforeRequest: endpoint.onBeforeRequest,
248
+ url: actionDefinition.url,
249
+ onBeforeRequest: actionDefinition.onBeforeRequest,
155
250
  graphqlContext,
156
- logger: logger.child({ component: "remote-actions.fetchActionsFromUrl", endpoint }),
251
+ logger: logger.child({ component: "remote-actions.fetchActionsFromUrl", actionDefinition }),
157
252
  frontendUrl,
158
253
  });
159
-
160
254
  return constructRemoteActions({
161
255
  json,
162
256
  messages,
163
- url: endpoint.url,
164
- onBeforeRequest: endpoint.onBeforeRequest,
257
+ url: actionDefinition.url,
258
+ onBeforeRequest: actionDefinition.onBeforeRequest,
165
259
  graphqlContext,
166
- logger: logger.child({ component: "remote-actions.constructActions", endpoint }),
260
+ logger: logger.child({ component: "remote-actions.constructActions", actionDefinition }),
167
261
  agentStates,
168
262
  });
169
263
  }),
@@ -260,7 +260,11 @@ async function executeAction(
260
260
  // Prepare arguments for function calling
261
261
  let args: Record<string, any>[] = [];
262
262
  if (actionArguments) {
263
- args = JSON.parse(actionArguments);
263
+ try {
264
+ args = JSON.parse(actionArguments);
265
+ } catch (e) {
266
+ console.warn("Action argument unparsable", { actionArguments });
267
+ }
264
268
  }
265
269
 
266
270
  // handle LangGraph agents