@copilotkit/runtime 1.5.15-next.3 → 1.5.15-next.4

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 (52) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/__snapshots__/schema/schema.graphql +26 -0
  3. package/dist/{chunk-WPJHMQDF.mjs → chunk-6Z3DFNOC.mjs} +2 -2
  4. package/dist/{chunk-KPOZF6JI.mjs → chunk-EC2ZHPRU.mjs} +2 -2
  5. package/dist/{chunk-I2OII4XX.mjs → chunk-QDK4OP2Y.mjs} +2 -2
  6. package/dist/{chunk-EV3MMEAZ.mjs → chunk-W4G47FRC.mjs} +513 -295
  7. package/dist/chunk-W4G47FRC.mjs.map +1 -0
  8. package/dist/{copilot-runtime-e6c34790.d.ts → copilot-runtime-a113045f.d.ts} +13 -1
  9. package/dist/{groq-adapter-acb6ed0b.d.ts → groq-adapter-248058e8.d.ts} +1 -1
  10. package/dist/index.d.ts +3 -3
  11. package/dist/index.js +787 -571
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.mjs +4 -4
  14. package/dist/{langserve-9614171f.d.ts → langserve-9580bd66.d.ts} +16 -2
  15. package/dist/lib/index.d.ts +3 -3
  16. package/dist/lib/index.js +787 -571
  17. package/dist/lib/index.js.map +1 -1
  18. package/dist/lib/index.mjs +4 -4
  19. package/dist/lib/integrations/index.d.ts +3 -3
  20. package/dist/lib/integrations/index.js +500 -319
  21. package/dist/lib/integrations/index.js.map +1 -1
  22. package/dist/lib/integrations/index.mjs +4 -4
  23. package/dist/lib/integrations/nest/index.d.ts +2 -2
  24. package/dist/lib/integrations/nest/index.js +500 -319
  25. package/dist/lib/integrations/nest/index.js.map +1 -1
  26. package/dist/lib/integrations/nest/index.mjs +2 -2
  27. package/dist/lib/integrations/node-express/index.d.ts +2 -2
  28. package/dist/lib/integrations/node-express/index.js +500 -319
  29. package/dist/lib/integrations/node-express/index.js.map +1 -1
  30. package/dist/lib/integrations/node-express/index.mjs +2 -2
  31. package/dist/lib/integrations/node-http/index.d.ts +2 -2
  32. package/dist/lib/integrations/node-http/index.js +500 -319
  33. package/dist/lib/integrations/node-http/index.js.map +1 -1
  34. package/dist/lib/integrations/node-http/index.mjs +1 -1
  35. package/dist/service-adapters/index.d.ts +3 -3
  36. package/package.json +3 -3
  37. package/src/agents/langgraph/event-source.ts +14 -2
  38. package/src/agents/langgraph/events.ts +12 -1
  39. package/src/graphql/inputs/generate-copilot-response.input.ts +4 -0
  40. package/src/graphql/inputs/meta-event.input.ts +17 -0
  41. package/src/graphql/resolvers/copilot.resolver.ts +67 -22
  42. package/src/graphql/types/copilot-response.type.ts +6 -0
  43. package/src/graphql/types/meta-events.type.ts +31 -0
  44. package/src/lib/runtime/copilot-runtime.ts +4 -0
  45. package/src/lib/runtime/remote-action-constructors.ts +5 -1
  46. package/src/lib/runtime/remote-actions.ts +2 -0
  47. package/src/lib/runtime/remote-lg-action.ts +35 -8
  48. package/src/service-adapters/events.ts +20 -1
  49. package/dist/chunk-EV3MMEAZ.mjs.map +0 -1
  50. /package/dist/{chunk-WPJHMQDF.mjs.map → chunk-6Z3DFNOC.mjs.map} +0 -0
  51. /package/dist/{chunk-KPOZF6JI.mjs.map → chunk-EC2ZHPRU.mjs.map} +0 -0
  52. /package/dist/{chunk-I2OII4XX.mjs.map → chunk-QDK4OP2Y.mjs.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  copilotRuntimeNodeHttpEndpoint
3
- } from "../../../chunk-EV3MMEAZ.mjs";
3
+ } from "../../../chunk-W4G47FRC.mjs";
4
4
  import "../../../chunk-S3KKBII4.mjs";
5
5
  import "../../../chunk-U3V2BCGI.mjs";
6
6
  import "../../../chunk-HNUNXFTW.mjs";
@@ -1,6 +1,6 @@
1
- import { b as CopilotServiceAdapter, C as CopilotRuntimeChatCompletionRequest, a as CopilotRuntimeChatCompletionResponse } from '../langserve-9614171f.js';
2
- export { c as RemoteChain, R as RemoteChainParameters } from '../langserve-9614171f.js';
3
- export { G as GoogleGenerativeAIAdapter, f as GroqAdapter, e as GroqAdapterParams, L as LangChainAdapter, a as OpenAIAdapter, O as OpenAIAdapterParams, c as OpenAIAssistantAdapter, b as OpenAIAssistantAdapterParams, d as UnifyAdapter, U as UnifyAdapterParams } from '../groq-adapter-acb6ed0b.js';
1
+ import { b as CopilotServiceAdapter, C as CopilotRuntimeChatCompletionRequest, a as CopilotRuntimeChatCompletionResponse } from '../langserve-9580bd66.js';
2
+ export { c as RemoteChain, R as RemoteChainParameters } from '../langserve-9580bd66.js';
3
+ export { G as GoogleGenerativeAIAdapter, f as GroqAdapter, e as GroqAdapterParams, L as LangChainAdapter, a as OpenAIAdapter, O as OpenAIAdapterParams, c as OpenAIAssistantAdapter, b as OpenAIAssistantAdapterParams, d as UnifyAdapter, U as UnifyAdapterParams } from '../groq-adapter-248058e8.js';
4
4
  import Anthropic from '@anthropic-ai/sdk';
5
5
  import '../index-a7f37670.js';
6
6
  import '../graphql/types/base/index.js';
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "publishConfig": {
10
10
  "access": "public"
11
11
  },
12
- "version": "1.5.15-next.3",
12
+ "version": "1.5.15-next.4",
13
13
  "sideEffects": false,
14
14
  "main": "./dist/index.js",
15
15
  "module": "./dist/index.mjs",
@@ -41,7 +41,7 @@
41
41
  "@langchain/community": "^0.0.53",
42
42
  "@langchain/core": "^0.3.13",
43
43
  "@langchain/google-gauth": "^0.1.0",
44
- "@langchain/langgraph-sdk": "^0.0.16",
44
+ "@langchain/langgraph-sdk": "^0.0.36",
45
45
  "@langchain/openai": "^0.0.28",
46
46
  "class-transformer": "^0.5.1",
47
47
  "express": "^4.19.2",
@@ -58,7 +58,7 @@
58
58
  "rxjs": "^7.8.1",
59
59
  "type-graphql": "2.0.0-rc.1",
60
60
  "zod": "^3.23.3",
61
- "@copilotkit/shared": "1.5.15-next.3"
61
+ "@copilotkit/shared": "1.5.15-next.4"
62
62
  },
63
63
  "keywords": [
64
64
  "copilotkit",
@@ -1,6 +1,10 @@
1
- import { ReplaySubject, scan, mergeMap, catchError } from "rxjs";
1
+ import { catchError, mergeMap, ReplaySubject, scan } from "rxjs";
2
2
  import { CustomEventNames, LangGraphEvent, LangGraphEventTypes } from "./events";
3
- import { RuntimeEvent, RuntimeEventTypes } from "../../service-adapters/events";
3
+ import {
4
+ RuntimeEvent,
5
+ RuntimeEventTypes,
6
+ RuntimeMetaEventName,
7
+ } from "../../service-adapters/events";
4
8
  import { randomId } from "@copilotkit/shared";
5
9
 
6
10
  interface LangGraphEventWithState {
@@ -125,6 +129,14 @@ export class RemoteLangGraphEventSource {
125
129
  }
126
130
  }
127
131
 
132
+ if (acc.event.event === LangGraphEventTypes.OnInterrupt) {
133
+ events.push({
134
+ type: RuntimeEventTypes.MetaEvent,
135
+ name: RuntimeMetaEventName.LangGraphInterruptEvent,
136
+ value: acc.event.value,
137
+ });
138
+ }
139
+
128
140
  const responseMetadata = this.getResponseMetadata(acc.event);
129
141
 
130
142
  // Tool call ended: emit ActionExecutionEnd
@@ -11,6 +11,11 @@ export enum LangGraphEventTypes {
11
11
  OnCopilotKitEmitMessage = "on_copilotkit_emit_message",
12
12
  OnCopilotKitEmitToolCall = "on_copilotkit_emit_tool_call",
13
13
  OnCustomEvent = "on_custom_event",
14
+ OnInterrupt = "on_interrupt",
15
+ }
16
+
17
+ export enum MetaEventNames {
18
+ LangGraphInterruptEvent = "LangGraphInterruptEvent",
14
19
  }
15
20
 
16
21
  export enum CustomEventNames {
@@ -325,6 +330,11 @@ type LangGraphOnCustomEvent = {
325
330
  parent_ids: string[];
326
331
  };
327
332
 
333
+ interface LangGraphInterruptEvent {
334
+ event: LangGraphEventTypes.OnInterrupt;
335
+ value: string;
336
+ }
337
+
328
338
  export type LangGraphEvent =
329
339
  | LangGraphOnChainStartEvent
330
340
  | LangGraphOnChainStreamEvent
@@ -335,4 +345,5 @@ export type LangGraphEvent =
335
345
  | LangGraphOnToolStartEvent
336
346
  | LangGraphOnToolEndEvent
337
347
  | LangGraphOnCopilotKitStateSyncEvent
338
- | LangGraphOnCustomEvent;
348
+ | LangGraphOnCustomEvent
349
+ | LangGraphInterruptEvent;
@@ -7,6 +7,7 @@ import { ForwardedParametersInput } from "./forwarded-parameters.input";
7
7
  import { AgentSessionInput } from "./agent-session.input";
8
8
  import { AgentStateInput } from "./agent-state.input";
9
9
  import { ExtensionsInput } from "./extensions.input";
10
+ import { MetaEventInput } from "./meta-event.input";
10
11
 
11
12
  @InputType()
12
13
  export class GenerateCopilotResponseMetadataInput {
@@ -48,4 +49,7 @@ export class GenerateCopilotResponseInput {
48
49
 
49
50
  @Field(() => ExtensionsInput, { nullable: true })
50
51
  extensions?: ExtensionsInput;
52
+
53
+ @Field(() => [MetaEventInput], { nullable: true })
54
+ metaEvents?: MetaEventInput[];
51
55
  }
@@ -0,0 +1,17 @@
1
+ import { Field, InputType } from "type-graphql";
2
+ import { MetaEventName } from "../types/meta-events.type";
3
+
4
+ @InputType()
5
+ export class MetaEventInput {
6
+ @Field(() => String)
7
+ type: "MetaEvent" = "MetaEvent";
8
+
9
+ @Field(() => MetaEventName)
10
+ name: MetaEventName;
11
+
12
+ @Field(() => String)
13
+ value?: string;
14
+
15
+ @Field(() => String, { nullable: true })
16
+ response?: string;
17
+ }
@@ -14,10 +14,15 @@ import {
14
14
  } from "rxjs";
15
15
  import { GenerateCopilotResponseInput } from "../inputs/generate-copilot-response.input";
16
16
  import { CopilotResponse } from "../types/copilot-response.type";
17
+ import { LangGraphInterruptEvent } from "../types/meta-events.type";
17
18
  import { ActionInputAvailability, MessageRole } from "../types/enums";
18
19
  import { Repeater } from "graphql-yoga";
19
20
  import type { CopilotRequestContextProperties, GraphQLContext } from "../../lib/integrations";
20
- import { RuntimeEvent, RuntimeEventTypes } from "../../service-adapters/events";
21
+ import {
22
+ RuntimeEvent,
23
+ RuntimeEventTypes,
24
+ RuntimeMetaEventName,
25
+ } from "../../service-adapters/events";
21
26
  import {
22
27
  FailedMessageStatus,
23
28
  MessageStatusUnion,
@@ -210,15 +215,74 @@ export class CopilotResolver {
210
215
  agentStates: data.agentStates,
211
216
  url: data.frontend.url,
212
217
  extensions: data.extensions,
218
+ metaEvents: data.metaEvents,
213
219
  });
214
220
 
215
221
  logger.debug("Event source created, creating response");
222
+ // run and process the event stream
223
+ const eventStream = eventSource
224
+ .processRuntimeEvents({
225
+ serverSideActions,
226
+ guardrailsResult$: data.cloud?.guardrails ? guardrailsResult$ : null,
227
+ actionInputsWithoutAgents: actionInputsWithoutAgents.filter(
228
+ // TODO-AGENTS: do not exclude ALL server side actions
229
+ (action) =>
230
+ !serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
231
+ ),
232
+ threadId,
233
+ })
234
+ .pipe(
235
+ // shareReplay() ensures that later subscribers will see the whole stream instead of
236
+ // just the events that were emitted after the subscriber was added.
237
+ shareReplay(),
238
+ finalize(() => {
239
+ logger.debug("Event stream finalized");
240
+ }),
241
+ );
216
242
 
217
243
  const response = {
218
244
  threadId,
219
245
  runId,
220
246
  status: firstValueFrom(responseStatus$),
221
247
  extensions,
248
+ metaEvents: new Repeater(async (push, stop) => {
249
+ let eventStreamSubscription: Subscription;
250
+
251
+ eventStreamSubscription = eventStream.subscribe({
252
+ next: async (event) => {
253
+ if (event.type != RuntimeEventTypes.MetaEvent) {
254
+ return;
255
+ }
256
+ switch (event.name) {
257
+ case RuntimeMetaEventName.LangGraphInterruptEvent:
258
+ push(
259
+ plainToInstance(LangGraphInterruptEvent, {
260
+ type: event.type,
261
+ name: event.name,
262
+ value: event.value,
263
+ }),
264
+ );
265
+ break;
266
+ }
267
+ },
268
+ error: (err) => {
269
+ logger.error({ err }, "Error in meta events stream");
270
+ responseStatus$.next(
271
+ new UnknownErrorResponse({
272
+ description: `An unknown error has occurred in the event stream`,
273
+ }),
274
+ );
275
+ eventStreamSubscription?.unsubscribe();
276
+ stop();
277
+ },
278
+ complete: async () => {
279
+ logger.debug("Meta events stream completed");
280
+ responseStatus$.next(new SuccessResponseStatus());
281
+ eventStreamSubscription?.unsubscribe();
282
+ stop();
283
+ },
284
+ });
285
+ }),
222
286
  messages: new Repeater(async (pushMessage, stopStreamingMessages) => {
223
287
  logger.debug("Messages repeater created");
224
288
 
@@ -275,32 +339,13 @@ export class CopilotResolver {
275
339
 
276
340
  let eventStreamSubscription: Subscription;
277
341
 
278
- // run and process the event stream
279
- const eventStream = eventSource
280
- .processRuntimeEvents({
281
- serverSideActions,
282
- guardrailsResult$: data.cloud?.guardrails ? guardrailsResult$ : null,
283
- actionInputsWithoutAgents: actionInputsWithoutAgents.filter(
284
- // TODO-AGENTS: do not exclude ALL server side actions
285
- (action) =>
286
- !serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
287
- ),
288
- threadId,
289
- })
290
- .pipe(
291
- // shareReplay() ensures that later subscribers will see the whole stream instead of
292
- // just the events that were emitted after the subscriber was added.
293
- shareReplay(),
294
- finalize(() => {
295
- logger.debug("Event stream finalized");
296
- }),
297
- );
298
-
299
342
  logger.debug("Event stream created, subscribing to event stream");
300
343
 
301
344
  eventStreamSubscription = eventStream.subscribe({
302
345
  next: async (event) => {
303
346
  switch (event.type) {
347
+ case RuntimeEventTypes.MetaEvent:
348
+ break;
304
349
  ////////////////////////////////
305
350
  // TextMessageStart
306
351
  ////////////////////////////////
@@ -3,6 +3,7 @@ import { MessageRole } from "./enums";
3
3
  import { MessageStatusUnion } from "./message-status.type";
4
4
  import { ResponseStatusUnion } from "./response-status.type";
5
5
  import { ExtensionsResponse } from "./extensions-response.type";
6
+ import { BaseMetaEvent, LangGraphInterruptEvent, MetaEventName } from "./meta-events.type";
6
7
 
7
8
  @InterfaceType({
8
9
  resolveType(value) {
@@ -14,6 +15,8 @@ import { ExtensionsResponse } from "./extensions-response.type";
14
15
  return ResultMessageOutput;
15
16
  } else if (value.hasOwnProperty("state")) {
16
17
  return AgentStateMessageOutput;
18
+ } else if (value.name === MetaEventName.LangGraphInterruptEvent) {
19
+ return LangGraphInterruptEvent;
17
20
  }
18
21
  return undefined;
19
22
  },
@@ -114,4 +117,7 @@ export class CopilotResponse {
114
117
 
115
118
  @Field(() => ExtensionsResponse, { nullable: true })
116
119
  extensions?: ExtensionsResponse;
120
+
121
+ @Field(() => [BaseMetaEvent], { nullable: true })
122
+ metaEvents?: (typeof BaseMetaEvent)[];
117
123
  }
@@ -0,0 +1,31 @@
1
+ import { Field, InterfaceType, ObjectType, registerEnumType } from "type-graphql";
2
+
3
+ export enum MetaEventName {
4
+ LangGraphInterruptEvent = "LangGraphInterruptEvent",
5
+ }
6
+
7
+ registerEnumType(MetaEventName, {
8
+ name: "MetaEventName",
9
+ description: "Meta event types",
10
+ });
11
+
12
+ @InterfaceType()
13
+ export abstract class BaseMetaEvent {
14
+ @Field(() => String)
15
+ type: "MetaEvent" = "MetaEvent";
16
+
17
+ @Field(() => MetaEventName)
18
+ name: MetaEventName;
19
+ }
20
+
21
+ @ObjectType({ implements: BaseMetaEvent })
22
+ export class LangGraphInterruptEvent {
23
+ @Field(() => MetaEventName)
24
+ name: MetaEventName.LangGraphInterruptEvent = MetaEventName.LangGraphInterruptEvent;
25
+
26
+ @Field(() => String)
27
+ value: string;
28
+
29
+ @Field(() => String, { nullable: true })
30
+ response?: string;
31
+ }
@@ -60,6 +60,7 @@ import { ExtensionsResponse } from "../../graphql/types/extensions-response.type
60
60
  import { LoadAgentStateResponse } from "../../graphql/types/load-agent-state-response.type";
61
61
  import { Client as LangGraphClient } from "@langchain/langgraph-sdk";
62
62
  import { langchainMessagesToCopilotKit } from "./remote-lg-action";
63
+ import { MetaEventInput } from "../../graphql/inputs/meta-event.input";
63
64
 
64
65
  interface CopilotRuntimeRequest {
65
66
  serviceAdapter: CopilotServiceAdapter;
@@ -75,6 +76,7 @@ interface CopilotRuntimeRequest {
75
76
  forwardedParameters?: ForwardedParametersInput;
76
77
  url?: string;
77
78
  extensions?: ExtensionsInput;
79
+ metaEvents?: MetaEventInput[];
78
80
  }
79
81
 
80
82
  interface CopilotRuntimeResponse {
@@ -465,6 +467,7 @@ please use an LLM adapter instead.`,
465
467
  graphqlContext,
466
468
  agentSession,
467
469
  threadId: threadIdFromRequest,
470
+ metaEvents,
468
471
  } = request;
469
472
  const { agentName, nodeName } = agentSession;
470
473
 
@@ -509,6 +512,7 @@ please use an LLM adapter instead.`,
509
512
  threadId,
510
513
  nodeName,
511
514
  actionInputsWithoutAgents,
515
+ metaEvents,
512
516
  });
513
517
 
514
518
  eventSource.stream(async (eventStream$) => {
@@ -42,6 +42,7 @@ export function constructLGCRemoteAction({
42
42
  threadId,
43
43
  nodeName,
44
44
  additionalMessages = [],
45
+ metaEvents,
45
46
  }: LangGraphAgentHandlerParams): Promise<Observable<RuntimeEvent>> => {
46
47
  logger.debug({ actionName: agent.name }, "Executing LangGraph Platform agent");
47
48
 
@@ -62,7 +63,7 @@ export function constructLGCRemoteAction({
62
63
 
63
64
  try {
64
65
  const response = await execute({
65
- logger,
66
+ logger: logger.child({ component: "remote-actions.remote-lg-action.streamEvents" }),
66
67
  deploymentUrl: endpoint.deploymentUrl,
67
68
  langsmithApiKey: endpoint.langsmithApiKey,
68
69
  agent,
@@ -76,6 +77,7 @@ export function constructLGCRemoteAction({
76
77
  description: action.description,
77
78
  parameters: JSON.parse(action.jsonSchema) as string,
78
79
  })),
80
+ metaEvents,
79
81
  });
80
82
 
81
83
  const eventSource = new RemoteLangGraphEventSource();
@@ -174,6 +176,7 @@ export function constructRemoteActions({
174
176
  threadId,
175
177
  nodeName,
176
178
  additionalMessages = [],
179
+ metaEvents,
177
180
  }: LangGraphAgentHandlerParams): Promise<Observable<RuntimeEvent>> => {
178
181
  logger.debug({ actionName: agent.name }, "Executing remote agent");
179
182
 
@@ -209,6 +212,7 @@ export function constructRemoteActions({
209
212
  description: action.description,
210
213
  parameters: JSON.parse(action.jsonSchema),
211
214
  })),
215
+ metaEvents,
212
216
  }),
213
217
  });
214
218
 
@@ -16,6 +16,7 @@ import {
16
16
  ResolvedCopilotKitError,
17
17
  CopilotKitError,
18
18
  } from "@copilotkit/shared";
19
+ import { MetaEventInput } from "../../graphql/inputs/meta-event.input";
19
20
 
20
21
  export type EndpointDefinition = CopilotKitEndpoint | LangGraphPlatformEndpoint;
21
22
 
@@ -59,6 +60,7 @@ export type LangGraphAgentHandlerParams = {
59
60
  threadId?: string;
60
61
  nodeName?: string;
61
62
  additionalMessages?: Message[];
63
+ metaEvents?: MetaEventInput[];
62
64
  };
63
65
 
64
66
  export type LangGraphAgentAction = Action<any> & {
@@ -1,6 +1,6 @@
1
1
  import { Client as LangGraphClient } from "@langchain/langgraph-sdk";
2
2
  import { createHash } from "node:crypto";
3
- import { randomUUID, isValidUUID } from "@copilotkit/shared";
3
+ import { isValidUUID, randomUUID } from "@copilotkit/shared";
4
4
  import { parse as parsePartialJson } from "partial-json";
5
5
  import { Logger } from "pino";
6
6
  import { ActionInput } from "../../graphql/inputs/action.input";
@@ -10,6 +10,9 @@ import { ActionExecutionMessage, Message, MessageType } from "../../graphql/type
10
10
  import { MessageRole } from "../../graphql/types/enums";
11
11
  import { CustomEventNames, LangGraphEventTypes } from "../../agents/langgraph/events";
12
12
  import telemetry from "../telemetry-client";
13
+ import { MetaEventInput } from "../../graphql/inputs/meta-event.input";
14
+ import { MetaEventName } from "../../graphql/types/meta-events.type";
15
+ import { RunsStreamPayload } from "@langchain/langgraph-sdk/dist/types";
13
16
 
14
17
  type State = Record<string, any>;
15
18
 
@@ -24,6 +27,7 @@ interface ExecutionArgs extends Omit<LangGraphPlatformEndpoint, "agents"> {
24
27
  properties: CopilotRequestContextProperties;
25
28
  actions: ExecutionAction[];
26
29
  logger: Logger;
30
+ metaEvents?: MetaEventInput[];
27
31
  }
28
32
 
29
33
  // The following types are our own definition to the messages accepted by LangGraph Platform, enhanced with some of our extra data.
@@ -85,6 +89,7 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
85
89
  actions,
86
90
  logger,
87
91
  properties,
92
+ metaEvents,
88
93
  } = args;
89
94
 
90
95
  let nodeName = initialNodeName;
@@ -139,7 +144,11 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
139
144
  }
140
145
  state = langGraphDefaultMergeState(state, formattedMessages, actions, name);
141
146
 
142
- if (mode === "continue") {
147
+ const lgInterruptEvent = metaEvents?.find(
148
+ (ev) => ev.name === MetaEventName.LangGraphInterruptEvent,
149
+ );
150
+
151
+ if (mode === "continue" && !lgInterruptEvent) {
143
152
  await client.threads.updateState(threadId, { values: state, asNode: nodeName });
144
153
  }
145
154
 
@@ -180,10 +189,16 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
180
189
  let shouldExit = false;
181
190
  let externalRunId = null;
182
191
 
183
- const streamResponse = client.runs.stream(threadId, assistantId, {
192
+ const payload: RunsStreamPayload = {
184
193
  input: streamInput,
185
- streamMode: ["events", "values"],
186
- });
194
+ streamMode: ["events", "values", "updates"],
195
+ command: undefined,
196
+ };
197
+
198
+ if (lgInterruptEvent?.response) {
199
+ payload.command = { resume: lgInterruptEvent.response };
200
+ }
201
+ const streamResponse = client.runs.stream(threadId, assistantId, payload);
187
202
 
188
203
  const emit = (message: string) => controller.enqueue(new TextEncoder().encode(message));
189
204
 
@@ -198,12 +213,23 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
198
213
  hashedLgcKey: streamInfo.hashedLgcKey,
199
214
  });
200
215
  for await (const chunk of streamResponse) {
201
- if (!["events", "values", "error"].includes(chunk.event)) continue;
216
+ if (!["events", "values", "error", "updates"].includes(chunk.event)) continue;
202
217
 
203
218
  if (chunk.event === "error") {
204
219
  throw new Error(`Error event thrown: ${chunk.data.message}`);
205
220
  }
206
221
 
222
+ if (chunk.event === "updates" && chunk.data.__interrupt__) {
223
+ emit(
224
+ JSON.stringify({
225
+ event: LangGraphEventTypes.OnInterrupt,
226
+ value: chunk.data.__interrupt__[0].value,
227
+ }) + "\n",
228
+ );
229
+ continue;
230
+ }
231
+ if (chunk.event === "updates") continue;
232
+
207
233
  if (chunk.event === "values") {
208
234
  latestStateValues = chunk.data;
209
235
  continue;
@@ -326,8 +352,9 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
326
352
  }
327
353
 
328
354
  state = await client.threads.getState(threadId);
329
- const isEndNode = state.next.length === 0;
330
- nodeName = Object.keys(state.metadata.writes)[0];
355
+ const interrupts = state.tasks?.[0]?.interrupts;
356
+ nodeName = interrupts ? nodeName : Object.keys(state.metadata.writes)[0];
357
+ const isEndNode = state.next.length === 0 && !interrupts;
331
358
 
332
359
  telemetry.capture("oss.runtime.agent_execution_stream_ended", streamInfo);
333
360
 
@@ -28,8 +28,26 @@ export enum RuntimeEventTypes {
28
28
  ActionExecutionEnd = "ActionExecutionEnd",
29
29
  ActionExecutionResult = "ActionExecutionResult",
30
30
  AgentStateMessage = "AgentStateMessage",
31
+ MetaEvent = "MetaEvent",
31
32
  }
32
33
 
34
+ export enum RuntimeMetaEventName {
35
+ LangGraphInterruptEvent = "LangGraphInterruptEvent",
36
+ LangGraphInterruptResumeEvent = "LangGraphInterruptResumeEvent",
37
+ }
38
+
39
+ export type RunTimeMetaEvent =
40
+ | {
41
+ type: RuntimeEventTypes.MetaEvent;
42
+ name: RuntimeMetaEventName.LangGraphInterruptEvent;
43
+ value: string;
44
+ }
45
+ | {
46
+ type: RuntimeEventTypes.MetaEvent;
47
+ name: RuntimeMetaEventName.LangGraphInterruptResumeEvent;
48
+ value: string;
49
+ };
50
+
33
51
  export type RuntimeEvent =
34
52
  | { type: RuntimeEventTypes.TextMessageStart; messageId: string; parentMessageId?: string }
35
53
  | {
@@ -62,7 +80,8 @@ export type RuntimeEvent =
62
80
  role: string;
63
81
  state: string;
64
82
  running: boolean;
65
- };
83
+ }
84
+ | RunTimeMetaEvent;
66
85
 
67
86
  interface RuntimeEventWithState {
68
87
  event: RuntimeEvent | null;