@copilotkit/runtime 1.2.1 → 1.2.2-feat-runtime-remote-actions.0

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 (75) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/__snapshots__/schema/schema.graphql +41 -0
  3. package/dist/{chunk-YMUS43FR.mjs → chunk-2N45GS3P.mjs} +2 -2
  4. package/dist/{chunk-URMISMK2.mjs → chunk-73NMP3DI.mjs} +2 -2
  5. package/dist/{chunk-736EEICU.mjs → chunk-BJ2LVHWA.mjs} +3 -3
  6. package/dist/{chunk-DMO6FA25.mjs → chunk-T6O5FSTK.mjs} +2 -2
  7. package/dist/{chunk-GEIBJJQ4.mjs → chunk-TBZGOJJX.mjs} +14 -2
  8. package/dist/chunk-TBZGOJJX.mjs.map +1 -0
  9. package/dist/{chunk-DYF5MUAH.mjs → chunk-X5QBBMCJ.mjs} +2 -2
  10. package/dist/{chunk-Q5ZTE7WH.mjs → chunk-XROLDARH.mjs} +786 -158
  11. package/dist/chunk-XROLDARH.mjs.map +1 -0
  12. package/dist/chunk-ZNZGATLW.mjs +260 -0
  13. package/dist/chunk-ZNZGATLW.mjs.map +1 -0
  14. package/dist/{shared-c5362338.d.ts → copilot-runtime-d427e991.d.ts} +65 -38
  15. package/dist/graphql/types/converted/index.d.ts +1 -1
  16. package/dist/graphql/types/converted/index.js +13 -0
  17. package/dist/graphql/types/converted/index.js.map +1 -1
  18. package/dist/graphql/types/converted/index.mjs +3 -1
  19. package/dist/{index-aa091e3c.d.ts → index-0476e4f7.d.ts} +24 -2
  20. package/dist/{index-13aa818e.d.ts → index-079752b9.d.ts} +1 -1
  21. package/dist/index.d.ts +7 -7
  22. package/dist/index.js +982 -245
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.mjs +8 -8
  25. package/dist/{langserve-a54438c6.d.ts → langserve-d6073a3b.d.ts} +24 -11
  26. package/dist/lib/index.d.ts +7 -7
  27. package/dist/lib/index.js +982 -245
  28. package/dist/lib/index.js.map +1 -1
  29. package/dist/lib/index.mjs +8 -8
  30. package/dist/lib/integrations/index.d.ts +6 -6
  31. package/dist/lib/integrations/index.js +437 -182
  32. package/dist/lib/integrations/index.js.map +1 -1
  33. package/dist/lib/integrations/index.mjs +6 -6
  34. package/dist/lib/integrations/nest/index.d.ts +5 -5
  35. package/dist/lib/integrations/nest/index.js +437 -182
  36. package/dist/lib/integrations/nest/index.js.map +1 -1
  37. package/dist/lib/integrations/nest/index.mjs +4 -4
  38. package/dist/lib/integrations/node-express/index.d.ts +5 -5
  39. package/dist/lib/integrations/node-express/index.js +437 -182
  40. package/dist/lib/integrations/node-express/index.js.map +1 -1
  41. package/dist/lib/integrations/node-express/index.mjs +4 -4
  42. package/dist/lib/integrations/node-http/index.d.ts +5 -5
  43. package/dist/lib/integrations/node-http/index.js +437 -182
  44. package/dist/lib/integrations/node-http/index.js.map +1 -1
  45. package/dist/lib/integrations/node-http/index.mjs +3 -3
  46. package/dist/service-adapters/index.d.ts +3 -3
  47. package/dist/service-adapters/index.js.map +1 -1
  48. package/dist/service-adapters/index.mjs +3 -3
  49. package/package.json +7 -5
  50. package/src/agents/langgraph/event-source.ts +222 -0
  51. package/src/agents/langgraph/events.ts +309 -0
  52. package/src/graphql/inputs/agent-session.input.ts +13 -0
  53. package/src/graphql/inputs/agent-state.input.ts +10 -0
  54. package/src/graphql/inputs/generate-copilot-response.input.ts +11 -0
  55. package/src/graphql/inputs/message.input.ts +30 -0
  56. package/src/graphql/resolvers/copilot.resolver.ts +56 -12
  57. package/src/graphql/types/converted/index.ts +15 -0
  58. package/src/graphql/types/copilot-response.type.ts +29 -0
  59. package/src/graphql/types/enums.ts +1 -0
  60. package/src/lib/index.ts +1 -1
  61. package/src/lib/integrations/shared.ts +1 -1
  62. package/src/lib/runtime/copilot-runtime.ts +360 -0
  63. package/src/lib/runtime/remote-actions.ts +241 -0
  64. package/src/service-adapters/conversion.ts +16 -0
  65. package/src/service-adapters/events.ts +101 -19
  66. package/dist/chunk-GEIBJJQ4.mjs.map +0 -1
  67. package/dist/chunk-PB24CCIJ.mjs +0 -158
  68. package/dist/chunk-PB24CCIJ.mjs.map +0 -1
  69. package/dist/chunk-Q5ZTE7WH.mjs.map +0 -1
  70. package/src/lib/copilot-runtime.ts +0 -231
  71. /package/dist/{chunk-YMUS43FR.mjs.map → chunk-2N45GS3P.mjs.map} +0 -0
  72. /package/dist/{chunk-URMISMK2.mjs.map → chunk-73NMP3DI.mjs.map} +0 -0
  73. /package/dist/{chunk-736EEICU.mjs.map → chunk-BJ2LVHWA.mjs.map} +0 -0
  74. /package/dist/{chunk-DMO6FA25.mjs.map → chunk-T6O5FSTK.mjs.map} +0 -0
  75. /package/dist/{chunk-DYF5MUAH.mjs.map → chunk-X5QBBMCJ.mjs.map} +0 -0
@@ -32,7 +32,13 @@ import {
32
32
  MessageStreamInterruptedResponse,
33
33
  UnknownErrorResponse,
34
34
  } from "../../utils";
35
- import { ActionExecutionMessage, Message, ResultMessage, TextMessage } from "../types/converted";
35
+ import {
36
+ ActionExecutionMessage,
37
+ AgentStateMessage,
38
+ Message,
39
+ ResultMessage,
40
+ TextMessage,
41
+ } from "../types/converted";
36
42
  import telemetry from "../../lib/telemetry-client";
37
43
  import { randomId } from "@copilotkit/shared";
38
44
 
@@ -49,8 +55,6 @@ const invokeGuardrails = async ({
49
55
  onResult: (result: GuardrailsResult) => void;
50
56
  onError: (err: Error) => void;
51
57
  }) => {
52
- console.log("invokeGuardrails.baseUrl", baseUrl);
53
-
54
58
  if (
55
59
  data.messages.length &&
56
60
  data.messages[data.messages.length - 1].textMessage?.role === MessageRole.user
@@ -116,14 +120,14 @@ export class CopilotResolver {
116
120
  let logger = ctx.logger.child({ component: "CopilotResolver.generateCopilotResponse" });
117
121
  logger.debug({ data }, "Generating Copilot response");
118
122
 
119
- const copilotRuntime = ctx._copilotkit.runtime;
120
- const serviceAdapter = ctx._copilotkit.serviceAdapter;
121
-
122
123
  if (properties) {
123
124
  logger.debug("Properties provided, merging with context properties");
124
125
  ctx.properties = { ...ctx.properties, ...properties };
125
126
  }
126
127
 
128
+ const copilotRuntime = ctx._copilotkit.runtime;
129
+ const serviceAdapter = ctx._copilotkit.serviceAdapter;
130
+
127
131
  let copilotCloudPublicApiKey: string | null = null;
128
132
  let copilotCloudBaseUrl: string;
129
133
 
@@ -169,17 +173,20 @@ export class CopilotResolver {
169
173
  eventSource,
170
174
  threadId = randomId(),
171
175
  runId,
172
- actions,
173
- } = await copilotRuntime.process({
176
+ serverSideActions,
177
+ actionInputsWithoutAgents,
178
+ } = await copilotRuntime.processRuntimeRequest({
174
179
  serviceAdapter,
175
180
  messages: data.messages,
176
181
  actions: data.frontend.actions,
177
182
  threadId: data.threadId,
178
183
  runId: data.runId,
179
184
  publicApiKey: undefined,
180
- properties: ctx.properties || {},
181
185
  outputMessagesPromise,
186
+ graphqlContext: ctx,
182
187
  forwardedParameters: data.forwardedParameters,
188
+ agentSession: data.agentSession,
189
+ agentStates: data.agentStates,
183
190
  url: data.frontend.url,
184
191
  });
185
192
 
@@ -247,9 +254,14 @@ export class CopilotResolver {
247
254
 
248
255
  // run and process the event stream
249
256
  const eventStream = eventSource
250
- .process({
251
- serversideActions: actions,
257
+ .processRuntimeEvents({
258
+ serverSideActions,
252
259
  guardrailsResult$: data.cloud?.guardrails ? guardrailsResult$ : null,
260
+ actionInputsWithoutAgents: actionInputsWithoutAgents.filter(
261
+ // TODO-AGENTS: do not exclude ALL server side actions
262
+ (action) =>
263
+ !serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
264
+ ),
253
265
  })
254
266
  .pipe(
255
267
  // shareReplay() ensures that later subscribers will see the whole stream instead of
@@ -281,7 +293,6 @@ export class CopilotResolver {
281
293
  const streamingTextStatus = new Subject<typeof MessageStatusUnion>();
282
294
 
283
295
  const messageId = randomId();
284
-
285
296
  // push the new message
286
297
  pushMessage({
287
298
  id: messageId,
@@ -433,6 +444,39 @@ export class CopilotResolver {
433
444
  }),
434
445
  );
435
446
  break;
447
+ ////////////////////////////////
448
+ // AgentStateMessage
449
+ ////////////////////////////////
450
+ case RuntimeEventTypes.AgentStateMessage:
451
+ logger.debug({ event }, "Agent message event received");
452
+ pushMessage({
453
+ id: randomId(),
454
+ status: new SuccessMessageStatus(),
455
+ threadId: event.threadId,
456
+ agentName: event.agentName,
457
+ nodeName: event.nodeName,
458
+ runId: event.runId,
459
+ active: event.active,
460
+ state: event.state,
461
+ running: event.running,
462
+ role: MessageRole.assistant,
463
+ createdAt: new Date(),
464
+ });
465
+ outputMessages.push(
466
+ plainToInstance(AgentStateMessage, {
467
+ id: randomId(),
468
+ threadId: event.threadId,
469
+ agentName: event.agentName,
470
+ nodeName: event.nodeName,
471
+ runId: event.runId,
472
+ active: event.active,
473
+ state: event.state,
474
+ running: event.running,
475
+ role: MessageRole.assistant,
476
+ createdAt: new Date(),
477
+ }),
478
+ );
479
+ break;
436
480
  }
437
481
  },
438
482
  error: (err) => {
@@ -2,6 +2,7 @@ import {
2
2
  ActionExecutionMessageInput,
3
3
  ResultMessageInput,
4
4
  TextMessageInput,
5
+ AgentStateMessageInput,
5
6
  } from "../../inputs/message.input";
6
7
  import { BaseMessage } from "../base";
7
8
  import { ActionExecutionScope, MessageRole } from "../enums";
@@ -27,3 +28,17 @@ export class ResultMessage extends BaseMessage implements ResultMessageInput {
27
28
  actionName: string;
28
29
  result: string;
29
30
  }
31
+
32
+ export class AgentStateMessage
33
+ extends BaseMessage
34
+ implements Omit<AgentStateMessageInput, "state">
35
+ {
36
+ threadId: string;
37
+ agentName: string;
38
+ nodeName: string;
39
+ runId: string;
40
+ active: boolean;
41
+ role: MessageRole;
42
+ state: any;
43
+ running: boolean;
44
+ }
@@ -11,6 +11,8 @@ import { ResponseStatusUnion } from "./response-status.type";
11
11
  return ActionExecutionMessageOutput;
12
12
  } else if (value.hasOwnProperty("result")) {
13
13
  return ResultMessageOutput;
14
+ } else if (value.hasOwnProperty("state")) {
15
+ return AgentStateMessageOutput;
14
16
  }
15
17
  return undefined;
16
18
  },
@@ -59,6 +61,33 @@ export class ResultMessageOutput {
59
61
  result: string;
60
62
  }
61
63
 
64
+ @ObjectType({ implements: BaseMessageOutput })
65
+ export class AgentStateMessageOutput {
66
+ @Field(() => String)
67
+ threadId: string;
68
+
69
+ @Field(() => String)
70
+ agentName: string;
71
+
72
+ @Field(() => String)
73
+ nodeName: string;
74
+
75
+ @Field(() => String)
76
+ runId: string;
77
+
78
+ @Field(() => Boolean)
79
+ active: boolean;
80
+
81
+ @Field(() => MessageRole)
82
+ role: MessageRole;
83
+
84
+ @Field(() => String)
85
+ state: string;
86
+
87
+ @Field(() => Boolean)
88
+ running: boolean;
89
+ }
90
+
62
91
  @ObjectType()
63
92
  export class CopilotResponse {
64
93
  @Field(() => String)
@@ -9,6 +9,7 @@ export enum MessageRole {
9
9
  export enum ActionExecutionScope {
10
10
  server = "server",
11
11
  client = "client",
12
+ passThrough = "passThrough",
12
13
  }
13
14
 
14
15
  export enum CopilotRequestType {
package/src/lib/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from "./copilot-runtime";
1
+ export * from "./runtime/copilot-runtime";
2
2
  export * from "../service-adapters/openai/openai-adapter";
3
3
  export * from "../service-adapters/langchain/langchain-adapter";
4
4
  export * from "../service-adapters/google/google-genai-adapter";
@@ -2,7 +2,7 @@ import { YogaInitialContext } from "graphql-yoga";
2
2
  import { buildSchemaSync } from "type-graphql";
3
3
  import { CopilotResolver } from "../../graphql/resolvers/copilot.resolver";
4
4
  import { useDeferStream } from "@graphql-yoga/plugin-defer-stream";
5
- import { CopilotRuntime } from "../copilot-runtime";
5
+ import { CopilotRuntime } from "../runtime/copilot-runtime";
6
6
  import { CopilotServiceAdapter } from "../../service-adapters";
7
7
  import { CopilotCloudOptions } from "../cloud";
8
8
  import { LogLevel, createLogger } from "../../lib/logger";
@@ -0,0 +1,360 @@
1
+ /**
2
+ * <Callout type="info">
3
+ * This is the reference for the `CopilotRuntime` class. For more information and example code snippets, please see [Concept: Copilot Runtime](/concepts/copilot-runtime).
4
+ * </Callout>
5
+ *
6
+ * ## Usage
7
+ *
8
+ * ```tsx
9
+ * import { CopilotRuntime } from "@copilotkit/runtime";
10
+ *
11
+ * const copilotKit = new CopilotRuntime();
12
+ * ```
13
+ */
14
+
15
+ import { Action, actionParametersToJsonSchema, Parameter, randomId } from "@copilotkit/shared";
16
+ import { RemoteChain, RemoteChainParameters, CopilotServiceAdapter } from "../../service-adapters";
17
+ import { MessageInput } from "../../graphql/inputs/message.input";
18
+ import { ActionInput } from "../../graphql/inputs/action.input";
19
+ import { RuntimeEventSource } from "../../service-adapters/events";
20
+ import { convertGqlInputToMessages } from "../../service-adapters/conversion";
21
+ import { AgentStateMessage, Message } from "../../graphql/types/converted";
22
+ import { ForwardedParametersInput } from "../../graphql/inputs/forwarded-parameters.input";
23
+ import {
24
+ setupRemoteActions,
25
+ RemoteActionDefinition,
26
+ LangGraphAgentAction,
27
+ isLangGraphAgentAction,
28
+ } from "./remote-actions";
29
+ import { GraphQLContext } from "../integrations/shared";
30
+ import { AgentSessionInput } from "../../graphql/inputs/agent-session.input";
31
+ import { from } from "rxjs";
32
+ import { AgentStateInput } from "../../graphql/inputs/agent-state.input";
33
+
34
+ interface CopilotRuntimeRequest {
35
+ serviceAdapter: CopilotServiceAdapter;
36
+ messages: MessageInput[];
37
+ actions: ActionInput[];
38
+ agentSession?: AgentSessionInput;
39
+ agentStates?: AgentStateInput[];
40
+ outputMessagesPromise: Promise<Message[]>;
41
+ threadId?: string;
42
+ runId?: string;
43
+ publicApiKey?: string;
44
+ graphqlContext: GraphQLContext;
45
+ forwardedParameters?: ForwardedParametersInput;
46
+ url?: string;
47
+ }
48
+
49
+ interface CopilotRuntimeResponse {
50
+ threadId: string;
51
+ runId?: string;
52
+ eventSource: RuntimeEventSource;
53
+ serverSideActions: Action<any>[];
54
+ actionInputsWithoutAgents: ActionInput[];
55
+ }
56
+
57
+ type ActionsConfiguration<T extends Parameter[] | [] = []> =
58
+ | Action<T>[]
59
+ | ((ctx: { properties: any; url?: string }) => Action<T>[]);
60
+
61
+ interface OnBeforeRequestOptions {
62
+ threadId?: string;
63
+ runId?: string;
64
+ inputMessages: Message[];
65
+ properties: any;
66
+ url?: string;
67
+ }
68
+
69
+ type OnBeforeRequestHandler = (options: OnBeforeRequestOptions) => void | Promise<void>;
70
+
71
+ interface OnAfterRequestOptions {
72
+ threadId: string;
73
+ runId?: string;
74
+ inputMessages: Message[];
75
+ outputMessages: Message[];
76
+ properties: any;
77
+ url?: string;
78
+ }
79
+
80
+ type OnAfterRequestHandler = (options: OnAfterRequestOptions) => void | Promise<void>;
81
+
82
+ interface Middleware {
83
+ /**
84
+ * A function that is called before the request is processed.
85
+ */
86
+ onBeforeRequest?: OnBeforeRequestHandler;
87
+
88
+ /**
89
+ * A function that is called after the request is processed.
90
+ */
91
+ onAfterRequest?: OnAfterRequestHandler;
92
+ }
93
+
94
+ export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []> {
95
+ /**
96
+ * Middleware to be used by the runtime.
97
+ *
98
+ * ```ts
99
+ * onBeforeRequest: (options: {
100
+ * threadId?: string;
101
+ * runId?: string;
102
+ * inputMessages: Message[];
103
+ * properties: any;
104
+ * }) => void | Promise<void>;
105
+ * ```
106
+ *
107
+ * ```ts
108
+ * onAfterRequest: (options: {
109
+ * threadId?: string;
110
+ * runId?: string;
111
+ * inputMessages: Message[];
112
+ * outputMessages: Message[];
113
+ * properties: any;
114
+ * }) => void | Promise<void>;
115
+ * ```
116
+ */
117
+ middleware?: Middleware;
118
+
119
+ /*
120
+ * A list of server side actions that can be executed.
121
+ */
122
+ actions?: ActionsConfiguration<T>;
123
+
124
+ /*
125
+ * A list of remote actions that can be executed.
126
+ */
127
+ remoteActions?: RemoteActionDefinition[];
128
+
129
+ /*
130
+ * An array of LangServer URLs.
131
+ */
132
+ langserve?: RemoteChainParameters[];
133
+ }
134
+
135
+ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
136
+ public actions: ActionsConfiguration<T>;
137
+ private remoteActionDefinitions: RemoteActionDefinition[];
138
+ private langserve: Promise<Action<any>>[] = [];
139
+ private onBeforeRequest?: OnBeforeRequestHandler;
140
+ private onAfterRequest?: OnAfterRequestHandler;
141
+
142
+ constructor(params?: CopilotRuntimeConstructorParams<T>) {
143
+ this.actions = params?.actions || [];
144
+
145
+ for (const chain of params?.langserve || []) {
146
+ const remoteChain = new RemoteChain(chain);
147
+ this.langserve.push(remoteChain.toAction());
148
+ }
149
+
150
+ this.remoteActionDefinitions = params?.remoteActions || [];
151
+
152
+ this.onBeforeRequest = params?.middleware?.onBeforeRequest;
153
+ this.onAfterRequest = params?.middleware?.onAfterRequest;
154
+ }
155
+
156
+ async processRuntimeRequest(request: CopilotRuntimeRequest): Promise<CopilotRuntimeResponse> {
157
+ const {
158
+ serviceAdapter,
159
+ messages: rawMessages,
160
+ actions: clientSideActionsInput,
161
+ threadId,
162
+ runId,
163
+ outputMessagesPromise,
164
+ graphqlContext,
165
+ forwardedParameters,
166
+ agentSession,
167
+ url,
168
+ } = request;
169
+
170
+ if (agentSession) {
171
+ return this.processAgentRequest(request);
172
+ }
173
+
174
+ const messages = rawMessages.filter((message) => !message.agentStateMessage);
175
+
176
+ const inputMessages = convertGqlInputToMessages(messages);
177
+ const serverSideActions = await this.getServerSideActions(request);
178
+
179
+ const serverSideActionsInput: ActionInput[] = serverSideActions.map((action) => ({
180
+ name: action.name,
181
+ description: action.description,
182
+ jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters)),
183
+ }));
184
+
185
+ const actionInputs = flattenToolCallsNoDuplicates([
186
+ ...serverSideActionsInput,
187
+ ...clientSideActionsInput,
188
+ ]);
189
+
190
+ await this.onBeforeRequest?.({
191
+ threadId,
192
+ runId,
193
+ inputMessages,
194
+ properties: graphqlContext.properties,
195
+ url,
196
+ });
197
+
198
+ try {
199
+ const eventSource = new RuntimeEventSource();
200
+
201
+ const result = await serviceAdapter.process({
202
+ messages: inputMessages,
203
+ actions: actionInputs,
204
+ threadId,
205
+ runId,
206
+ eventSource,
207
+ forwardedParameters,
208
+ });
209
+
210
+ outputMessagesPromise
211
+ .then((outputMessages) => {
212
+ this.onAfterRequest?.({
213
+ threadId: result.threadId,
214
+ runId: result.runId,
215
+ inputMessages,
216
+ outputMessages,
217
+ properties: graphqlContext.properties,
218
+ url,
219
+ });
220
+ })
221
+ .catch((_error) => {});
222
+
223
+ return {
224
+ threadId: result.threadId,
225
+ runId: result.runId,
226
+ eventSource,
227
+ serverSideActions,
228
+ actionInputsWithoutAgents: actionInputs.filter(
229
+ (action) =>
230
+ // TODO-AGENTS: do not exclude ALL server side actions
231
+ !serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
232
+ // !isLangGraphAgentAction(
233
+ // serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
234
+ // ),
235
+ ),
236
+ };
237
+ } catch (error) {
238
+ console.error("Error getting response:", error);
239
+ throw error;
240
+ }
241
+ }
242
+
243
+ private async processAgentRequest(
244
+ request: CopilotRuntimeRequest,
245
+ ): Promise<CopilotRuntimeResponse> {
246
+ const { messages: rawMessages, outputMessagesPromise, graphqlContext, agentSession } = request;
247
+ const { threadId = randomId(), agentName, nodeName } = agentSession;
248
+ const serverSideActions = await this.getServerSideActions(request);
249
+
250
+ const messages = convertGqlInputToMessages(rawMessages);
251
+
252
+ const agent = serverSideActions.find(
253
+ (action) => action.name === agentName && isLangGraphAgentAction(action),
254
+ ) as LangGraphAgentAction;
255
+
256
+ if (!agent) {
257
+ throw new Error(`Agent ${agentName} not found`);
258
+ }
259
+
260
+ const serverSideActionsInput: ActionInput[] = serverSideActions
261
+ .filter((action) => !isLangGraphAgentAction(action))
262
+ .map((action) => ({
263
+ name: action.name,
264
+ description: action.description,
265
+ jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters)),
266
+ }));
267
+
268
+ const actionInputsWithoutAgents = flattenToolCallsNoDuplicates([
269
+ ...serverSideActionsInput,
270
+ ...request.actions,
271
+ ]);
272
+
273
+ await this.onBeforeRequest?.({
274
+ threadId,
275
+ runId: undefined,
276
+ inputMessages: messages,
277
+ properties: graphqlContext.properties,
278
+ });
279
+ try {
280
+ const eventSource = new RuntimeEventSource();
281
+ const stream = await agent.langGraphAgentHandler({
282
+ name: agentName,
283
+ threadId,
284
+ nodeName,
285
+ actionInputsWithoutAgents,
286
+ });
287
+
288
+ eventSource.stream(async (eventStream$) => {
289
+ from(stream).subscribe({
290
+ next: (event) => eventStream$.next(event),
291
+ error: (err) => console.error("Error in stream", err),
292
+ complete: () => eventStream$.complete(),
293
+ });
294
+ });
295
+
296
+ outputMessagesPromise
297
+ .then((outputMessages) => {
298
+ this.onAfterRequest?.({
299
+ threadId,
300
+ runId: undefined,
301
+ inputMessages: messages,
302
+ outputMessages,
303
+ properties: graphqlContext.properties,
304
+ });
305
+ })
306
+ .catch((_error) => {});
307
+
308
+ return {
309
+ threadId,
310
+ runId: undefined,
311
+ eventSource,
312
+ serverSideActions: [],
313
+ actionInputsWithoutAgents,
314
+ };
315
+ } catch (error) {
316
+ console.error("Error getting response:", error);
317
+ throw error;
318
+ }
319
+ }
320
+
321
+ private async getServerSideActions(request: CopilotRuntimeRequest): Promise<Action<any>[]> {
322
+ const { messages: rawMessages, graphqlContext, agentStates, url } = request;
323
+ const inputMessages = convertGqlInputToMessages(rawMessages);
324
+ const langserveFunctions: Action<any>[] = [];
325
+
326
+ for (const chainPromise of this.langserve) {
327
+ try {
328
+ const chain = await chainPromise;
329
+ langserveFunctions.push(chain);
330
+ } catch (error) {
331
+ console.error("Error loading langserve chain:", error);
332
+ }
333
+ }
334
+ const remoteActions = await setupRemoteActions({
335
+ remoteActionDefinitions: this.remoteActionDefinitions,
336
+ graphqlContext,
337
+ messages: inputMessages,
338
+ agentStates,
339
+ });
340
+
341
+ const configuredActions =
342
+ typeof this.actions === "function"
343
+ ? this.actions({ properties: graphqlContext.properties, url })
344
+ : this.actions;
345
+
346
+ return [...configuredActions, ...langserveFunctions, ...remoteActions];
347
+ }
348
+ }
349
+
350
+ export function flattenToolCallsNoDuplicates(toolsByPriority: ActionInput[]): ActionInput[] {
351
+ let allTools: ActionInput[] = [];
352
+ const allToolNames: string[] = [];
353
+ for (const tool of toolsByPriority) {
354
+ if (!allToolNames.includes(tool.name)) {
355
+ allTools.push(tool);
356
+ allToolNames.push(tool.name);
357
+ }
358
+ }
359
+ return allTools;
360
+ }