@langchain/langgraph-api 0.0.35 → 0.0.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api/runs.mjs CHANGED
@@ -75,6 +75,7 @@ const createValidRun = async (threadId, payload, kwargs) => {
75
75
  feedback_keys: feedbackKeys,
76
76
  temporary: threadId == null && (run.on_completion ?? "delete") === "delete",
77
77
  subgraphs: run.stream_subgraphs ?? false,
78
+ resumable: run.stream_resumable ?? false,
78
79
  }, {
79
80
  threadId,
80
81
  userId,
@@ -139,7 +140,11 @@ api.post("/runs/stream", zValidator("json", schemas.RunCreate), async (c) => {
139
140
  ? getDisconnectAbortSignal(c, stream)
140
141
  : undefined;
141
142
  try {
142
- for await (const { event, data } of Runs.Stream.join(run.run_id, undefined, { cancelOnDisconnect, ignore404: true }, c.var.auth)) {
143
+ for await (const { event, data } of Runs.Stream.join(run.run_id, undefined, {
144
+ cancelOnDisconnect,
145
+ lastEventId: run.kwargs.resumable ? "-1" : undefined,
146
+ ignore404: true,
147
+ }, c.var.auth)) {
143
148
  await stream.writeSSE({ data: serialiseAsDict(data), event });
144
149
  }
145
150
  }
@@ -148,6 +153,25 @@ api.post("/runs/stream", zValidator("json", schemas.RunCreate), async (c) => {
148
153
  }
149
154
  });
150
155
  });
156
+ // TODO: port to Python API
157
+ api.get("/runs/:run_id/stream", zValidator("param", z.object({ run_id: z.string().uuid() })), zValidator("query", z.object({ cancel_on_disconnect: schemas.coercedBoolean.optional() })), async (c) => {
158
+ const { run_id } = c.req.valid("param");
159
+ const query = c.req.valid("query");
160
+ const lastEventId = c.req.header("Last-Event-ID") || undefined;
161
+ return streamSSE(c, async (stream) => {
162
+ const cancelOnDisconnect = query.cancel_on_disconnect
163
+ ? getDisconnectAbortSignal(c, stream)
164
+ : undefined;
165
+ try {
166
+ for await (const { id, event, data } of Runs.Stream.join(run_id, undefined, { cancelOnDisconnect, lastEventId, ignore404: true }, c.var.auth)) {
167
+ await stream.writeSSE({ id, data: serialiseAsDict(data), event });
168
+ }
169
+ }
170
+ catch (error) {
171
+ logError(error, { prefix: "Error streaming run" });
172
+ }
173
+ });
174
+ });
151
175
  api.post("/runs/wait", zValidator("json", schemas.RunCreate), async (c) => {
152
176
  // Wait Stateless Run
153
177
  const payload = c.req.valid("json");
@@ -198,6 +222,7 @@ api.post("/threads/:thread_id/runs", zValidator("param", z.object({ thread_id: z
198
222
  auth: c.var.auth,
199
223
  headers: c.req.raw.headers,
200
224
  });
225
+ c.header("Content-Location", `/threads/${thread_id}/runs/${run.run_id}`);
201
226
  return jsonExtra(c, run);
202
227
  });
203
228
  api.post("/threads/:thread_id/runs/stream", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("json", schemas.RunCreate), async (c) => {
@@ -208,13 +233,17 @@ api.post("/threads/:thread_id/runs/stream", zValidator("param", z.object({ threa
208
233
  auth: c.var.auth,
209
234
  headers: c.req.raw.headers,
210
235
  });
236
+ c.header("Content-Location", `/threads/${thread_id}/runs/${run.run_id}`);
211
237
  return streamSSE(c, async (stream) => {
212
238
  const cancelOnDisconnect = payload.on_disconnect === "cancel"
213
239
  ? getDisconnectAbortSignal(c, stream)
214
240
  : undefined;
215
241
  try {
216
- for await (const { event, data } of Runs.Stream.join(run.run_id, thread_id, { cancelOnDisconnect }, c.var.auth)) {
217
- await stream.writeSSE({ data: serialiseAsDict(data), event });
242
+ for await (const { id, event, data } of Runs.Stream.join(run.run_id, thread_id, {
243
+ cancelOnDisconnect,
244
+ lastEventId: run.kwargs.resumable ? "-1" : undefined,
245
+ }, c.var.auth)) {
246
+ await stream.writeSSE({ id, data: serialiseAsDict(data), event });
218
247
  }
219
248
  }
220
249
  catch (error) {
@@ -230,6 +259,7 @@ api.post("/threads/:thread_id/runs/wait", zValidator("param", z.object({ thread_
230
259
  auth: c.var.auth,
231
260
  headers: c.req.raw.headers,
232
261
  });
262
+ c.header("Content-Location", `/threads/${thread_id}/runs/${run.run_id}`);
233
263
  return waitKeepAlive(c, Runs.join(run.run_id, thread_id, c.var.auth));
234
264
  });
235
265
  api.get("/threads/:thread_id/runs/:run_id", zValidator("param", z.object({ thread_id: z.string().uuid(), run_id: z.string().uuid() })), async (c) => {
@@ -257,12 +287,13 @@ api.get("/threads/:thread_id/runs/:run_id/stream", zValidator("param", z.object(
257
287
  // Stream Run Http
258
288
  const { thread_id, run_id } = c.req.valid("param");
259
289
  const { cancel_on_disconnect } = c.req.valid("query");
290
+ const lastEventId = c.req.header("Last-Event-ID") || undefined;
260
291
  return streamSSE(c, async (stream) => {
261
292
  const signal = cancel_on_disconnect
262
293
  ? getDisconnectAbortSignal(c, stream)
263
294
  : undefined;
264
- for await (const { event, data } of Runs.Stream.join(run_id, thread_id, { cancelOnDisconnect: signal }, c.var.auth)) {
265
- await stream.writeSSE({ data: serialiseAsDict(data), event });
295
+ for await (const { id, event, data } of Runs.Stream.join(run_id, thread_id, { cancelOnDisconnect: signal, lastEventId }, c.var.auth)) {
296
+ await stream.writeSSE({ id, data: serialiseAsDict(data), event });
266
297
  }
267
298
  });
268
299
  });
@@ -1,7 +1,11 @@
1
1
  import { cors as honoCors } from "hono/cors";
2
2
  export const cors = (cors) => {
3
- if (cors == null)
4
- return honoCors();
3
+ if (cors == null) {
4
+ return honoCors({
5
+ origin: "*",
6
+ exposeHeaders: ["content-location"],
7
+ });
8
+ }
5
9
  const originRegex = cors.allow_origin_regex
6
10
  ? new RegExp(cors.allow_origin_regex)
7
11
  : undefined;
@@ -13,6 +17,11 @@ export const cors = (cors) => {
13
17
  return undefined;
14
18
  }
15
19
  : (cors.allow_origins ?? []);
20
+ if (!!cors.expose_headers?.length &&
21
+ cors.expose_headers.some((i) => i.toLocaleLowerCase() === "content-location")) {
22
+ console.warn("Adding missing `Content-Location` header in `cors.expose_headers`.");
23
+ cors.expose_headers.push("content-location");
24
+ }
16
25
  // TODO: handle `cors.allow_credentials`
17
26
  return honoCors({
18
27
  origin,
package/dist/queue.mjs CHANGED
@@ -45,17 +45,24 @@ const worker = async (run, attempt, abortSignal) => {
45
45
  if (attempt > MAX_RETRY_ATTEMPTS) {
46
46
  throw new Error(`Run ${run.run_id} exceeded max attempts`);
47
47
  }
48
+ const runId = run.run_id;
49
+ const resumable = run.kwargs?.resumable ?? false;
48
50
  try {
49
51
  const stream = streamState(run, attempt, {
50
52
  signal: abortSignal,
51
53
  ...(!temporary ? { onCheckpoint, onTaskResult } : undefined),
52
54
  });
53
55
  for await (const { event, data } of stream) {
54
- await Runs.Stream.publish(run.run_id, event, data);
56
+ await Runs.Stream.publish({ runId, resumable, event, data });
55
57
  }
56
58
  }
57
59
  catch (error) {
58
- await Runs.Stream.publish(run.run_id, "error", serializeError(error));
60
+ await Runs.Stream.publish({
61
+ runId,
62
+ resumable,
63
+ event: "error",
64
+ data: serializeError(error),
65
+ });
59
66
  throw error;
60
67
  }
61
68
  endedAt = new Date();
@@ -687,6 +687,7 @@ export declare const RunCreate: z.ZodObject<{
687
687
  multitask_strategy: z.ZodOptional<z.ZodEnum<["reject", "rollback", "interrupt", "enqueue"]>>;
688
688
  stream_mode: z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodEnum<["values", "messages", "messages-tuple", "updates", "events", "debug", "custom"]>, "many">, z.ZodEnum<["values", "messages", "messages-tuple", "updates", "events", "debug", "custom"]>]>>;
689
689
  stream_subgraphs: z.ZodOptional<z.ZodBoolean>;
690
+ stream_resumable: z.ZodOptional<z.ZodBoolean>;
690
691
  after_seconds: z.ZodOptional<z.ZodNumber>;
691
692
  if_not_exists: z.ZodOptional<z.ZodEnum<["reject", "create"]>>;
692
693
  on_completion: z.ZodOptional<z.ZodEnum<["delete", "keep"]>>;
@@ -736,6 +737,7 @@ export declare const RunCreate: z.ZodObject<{
736
737
  if_not_exists?: "reject" | "create" | undefined;
737
738
  after_seconds?: number | undefined;
738
739
  stream_subgraphs?: boolean | undefined;
740
+ stream_resumable?: boolean | undefined;
739
741
  on_completion?: "delete" | "keep" | undefined;
740
742
  }, {
741
743
  assistant_id: string;
@@ -782,6 +784,7 @@ export declare const RunCreate: z.ZodObject<{
782
784
  after_seconds?: number | undefined;
783
785
  on_disconnect?: "cancel" | "continue" | undefined;
784
786
  stream_subgraphs?: boolean | undefined;
787
+ stream_resumable?: boolean | undefined;
785
788
  on_completion?: "delete" | "keep" | undefined;
786
789
  }>;
787
790
  export declare const RunBatchCreate: z.ZodArray<z.ZodObject<{
@@ -892,6 +895,7 @@ export declare const RunBatchCreate: z.ZodArray<z.ZodObject<{
892
895
  multitask_strategy: z.ZodOptional<z.ZodEnum<["reject", "rollback", "interrupt", "enqueue"]>>;
893
896
  stream_mode: z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodEnum<["values", "messages", "messages-tuple", "updates", "events", "debug", "custom"]>, "many">, z.ZodEnum<["values", "messages", "messages-tuple", "updates", "events", "debug", "custom"]>]>>;
894
897
  stream_subgraphs: z.ZodOptional<z.ZodBoolean>;
898
+ stream_resumable: z.ZodOptional<z.ZodBoolean>;
895
899
  after_seconds: z.ZodOptional<z.ZodNumber>;
896
900
  if_not_exists: z.ZodOptional<z.ZodEnum<["reject", "create"]>>;
897
901
  on_completion: z.ZodOptional<z.ZodEnum<["delete", "keep"]>>;
@@ -941,6 +945,7 @@ export declare const RunBatchCreate: z.ZodArray<z.ZodObject<{
941
945
  if_not_exists?: "reject" | "create" | undefined;
942
946
  after_seconds?: number | undefined;
943
947
  stream_subgraphs?: boolean | undefined;
948
+ stream_resumable?: boolean | undefined;
944
949
  on_completion?: "delete" | "keep" | undefined;
945
950
  }, {
946
951
  assistant_id: string;
@@ -987,6 +992,7 @@ export declare const RunBatchCreate: z.ZodArray<z.ZodObject<{
987
992
  after_seconds?: number | undefined;
988
993
  on_disconnect?: "cancel" | "continue" | undefined;
989
994
  stream_subgraphs?: boolean | undefined;
995
+ stream_resumable?: boolean | undefined;
990
996
  on_completion?: "delete" | "keep" | undefined;
991
997
  }>, "many">;
992
998
  export declare const SearchResult: z.ZodObject<{
package/dist/schemas.mjs CHANGED
@@ -205,6 +205,7 @@ export const RunCreate = z
205
205
  ])
206
206
  .optional(),
207
207
  stream_subgraphs: z.boolean().optional(),
208
+ stream_resumable: z.boolean().optional(),
208
209
  after_seconds: z.number().optional(),
209
210
  if_not_exists: z.enum(["reject", "create"]).optional(),
210
211
  on_completion: z.enum(["delete", "keep"]).optional(),
package/dist/server.d.mts CHANGED
@@ -40,19 +40,19 @@ export declare const StartServerSchema: z.ZodObject<{
40
40
  max_age: z.ZodOptional<z.ZodNumber>;
41
41
  }, "strip", z.ZodTypeAny, {
42
42
  allow_origin_regex?: string | undefined;
43
+ expose_headers?: string[] | undefined;
43
44
  allow_origins?: string[] | undefined;
44
45
  allow_methods?: string[] | undefined;
45
46
  allow_headers?: string[] | undefined;
46
47
  allow_credentials?: boolean | undefined;
47
- expose_headers?: string[] | undefined;
48
48
  max_age?: number | undefined;
49
49
  }, {
50
50
  allow_origin_regex?: string | undefined;
51
+ expose_headers?: string[] | undefined;
51
52
  allow_origins?: string[] | undefined;
52
53
  allow_methods?: string[] | undefined;
53
54
  allow_headers?: string[] | undefined;
54
55
  allow_credentials?: boolean | undefined;
55
- expose_headers?: string[] | undefined;
56
56
  max_age?: number | undefined;
57
57
  }>>;
58
58
  }, "strip", z.ZodTypeAny, {
@@ -63,22 +63,22 @@ export declare const StartServerSchema: z.ZodObject<{
63
63
  disable_meta: boolean;
64
64
  cors?: {
65
65
  allow_origin_regex?: string | undefined;
66
+ expose_headers?: string[] | undefined;
66
67
  allow_origins?: string[] | undefined;
67
68
  allow_methods?: string[] | undefined;
68
69
  allow_headers?: string[] | undefined;
69
70
  allow_credentials?: boolean | undefined;
70
- expose_headers?: string[] | undefined;
71
71
  max_age?: number | undefined;
72
72
  } | undefined;
73
73
  app?: string | undefined;
74
74
  }, {
75
75
  cors?: {
76
76
  allow_origin_regex?: string | undefined;
77
+ expose_headers?: string[] | undefined;
77
78
  allow_origins?: string[] | undefined;
78
79
  allow_methods?: string[] | undefined;
79
80
  allow_headers?: string[] | undefined;
80
81
  allow_credentials?: boolean | undefined;
81
- expose_headers?: string[] | undefined;
82
82
  max_age?: number | undefined;
83
83
  } | undefined;
84
84
  app?: string | undefined;
@@ -110,11 +110,11 @@ export declare const StartServerSchema: z.ZodObject<{
110
110
  disable_meta: boolean;
111
111
  cors?: {
112
112
  allow_origin_regex?: string | undefined;
113
+ expose_headers?: string[] | undefined;
113
114
  allow_origins?: string[] | undefined;
114
115
  allow_methods?: string[] | undefined;
115
116
  allow_headers?: string[] | undefined;
116
117
  allow_credentials?: boolean | undefined;
117
- expose_headers?: string[] | undefined;
118
118
  max_age?: number | undefined;
119
119
  } | undefined;
120
120
  app?: string | undefined;
@@ -136,11 +136,11 @@ export declare const StartServerSchema: z.ZodObject<{
136
136
  http?: {
137
137
  cors?: {
138
138
  allow_origin_regex?: string | undefined;
139
+ expose_headers?: string[] | undefined;
139
140
  allow_origins?: string[] | undefined;
140
141
  allow_methods?: string[] | undefined;
141
142
  allow_headers?: string[] | undefined;
142
143
  allow_credentials?: boolean | undefined;
143
- expose_headers?: string[] | undefined;
144
144
  max_age?: number | undefined;
145
145
  } | undefined;
146
146
  app?: string | undefined;
@@ -46,6 +46,7 @@ export interface RunKwargs {
46
46
  interrupt_after?: "*" | string[] | undefined;
47
47
  config?: RunnableConfig;
48
48
  subgraphs?: boolean;
49
+ resumable?: boolean;
49
50
  temporary?: boolean;
50
51
  webhook?: unknown;
51
52
  feedback_keys?: string[] | undefined;
@@ -75,13 +76,19 @@ interface Message {
75
76
  data: unknown;
76
77
  }
77
78
  declare class Queue {
78
- private buffer;
79
+ private log;
79
80
  private listeners;
81
+ private nextId;
82
+ private resumable;
83
+ constructor(options: {
84
+ resumable: boolean;
85
+ });
80
86
  push(item: Message): void;
81
87
  get(options: {
82
88
  timeout: number;
89
+ lastEventId?: string;
83
90
  signal?: AbortSignal;
84
- }): Promise<Message>;
91
+ }): Promise<[id: string, message: Message]>;
85
92
  }
86
93
  declare class CancellationAbortController extends AbortController {
87
94
  abort(reason: "rollback" | "interrupt"): void;
@@ -91,10 +98,8 @@ declare class StreamManagerImpl {
91
98
  control: Record<string, CancellationAbortController>;
92
99
  getQueue(runId: string, options: {
93
100
  ifNotFound: "create";
101
+ resumable: boolean;
94
102
  }): Queue;
95
- getQueue(runId: string, options: {
96
- ifNotFound: "ignore";
97
- }): Queue | undefined;
98
103
  getControl(runId: string): CancellationAbortController | undefined;
99
104
  isLocked(runId: string): boolean;
100
105
  lock(runId: string): AbortSignal;
@@ -272,11 +277,18 @@ export declare class Runs {
272
277
  join(runId: string, threadId: string | undefined, options: {
273
278
  ignore404?: boolean;
274
279
  cancelOnDisconnect?: AbortSignal;
280
+ lastEventId: string | undefined;
275
281
  }, auth: AuthContext | undefined): AsyncGenerator<{
282
+ id?: string;
276
283
  event: string;
277
284
  data: unknown;
278
285
  }>;
279
- publish(runId: string, topic: string, data: unknown): Promise<void>;
286
+ publish(payload: {
287
+ runId: string;
288
+ event: string;
289
+ data: unknown;
290
+ resumable: boolean;
291
+ }): Promise<void>;
280
292
  };
281
293
  }
282
294
  export declare class Crons {
@@ -20,28 +20,58 @@ class TimeoutError extends Error {
20
20
  class AbortError extends Error {
21
21
  }
22
22
  class Queue {
23
- buffer = [];
23
+ log = [];
24
24
  listeners = [];
25
+ nextId = 0;
26
+ resumable = false;
27
+ constructor(options) {
28
+ this.resumable = options.resumable;
29
+ }
25
30
  push(item) {
26
- this.buffer.push(item);
27
- for (const listener of this.listeners) {
28
- listener();
29
- }
31
+ this.log.push(item);
32
+ for (const listener of this.listeners)
33
+ listener(this.nextId);
34
+ this.nextId += 1;
30
35
  }
31
36
  async get(options) {
32
- if (this.buffer.length > 0) {
33
- return this.buffer.shift();
37
+ if (this.resumable) {
38
+ const lastEventId = options.lastEventId;
39
+ // Generator stores internal state of the read head index,
40
+ let targetId = lastEventId != null ? +lastEventId + 1 : null;
41
+ if (targetId == null ||
42
+ isNaN(targetId) ||
43
+ targetId < 0 ||
44
+ targetId >= this.log.length) {
45
+ targetId = null;
46
+ }
47
+ if (targetId != null)
48
+ return [String(targetId), this.log[targetId]];
49
+ }
50
+ else {
51
+ if (this.log.length) {
52
+ const nextId = this.nextId - this.log.length;
53
+ const nextItem = this.log.shift();
54
+ return [String(nextId), nextItem];
55
+ }
34
56
  }
35
57
  let timeout = undefined;
36
58
  let resolver = undefined;
37
59
  const clean = new AbortController();
60
+ // listen to new item
38
61
  return await new Promise((resolve, reject) => {
39
62
  timeout = setTimeout(() => reject(new TimeoutError()), options.timeout);
40
63
  resolver = resolve;
41
64
  options.signal?.addEventListener("abort", () => reject(new AbortError()), { signal: clean.signal });
42
65
  this.listeners.push(resolver);
43
66
  })
44
- .then(() => this.buffer.shift())
67
+ .then((idx) => {
68
+ if (this.resumable) {
69
+ return [String(idx), this.log[idx]];
70
+ }
71
+ const nextId = this.nextId - this.log.length;
72
+ const nextItem = this.log.shift();
73
+ return [String(nextId), nextItem];
74
+ })
45
75
  .finally(() => {
46
76
  this.listeners = this.listeners.filter((l) => l !== resolver);
47
77
  clearTimeout(timeout);
@@ -59,12 +89,7 @@ class StreamManagerImpl {
59
89
  control = {};
60
90
  getQueue(runId, options) {
61
91
  if (this.readers[runId] == null) {
62
- if (options?.ifNotFound === "create") {
63
- this.readers[runId] = new Queue();
64
- }
65
- else {
66
- return undefined;
67
- }
92
+ this.readers[runId] = new Queue(options);
68
93
  }
69
94
  return this.readers[runId];
70
95
  }
@@ -883,7 +908,7 @@ export class Runs {
883
908
  });
884
909
  }
885
910
  static async wait(runId, threadId, auth) {
886
- const runStream = Runs.Stream.join(runId, threadId, { ignore404: threadId == null }, auth);
911
+ const runStream = Runs.Stream.join(runId, threadId, { ignore404: threadId == null, lastEventId: undefined }, auth);
887
912
  const lastChunk = new Promise(async (resolve, reject) => {
888
913
  try {
889
914
  let lastChunk = null;
@@ -1012,7 +1037,10 @@ export class Runs {
1012
1037
  yield* conn.withGenerator(async function* (STORE) {
1013
1038
  // TODO: what if we're joining an already completed run? Should we check before?
1014
1039
  const signal = options?.cancelOnDisconnect;
1015
- const queue = StreamManager.getQueue(runId, { ifNotFound: "create" });
1040
+ const queue = StreamManager.getQueue(runId, {
1041
+ ifNotFound: "create",
1042
+ resumable: options.lastEventId != null,
1043
+ });
1016
1044
  const [filters] = await handleAuthEvent(auth, "threads:read", {
1017
1045
  thread_id: threadId,
1018
1046
  });
@@ -1027,16 +1055,22 @@ export class Runs {
1027
1055
  return;
1028
1056
  }
1029
1057
  }
1058
+ let lastEventId = options?.lastEventId;
1030
1059
  while (!signal?.aborted) {
1031
1060
  try {
1032
- const message = await queue.get({ timeout: 500, signal });
1061
+ const [id, message] = await queue.get({
1062
+ timeout: 500,
1063
+ signal,
1064
+ lastEventId,
1065
+ });
1066
+ lastEventId = id;
1033
1067
  if (message.topic === `run:${runId}:control`) {
1034
1068
  if (message.data === "done")
1035
1069
  break;
1036
1070
  }
1037
1071
  else {
1038
1072
  const streamTopic = message.topic.substring(`run:${runId}:stream:`.length);
1039
- yield { event: streamTopic, data: message.data };
1073
+ yield { id, event: streamTopic, data: message.data };
1040
1074
  }
1041
1075
  }
1042
1076
  catch (error) {
@@ -1058,9 +1092,15 @@ export class Runs {
1058
1092
  }
1059
1093
  });
1060
1094
  }
1061
- static async publish(runId, topic, data) {
1062
- const queue = StreamManager.getQueue(runId, { ifNotFound: "create" });
1063
- queue.push({ topic: `run:${runId}:stream:${topic}`, data });
1095
+ static async publish(payload) {
1096
+ const queue = StreamManager.getQueue(payload.runId, {
1097
+ ifNotFound: "create",
1098
+ resumable: payload.resumable,
1099
+ });
1100
+ queue.push({
1101
+ topic: `run:${payload.runId}:stream:${payload.event}`,
1102
+ data: payload.data,
1103
+ });
1064
1104
  }
1065
1105
  };
1066
1106
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph-api",
3
- "version": "0.0.35",
3
+ "version": "0.0.36",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": "^18.19.0 || >=20.16.0"
@@ -53,7 +53,7 @@
53
53
  "winston": "^3.17.0",
54
54
  "winston-console-format": "^1.0.8",
55
55
  "zod": "^3.23.8",
56
- "@langchain/langgraph-ui": "0.0.35"
56
+ "@langchain/langgraph-ui": "0.0.36"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "@langchain/core": "^0.3.42",
@@ -69,7 +69,7 @@
69
69
  },
70
70
  "devDependencies": {
71
71
  "typescript": "^5.5.4",
72
- "@langchain/langgraph-sdk": "^0.0.70",
72
+ "@langchain/langgraph-sdk": "^0.0.77",
73
73
  "@types/babel__code-frame": "^7.0.6",
74
74
  "@types/node": "^22.2.0",
75
75
  "@types/react": "^19.0.8",