@copilotkit/runtime 1.5.12-next.5 → 1.5.12-next.7

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 (72) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/__snapshots__/schema/schema.graphql +33 -0
  3. package/dist/{chunk-MFDRA3BJ.mjs → chunk-34276UUU.mjs} +652 -285
  4. package/dist/chunk-34276UUU.mjs.map +1 -0
  5. package/dist/{chunk-XRW7ZSWJ.mjs → chunk-DLESGNLO.mjs} +2 -2
  6. package/dist/{chunk-TPTCSIAR.mjs → chunk-S3KKBII4.mjs} +42 -30
  7. package/dist/chunk-S3KKBII4.mjs.map +1 -0
  8. package/dist/{chunk-QDMAQO2C.mjs → chunk-UBYSQI43.mjs} +2 -2
  9. package/dist/{chunk-NORCONUM.mjs → chunk-WTUPF3W3.mjs} +2 -2
  10. package/dist/{copilot-runtime-1a224a0f.d.ts → copilot-runtime-8c442d65.d.ts} +16 -3
  11. package/dist/graphql/types/converted/index.d.ts +1 -1
  12. package/dist/{groq-adapter-c35c5374.d.ts → groq-adapter-7a82cd22.d.ts} +21 -1
  13. package/dist/{index-24315d90.d.ts → index-a7f37670.d.ts} +1 -1
  14. package/dist/index.d.ts +4 -4
  15. package/dist/index.js +727 -348
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.mjs +5 -5
  18. package/dist/{langserve-a16ef8f4.d.ts → langserve-e308c437.d.ts} +32 -3
  19. package/dist/lib/index.d.ts +4 -4
  20. package/dist/lib/index.js +725 -346
  21. package/dist/lib/index.js.map +1 -1
  22. package/dist/lib/index.mjs +5 -5
  23. package/dist/lib/integrations/index.d.ts +4 -4
  24. package/dist/lib/integrations/index.js +504 -244
  25. package/dist/lib/integrations/index.js.map +1 -1
  26. package/dist/lib/integrations/index.mjs +5 -5
  27. package/dist/lib/integrations/nest/index.d.ts +3 -3
  28. package/dist/lib/integrations/nest/index.js +504 -244
  29. package/dist/lib/integrations/nest/index.js.map +1 -1
  30. package/dist/lib/integrations/nest/index.mjs +3 -3
  31. package/dist/lib/integrations/node-express/index.d.ts +3 -3
  32. package/dist/lib/integrations/node-express/index.js +504 -244
  33. package/dist/lib/integrations/node-express/index.js.map +1 -1
  34. package/dist/lib/integrations/node-express/index.mjs +3 -3
  35. package/dist/lib/integrations/node-http/index.d.ts +3 -3
  36. package/dist/lib/integrations/node-http/index.js +504 -244
  37. package/dist/lib/integrations/node-http/index.js.map +1 -1
  38. package/dist/lib/integrations/node-http/index.mjs +2 -2
  39. package/dist/service-adapters/index.d.ts +4 -4
  40. package/dist/service-adapters/index.js +23 -11
  41. package/dist/service-adapters/index.js.map +1 -1
  42. package/dist/service-adapters/index.mjs +1 -1
  43. package/package.json +2 -2
  44. package/src/graphql/inputs/extensions.input.ts +21 -0
  45. package/src/graphql/inputs/generate-copilot-response.input.ts +4 -0
  46. package/src/graphql/inputs/load-agent-state.input.ts +10 -0
  47. package/src/graphql/resolvers/copilot.resolver.ts +8 -3
  48. package/src/graphql/resolvers/state.resolver.ts +23 -0
  49. package/src/graphql/types/agents-response.type.ts +1 -4
  50. package/src/graphql/types/copilot-response.type.ts +5 -1
  51. package/src/graphql/types/extensions-response.type.ts +23 -0
  52. package/src/graphql/types/load-agent-state-response.type.ts +17 -0
  53. package/src/lib/integrations/shared.ts +2 -1
  54. package/src/lib/runtime/copilot-runtime.ts +155 -31
  55. package/src/lib/runtime/remote-action-constructors.ts +42 -33
  56. package/src/lib/runtime/remote-actions.ts +12 -7
  57. package/src/lib/runtime/remote-lg-action.ts +24 -12
  58. package/src/service-adapters/anthropic/anthropic-adapter.ts +2 -3
  59. package/src/service-adapters/empty/empty-adapter.ts +2 -2
  60. package/src/service-adapters/events.ts +5 -0
  61. package/src/service-adapters/experimental/ollama/ollama-adapter.ts +2 -2
  62. package/src/service-adapters/groq/groq-adapter.ts +2 -2
  63. package/src/service-adapters/langchain/langchain-adapter.ts +10 -3
  64. package/src/service-adapters/openai/openai-adapter.ts +4 -3
  65. package/src/service-adapters/openai/openai-assistant-adapter.ts +15 -4
  66. package/src/service-adapters/service-adapter.ts +4 -0
  67. package/src/service-adapters/unify/unify-adapter.ts +2 -3
  68. package/dist/chunk-MFDRA3BJ.mjs.map +0 -1
  69. package/dist/chunk-TPTCSIAR.mjs.map +0 -1
  70. /package/dist/{chunk-XRW7ZSWJ.mjs.map → chunk-DLESGNLO.mjs.map} +0 -0
  71. /package/dist/{chunk-QDMAQO2C.mjs.map → chunk-UBYSQI43.mjs.map} +0 -0
  72. /package/dist/{chunk-NORCONUM.mjs.map → chunk-WTUPF3W3.mjs.map} +0 -0
@@ -42,7 +42,6 @@ import {
42
42
  } from "../types/converted";
43
43
  import telemetry from "../../lib/telemetry-client";
44
44
  import { randomId } from "@copilotkit/shared";
45
- import { EndpointType, LangGraphPlatformAgent } from "../../lib/runtime/remote-actions";
46
45
  import { AgentsResponse } from "../types/agents-response.type";
47
46
 
48
47
  const invokeGuardrails = async ({
@@ -113,12 +112,14 @@ export class CopilotResolver {
113
112
  let logger = ctx.logger.child({ component: "CopilotResolver.availableAgents" });
114
113
 
115
114
  logger.debug("Processing");
116
- const agents = await ctx._copilotkit.runtime.discoverAgentsFromEndpoints(ctx);
115
+ const agentsWithEndpoints = await ctx._copilotkit.runtime.discoverAgentsFromEndpoints(ctx);
117
116
 
118
117
  logger.debug("Event source created, creating response");
119
118
 
120
119
  return {
121
- agents,
120
+ agents: agentsWithEndpoints.map(
121
+ ({ endpoint, ...agentWithoutEndpoint }) => agentWithoutEndpoint,
122
+ ),
122
123
  };
123
124
  }
124
125
 
@@ -192,6 +193,7 @@ export class CopilotResolver {
192
193
  runId,
193
194
  serverSideActions,
194
195
  actionInputsWithoutAgents,
196
+ extensions,
195
197
  } = await copilotRuntime.processRuntimeRequest({
196
198
  serviceAdapter,
197
199
  messages: data.messages,
@@ -207,6 +209,7 @@ export class CopilotResolver {
207
209
  agentSession: data.agentSession,
208
210
  agentStates: data.agentStates,
209
211
  url: data.frontend.url,
212
+ extensions: data.extensions,
210
213
  });
211
214
 
212
215
  logger.debug("Event source created, creating response");
@@ -215,6 +218,7 @@ export class CopilotResolver {
215
218
  threadId,
216
219
  runId,
217
220
  status: firstValueFrom(responseStatus$),
221
+ extensions,
218
222
  messages: new Repeater(async (pushMessage, stopStreamingMessages) => {
219
223
  logger.debug("Messages repeater created");
220
224
 
@@ -281,6 +285,7 @@ export class CopilotResolver {
281
285
  (action) =>
282
286
  !serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
283
287
  ),
288
+ threadId,
284
289
  })
285
290
  .pipe(
286
291
  // shareReplay() ensures that later subscribers will see the whole stream instead of
@@ -0,0 +1,23 @@
1
+ import { Arg, Resolver } from "type-graphql";
2
+ import { Ctx } from "type-graphql";
3
+ import { Query } from "type-graphql";
4
+ import { LoadAgentStateResponse } from "../types/load-agent-state-response.type";
5
+ import type { GraphQLContext } from "../../lib/integrations";
6
+ import { LoadAgentStateInput } from "../inputs/load-agent-state.input";
7
+
8
+ @Resolver(() => LoadAgentStateResponse)
9
+ export class StateResolver {
10
+ @Query(() => LoadAgentStateResponse)
11
+ async loadAgentState(@Ctx() ctx: GraphQLContext, @Arg("data") data: LoadAgentStateInput) {
12
+ const agents = await ctx._copilotkit.runtime.discoverAgentsFromEndpoints(ctx);
13
+ const agent = agents.find((agent) => agent.name === data.agentName);
14
+
15
+ if (!agent) {
16
+ throw new Error("Agent not found");
17
+ }
18
+
19
+ const state = await ctx._copilotkit.runtime.loadAgentState(ctx, data.threadId, data.agentName);
20
+
21
+ return state;
22
+ }
23
+ }
@@ -1,7 +1,4 @@
1
- import { Field, InterfaceType, ObjectType } from "type-graphql";
2
- import { MessageRole } from "./enums";
3
- import { MessageStatusUnion } from "./message-status.type";
4
- import { ResponseStatusUnion } from "./response-status.type";
1
+ import { Field, ObjectType } from "type-graphql";
5
2
 
6
3
  @ObjectType()
7
4
  export class Agent {
@@ -2,6 +2,7 @@ import { Field, InterfaceType, ObjectType } from "type-graphql";
2
2
  import { MessageRole } from "./enums";
3
3
  import { MessageStatusUnion } from "./message-status.type";
4
4
  import { ResponseStatusUnion } from "./response-status.type";
5
+ import { ExtensionsResponse } from "./extensions-response.type";
5
6
 
6
7
  @InterfaceType({
7
8
  resolveType(value) {
@@ -17,7 +18,7 @@ import { ResponseStatusUnion } from "./response-status.type";
17
18
  return undefined;
18
19
  },
19
20
  })
20
- abstract class BaseMessageOutput {
21
+ export abstract class BaseMessageOutput {
21
22
  @Field(() => String)
22
23
  id: string;
23
24
 
@@ -110,4 +111,7 @@ export class CopilotResponse {
110
111
 
111
112
  @Field(() => [BaseMessageOutput])
112
113
  messages: (typeof BaseMessageOutput)[];
114
+
115
+ @Field(() => ExtensionsResponse, { nullable: true })
116
+ extensions?: ExtensionsResponse;
113
117
  }
@@ -0,0 +1,23 @@
1
+ import { Field, ObjectType } from "type-graphql";
2
+
3
+ /**
4
+ * The extensions response is used to receive additional information from the copilot runtime, specific to a
5
+ * service adapter or agent framework.
6
+ *
7
+ * Next time a request to the runtime is made, the extensions response will be included in the request as input.
8
+ */
9
+
10
+ @ObjectType()
11
+ export class ExtensionsResponse {
12
+ @Field(() => OpenAIApiAssistantAPIResponse, { nullable: true })
13
+ openaiAssistantAPI?: OpenAIApiAssistantAPIResponse;
14
+ }
15
+
16
+ @ObjectType()
17
+ export class OpenAIApiAssistantAPIResponse {
18
+ @Field(() => String, { nullable: true })
19
+ runId?: string;
20
+
21
+ @Field(() => String, { nullable: true })
22
+ threadId?: string;
23
+ }
@@ -0,0 +1,17 @@
1
+ import { Field, ObjectType } from "type-graphql";
2
+ import { BaseMessageOutput } from "./copilot-response.type";
3
+
4
+ @ObjectType()
5
+ export class LoadAgentStateResponse {
6
+ @Field(() => String)
7
+ threadId: string;
8
+
9
+ @Field(() => Boolean)
10
+ threadExists: boolean;
11
+
12
+ @Field(() => String)
13
+ state: string;
14
+
15
+ @Field(() => String)
16
+ messages: string;
17
+ }
@@ -8,6 +8,7 @@ import { CopilotCloudOptions } from "../cloud";
8
8
  import { LogLevel, createLogger } from "../../lib/logger";
9
9
  import { createYoga } from "graphql-yoga";
10
10
  import telemetry from "../telemetry-client";
11
+ import { StateResolver } from "../../graphql/resolvers/state.resolver";
11
12
 
12
13
  const logger = createLogger();
13
14
 
@@ -58,7 +59,7 @@ export function buildSchema(
58
59
  ) {
59
60
  logger.debug("Building GraphQL schema...");
60
61
  const schema = buildSchemaSync({
61
- resolvers: [CopilotResolver],
62
+ resolvers: [CopilotResolver, StateResolver],
62
63
  emitSchemaFile: options.emitSchemaFile,
63
64
  });
64
65
  logger.debug("GraphQL schema built successfully");
@@ -12,7 +12,18 @@
12
12
  * ```
13
13
  */
14
14
 
15
- import { Action, actionParametersToJsonSchema, Parameter, randomId } from "@copilotkit/shared";
15
+ import {
16
+ Action,
17
+ actionParametersToJsonSchema,
18
+ Parameter,
19
+ ResolvedCopilotKitError,
20
+ CopilotKitApiDiscoveryError,
21
+ randomId,
22
+ CopilotKitError,
23
+ CopilotKitLowLevelError,
24
+ CopilotKitAgentDiscoveryError,
25
+ CopilotKitMisuseError,
26
+ } from "@copilotkit/shared";
16
27
  import {
17
28
  CopilotServiceAdapter,
18
29
  EmptyAdapter,
@@ -41,6 +52,11 @@ import { AgentStateInput } from "../../graphql/inputs/agent-state.input";
41
52
  import { ActionInputAvailability } from "../../graphql/types/enums";
42
53
  import { createHeaders } from "./remote-action-constructors";
43
54
  import { Agent } from "../../graphql/types/agents-response.type";
55
+ import { ExtensionsInput } from "../../graphql/inputs/extensions.input";
56
+ import { ExtensionsResponse } from "../../graphql/types/extensions-response.type";
57
+ import { LoadAgentStateResponse } from "../../graphql/types/load-agent-state-response.type";
58
+ import { Client as LangGraphClient } from "@langchain/langgraph-sdk";
59
+ import { langchainMessagesToCopilotKit } from "./remote-lg-action";
44
60
 
45
61
  interface CopilotRuntimeRequest {
46
62
  serviceAdapter: CopilotServiceAdapter;
@@ -55,6 +71,7 @@ interface CopilotRuntimeRequest {
55
71
  graphqlContext: GraphQLContext;
56
72
  forwardedParameters?: ForwardedParametersInput;
57
73
  url?: string;
74
+ extensions?: ExtensionsInput;
58
75
  }
59
76
 
60
77
  interface CopilotRuntimeResponse {
@@ -63,6 +80,7 @@ interface CopilotRuntimeResponse {
63
80
  eventSource: RuntimeEventSource;
64
81
  serverSideActions: Action<any>[];
65
82
  actionInputsWithoutAgents: ActionInput[];
83
+ extensions?: ExtensionsResponse;
66
84
  }
67
85
 
68
86
  type ActionsConfiguration<T extends Parameter[] | [] = []> =
@@ -102,6 +120,8 @@ interface Middleware {
102
120
  onAfterRequest?: OnAfterRequestHandler;
103
121
  }
104
122
 
123
+ type AgentWithEndpoint = Agent & { endpoint: EndpointDefinition };
124
+
105
125
  export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []> {
106
126
  /**
107
127
  * Middleware to be used by the runtime.
@@ -181,6 +201,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
181
201
  forwardedParameters,
182
202
  agentSession,
183
203
  url,
204
+ extensions,
184
205
  } = request;
185
206
 
186
207
  const eventSource = new RuntimeEventSource();
@@ -190,10 +211,11 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
190
211
  return await this.processAgentRequest(request);
191
212
  }
192
213
  if (serviceAdapter instanceof EmptyAdapter) {
193
- // TODO: use CPK error here
194
- throw new Error(`Invalid adapter configuration: EmptyAdapter is only meant to be used with agent lock mode.
214
+ throw new CopilotKitMisuseError({
215
+ message: `Invalid adapter configuration: EmptyAdapter is only meant to be used with agent lock mode.
195
216
  For non-agent components like useCopilotChatSuggestions, CopilotTextarea, or CopilotTask,
196
- please use an LLM adapter instead.`);
217
+ please use an LLM adapter instead.`,
218
+ });
197
219
  }
198
220
 
199
221
  const messages = rawMessages.filter((message) => !message.agentStateMessage);
@@ -230,12 +252,17 @@ please use an LLM adapter instead.`);
230
252
  runId,
231
253
  eventSource,
232
254
  forwardedParameters,
255
+ extensions,
233
256
  });
234
257
 
258
+ // for backwards compatibility, we deal with the case that no threadId is provided
259
+ // by the frontend, by using the threadId from the response
260
+ const nonEmptyThreadId = threadId ?? result.threadId;
261
+
235
262
  outputMessagesPromise
236
263
  .then((outputMessages) => {
237
264
  this.onAfterRequest?.({
238
- threadId: result.threadId,
265
+ threadId: nonEmptyThreadId,
239
266
  runId: result.runId,
240
267
  inputMessages,
241
268
  outputMessages,
@@ -246,7 +273,7 @@ please use an LLM adapter instead.`);
246
273
  .catch((_error) => {});
247
274
 
248
275
  return {
249
- threadId: result.threadId,
276
+ threadId: nonEmptyThreadId,
250
277
  runId: result.runId,
251
278
  eventSource,
252
279
  serverSideActions,
@@ -258,32 +285,37 @@ please use an LLM adapter instead.`);
258
285
  // serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
259
286
  // ),
260
287
  ),
288
+ extensions: result.extensions,
261
289
  };
262
290
  } catch (error) {
291
+ if (error instanceof CopilotKitError) {
292
+ throw error;
293
+ }
263
294
  console.error("Error getting response:", error);
264
295
  eventSource.sendErrorMessageToChat();
265
296
  throw error;
266
297
  }
267
298
  }
268
299
 
269
- async discoverAgentsFromEndpoints(graphqlContext: GraphQLContext): Promise<Agent[]> {
300
+ async discoverAgentsFromEndpoints(graphqlContext: GraphQLContext): Promise<AgentWithEndpoint[]> {
270
301
  const headers = createHeaders(null, graphqlContext);
271
302
  const agents = this.remoteEndpointDefinitions.reduce(
272
303
  async (acc: Promise<Agent[]>, endpoint) => {
273
304
  const agents = await acc;
274
305
  if (endpoint.type === EndpointType.LangGraphPlatform) {
275
- const response = await fetch(
276
- `${(endpoint as LangGraphPlatformEndpoint).deploymentUrl}/assistants/search`,
277
- {
278
- method: "POST",
279
- headers,
280
- },
281
- );
282
-
283
- const data: Array<{ assistant_id: string; graph_id: string }> = await response.json();
306
+ const client = new LangGraphClient({
307
+ apiUrl: endpoint.deploymentUrl,
308
+ apiKey: endpoint.langsmithApiKey,
309
+ });
310
+
311
+ const data: Array<{ assistant_id: string; graph_id: string }> =
312
+ await client.assistants.search();
313
+
284
314
  const endpointAgents = (data ?? []).map((entry) => ({
285
315
  name: entry.graph_id,
286
316
  id: entry.assistant_id,
317
+ description: "",
318
+ endpoint,
287
319
  }));
288
320
  return [...agents, ...endpointAgents];
289
321
  }
@@ -295,18 +327,34 @@ please use an LLM adapter instead.`);
295
327
  }>;
296
328
  }
297
329
 
298
- const response = await fetch(`${(endpoint as CopilotKitEndpoint).url}/info`, {
299
- method: "POST",
300
- headers,
301
- body: JSON.stringify({ properties: graphqlContext.properties }),
302
- });
303
- const data: InfoResponse = await response.json();
304
- const endpointAgents = (data?.agents ?? []).map((agent) => ({
305
- name: agent.name,
306
- description: agent.description,
307
- id: randomId(), // Required by Agent type
308
- }));
309
- return [...agents, ...endpointAgents];
330
+ const fetchUrl = `${(endpoint as CopilotKitEndpoint).url}/info`;
331
+ try {
332
+ const response = await fetch(fetchUrl, {
333
+ method: "POST",
334
+ headers,
335
+ body: JSON.stringify({ properties: graphqlContext.properties }),
336
+ });
337
+ if (!response.ok) {
338
+ if (response.status === 404) {
339
+ throw new CopilotKitApiDiscoveryError();
340
+ }
341
+ throw new ResolvedCopilotKitError({ status: response.status, isRemoteEndpoint: true });
342
+ }
343
+
344
+ const data: InfoResponse = await response.json();
345
+ const endpointAgents = (data?.agents ?? []).map((agent) => ({
346
+ name: agent.name,
347
+ description: agent.description ?? "" ?? "",
348
+ id: randomId(), // Required by Agent type
349
+ endpoint,
350
+ }));
351
+ return [...agents, ...endpointAgents];
352
+ } catch (error) {
353
+ if (error instanceof CopilotKitError) {
354
+ throw error;
355
+ }
356
+ throw new CopilotKitLowLevelError({ error: error as Error, url: fetchUrl });
357
+ }
310
358
  },
311
359
  Promise.resolve([]),
312
360
  );
@@ -314,11 +362,87 @@ please use an LLM adapter instead.`);
314
362
  return agents;
315
363
  }
316
364
 
365
+ async loadAgentState(
366
+ graphqlContext: GraphQLContext,
367
+ threadId: string,
368
+ agentName: string,
369
+ ): Promise<LoadAgentStateResponse> {
370
+ const agentsWithEndpoints = await this.discoverAgentsFromEndpoints(graphqlContext);
371
+
372
+ const agentWithEndpoint = agentsWithEndpoints.find((agent) => agent.name === agentName);
373
+ if (!agentWithEndpoint) {
374
+ throw new Error("Agent not found");
375
+ }
376
+ const headers = createHeaders(null, graphqlContext);
377
+
378
+ if (agentWithEndpoint.endpoint.type === EndpointType.LangGraphPlatform) {
379
+ const client = new LangGraphClient({
380
+ apiUrl: agentWithEndpoint.endpoint.deploymentUrl,
381
+ apiKey: agentWithEndpoint.endpoint.langsmithApiKey,
382
+ });
383
+ const state = (await client.threads.getState(threadId)).values as any;
384
+
385
+ if (Object.keys(state).length === 0) {
386
+ return {
387
+ threadId,
388
+ threadExists: false,
389
+ state: JSON.stringify({}),
390
+ messages: JSON.stringify([]),
391
+ };
392
+ } else {
393
+ console.log(state);
394
+ const { messages, ...stateWithoutMessages } = state;
395
+ const copilotkitMessages = langchainMessagesToCopilotKit(messages);
396
+ return {
397
+ threadId,
398
+ threadExists: true,
399
+ state: JSON.stringify(stateWithoutMessages),
400
+ messages: JSON.stringify(copilotkitMessages),
401
+ };
402
+ }
403
+ } else if (
404
+ agentWithEndpoint.endpoint.type === EndpointType.CopilotKit ||
405
+ !("type" in agentWithEndpoint.endpoint)
406
+ ) {
407
+ const response = await fetch(
408
+ `${(agentWithEndpoint.endpoint as CopilotKitEndpoint).url}/agents/state`,
409
+ {
410
+ method: "POST",
411
+ headers,
412
+ body: JSON.stringify({
413
+ properties: graphqlContext.properties,
414
+ threadId,
415
+ name: agentName,
416
+ }),
417
+ },
418
+ );
419
+ const data: LoadAgentStateResponse = await response.json();
420
+
421
+ return {
422
+ ...data,
423
+ state: JSON.stringify(data.state),
424
+ messages: JSON.stringify(data.messages),
425
+ };
426
+ } else {
427
+ throw new Error(`Unknown endpoint type: ${(agentWithEndpoint.endpoint as any).type}`);
428
+ }
429
+ }
430
+
317
431
  private async processAgentRequest(
318
432
  request: CopilotRuntimeRequest,
319
433
  ): Promise<CopilotRuntimeResponse> {
320
- const { messages: rawMessages, outputMessagesPromise, graphqlContext, agentSession } = request;
321
- const { threadId, agentName, nodeName } = agentSession;
434
+ const {
435
+ messages: rawMessages,
436
+ outputMessagesPromise,
437
+ graphqlContext,
438
+ agentSession,
439
+ threadId: threadIdFromRequest,
440
+ } = request;
441
+ const { agentName, nodeName } = agentSession;
442
+
443
+ // for backwards compatibility, deal with the case when no threadId is provided
444
+ const threadId = threadIdFromRequest ?? agentSession.threadId;
445
+
322
446
  const serverSideActions = await this.getServerSideActions(request);
323
447
 
324
448
  const messages = convertGqlInputToMessages(rawMessages);
@@ -328,7 +452,7 @@ please use an LLM adapter instead.`);
328
452
  ) as LangGraphAgentAction;
329
453
 
330
454
  if (!agent) {
331
- throw new Error(`Agent ${agentName} not found`);
455
+ throw new CopilotKitAgentDiscoveryError({ agentName });
332
456
  }
333
457
 
334
458
  const serverSideActionsInput: ActionInput[] = serverSideActions
@@ -16,6 +16,7 @@ import { RemoteLangGraphEventSource } from "../../agents/langgraph/event-source"
16
16
  import { Action } from "@copilotkit/shared";
17
17
  import { LangGraphEvent } from "../../agents/langgraph/events";
18
18
  import { execute } from "./remote-lg-action";
19
+ import { CopilotKitError, CopilotKitLowLevelError } from "@copilotkit/shared";
19
20
 
20
21
  export function constructLGCRemoteAction({
21
22
  endpoint,
@@ -126,8 +127,9 @@ export function constructRemoteActions({
126
127
  agentsAmount: totalAgents,
127
128
  });
128
129
 
130
+ const fetchUrl = `${url}/actions/execute`;
129
131
  try {
130
- const response = await fetch(`${url}/actions/execute`, {
132
+ const response = await fetch(fetchUrl, {
131
133
  method: "POST",
132
134
  headers,
133
135
  body: JSON.stringify({
@@ -151,11 +153,10 @@ export function constructRemoteActions({
151
153
  logger.debug({ actionName: action.name, result }, "Executed remote action");
152
154
  return result;
153
155
  } catch (error) {
154
- logger.error(
155
- { error: error.message ? error.message : error + "" },
156
- "Failed to execute remote action",
157
- );
158
- return "Failed to execute remote action";
156
+ if (error instanceof CopilotKitError) {
157
+ throw error;
158
+ }
159
+ throw new CopilotKitLowLevelError({ error, url: fetchUrl });
159
160
  }
160
161
  },
161
162
  }));
@@ -191,35 +192,43 @@ export function constructRemoteActions({
191
192
  }
192
193
  }
193
194
 
194
- const response = await fetch(`${url}/agents/execute`, {
195
- method: "POST",
196
- headers,
197
- body: JSON.stringify({
198
- name,
199
- threadId,
200
- nodeName,
201
- messages: [...messages, ...additionalMessages],
202
- state,
203
- properties: graphqlContext.properties,
204
- actions: actionInputsWithoutAgents.map((action) => ({
205
- name: action.name,
206
- description: action.description,
207
- parameters: JSON.parse(action.jsonSchema),
208
- })),
209
- }),
210
- });
195
+ const fetchUrl = `${url}/agents/execute`;
196
+ try {
197
+ const response = await fetch(fetchUrl, {
198
+ method: "POST",
199
+ headers,
200
+ body: JSON.stringify({
201
+ name,
202
+ threadId,
203
+ nodeName,
204
+ messages: [...messages, ...additionalMessages],
205
+ state,
206
+ properties: graphqlContext.properties,
207
+ actions: actionInputsWithoutAgents.map((action) => ({
208
+ name: action.name,
209
+ description: action.description,
210
+ parameters: JSON.parse(action.jsonSchema),
211
+ })),
212
+ }),
213
+ });
214
+
215
+ if (!response.ok) {
216
+ logger.error(
217
+ { url, status: response.status, body: await response.text() },
218
+ "Failed to execute remote agent",
219
+ );
220
+ throw new Error("Failed to execute remote agent");
221
+ }
211
222
 
212
- if (!response.ok) {
213
- logger.error(
214
- { url, status: response.status, body: await response.text() },
215
- "Failed to execute remote agent",
216
- );
217
- throw new Error("Failed to execute remote agent");
223
+ const eventSource = new RemoteLangGraphEventSource();
224
+ streamResponse(response.body!, eventSource.eventStream$);
225
+ return eventSource.processLangGraphEvents();
226
+ } catch (error) {
227
+ if (error instanceof CopilotKitError) {
228
+ throw error;
229
+ }
230
+ throw new CopilotKitLowLevelError({ error, url: fetchUrl });
218
231
  }
219
-
220
- const eventSource = new RemoteLangGraphEventSource();
221
- streamResponse(response.body!, eventSource.eventStream$);
222
- return eventSource.processLangGraphEvents();
223
232
  },
224
233
  }))
225
234
  : [];
@@ -11,6 +11,11 @@ import {
11
11
  constructRemoteActions,
12
12
  createHeaders,
13
13
  } from "./remote-action-constructors";
14
+ import {
15
+ CopilotKitLowLevelError,
16
+ ResolvedCopilotKitError,
17
+ CopilotKitError,
18
+ } from "@copilotkit/shared";
14
19
 
15
20
  export type EndpointDefinition = CopilotKitEndpoint | LangGraphPlatformEndpoint;
16
21
 
@@ -83,8 +88,9 @@ async function fetchRemoteInfo({
83
88
  logger.debug({ url }, "Fetching actions from url");
84
89
  const headers = createHeaders(onBeforeRequest, graphqlContext);
85
90
 
91
+ const fetchUrl = `${url}/info`;
86
92
  try {
87
- const response = await fetch(`${url}/info`, {
93
+ const response = await fetch(fetchUrl, {
88
94
  method: "POST",
89
95
  headers,
90
96
  body: JSON.stringify({ properties: graphqlContext.properties, frontendUrl }),
@@ -95,18 +101,17 @@ async function fetchRemoteInfo({
95
101
  { url, status: response.status, body: await response.text() },
96
102
  "Failed to fetch actions from url",
97
103
  );
98
- return { actions: [], agents: [] };
104
+ throw new ResolvedCopilotKitError({ status: response.status, isRemoteEndpoint: true });
99
105
  }
100
106
 
101
107
  const json = await response.json();
102
108
  logger.debug({ json }, "Fetched actions from url");
103
109
  return json;
104
110
  } catch (error) {
105
- logger.error(
106
- { error: error.message ? error.message : error + "" },
107
- "Failed to fetch actions from url",
108
- );
109
- return { actions: [], agents: [] };
111
+ if (error instanceof CopilotKitError) {
112
+ throw error;
113
+ }
114
+ throw new CopilotKitLowLevelError({ error, url: fetchUrl });
110
115
  }
111
116
  }
112
117