@langchain/langgraph-sdk 0.1.5 → 0.1.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 (36) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/react/index.cjs +3 -1
  3. package/dist/react/index.d.ts +2 -1
  4. package/dist/react/index.js +1 -0
  5. package/dist/react/stream.cjs +12 -460
  6. package/dist/react/stream.custom.cjs +148 -0
  7. package/dist/react/stream.custom.d.ts +41 -0
  8. package/dist/react/stream.custom.js +142 -0
  9. package/dist/react/stream.d.ts +61 -1
  10. package/dist/react/stream.js +13 -460
  11. package/dist/react/stream.lgp.cjs +499 -0
  12. package/dist/react/stream.lgp.d.ts +7 -0
  13. package/dist/react/stream.lgp.js +495 -0
  14. package/dist/react/thread.cjs +19 -0
  15. package/dist/react/thread.d.ts +4 -0
  16. package/dist/react/thread.js +15 -0
  17. package/dist/react/types.d.ts +25 -1
  18. package/dist/ui/branching.test.cjs +370 -0
  19. package/dist/ui/branching.test.d.ts +1 -0
  20. package/dist/ui/branching.test.js +368 -0
  21. package/dist/{react → ui}/manager.cjs +8 -4
  22. package/dist/{react → ui}/manager.d.ts +1 -0
  23. package/dist/{react → ui}/manager.js +8 -4
  24. package/package.json +1 -1
  25. /package/dist/{react → ui}/branching.cjs +0 -0
  26. /package/dist/{react → ui}/branching.d.ts +0 -0
  27. /package/dist/{react → ui}/branching.js +0 -0
  28. /package/dist/{react → ui}/errors.cjs +0 -0
  29. /package/dist/{react → ui}/errors.d.ts +0 -0
  30. /package/dist/{react → ui}/errors.js +0 -0
  31. /package/dist/{react → ui}/messages.cjs +0 -0
  32. /package/dist/{react → ui}/messages.d.ts +0 -0
  33. /package/dist/{react → ui}/messages.js +0 -0
  34. /package/dist/{react → ui}/utils.cjs +0 -0
  35. /package/dist/{react → ui}/utils.d.ts +0 -0
  36. /package/dist/{react → ui}/utils.js +0 -0
@@ -0,0 +1,368 @@
1
+ import { it, expect } from "vitest";
2
+ import { getBranchSequence } from "./branching.js";
3
+ const history = [
4
+ {
5
+ values: {
6
+ messages: [
7
+ {
8
+ content: "Fork: Hello",
9
+ additional_kwargs: {},
10
+ response_metadata: {},
11
+ id: "33357aea-9c2d-4718-92f4-20038d5a2d29",
12
+ type: "human",
13
+ },
14
+ {
15
+ content: "Hey",
16
+ additional_kwargs: {},
17
+ response_metadata: {},
18
+ tool_call_chunks: [],
19
+ id: "run-782a2f90-2e39-4c21-9ee6-0f38585a0ae6",
20
+ tool_calls: [],
21
+ invalid_tool_calls: [],
22
+ type: "ai",
23
+ },
24
+ ],
25
+ },
26
+ next: [],
27
+ tasks: [],
28
+ metadata: {
29
+ source: "loop",
30
+ step: 2,
31
+ parents: {},
32
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
33
+ },
34
+ created_at: "2025-08-21T12:47:12.640Z",
35
+ checkpoint: {
36
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
37
+ checkpoint_id: "1f07e8cf-56a7-6000-8002-5e272b1d5285",
38
+ checkpoint_ns: "",
39
+ checkpoint_map: null,
40
+ },
41
+ parent_checkpoint: {
42
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
43
+ checkpoint_id: "1f07e8cf-53aa-6d70-8001-2096b0bbf835",
44
+ checkpoint_ns: "",
45
+ checkpoint_map: null,
46
+ },
47
+ },
48
+ {
49
+ values: {
50
+ messages: [
51
+ {
52
+ content: "Fork: Hello",
53
+ additional_kwargs: {},
54
+ response_metadata: {},
55
+ id: "33357aea-9c2d-4718-92f4-20038d5a2d29",
56
+ type: "human",
57
+ },
58
+ ],
59
+ },
60
+ next: ["agent"],
61
+ tasks: [
62
+ {
63
+ id: "680ee831-4d10-50f9-956f-e0d937321614",
64
+ name: "agent",
65
+ error: null,
66
+ interrupts: [],
67
+ path: ["__pregel_pull", "agent"],
68
+ checkpoint: null,
69
+ state: null,
70
+ result: {
71
+ messages: [
72
+ {
73
+ content: "Hey",
74
+ additional_kwargs: {},
75
+ response_metadata: {},
76
+ tool_call_chunks: [],
77
+ id: "run-782a2f90-2e39-4c21-9ee6-0f38585a0ae6",
78
+ tool_calls: [],
79
+ invalid_tool_calls: [],
80
+ type: "ai",
81
+ },
82
+ ],
83
+ },
84
+ },
85
+ ],
86
+ metadata: {
87
+ source: "loop",
88
+ step: 1,
89
+ parents: {},
90
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
91
+ },
92
+ created_at: "2025-08-21T12:47:12.327Z",
93
+ checkpoint: {
94
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
95
+ checkpoint_id: "1f07e8cf-53aa-6d70-8001-2096b0bbf835",
96
+ checkpoint_ns: "",
97
+ checkpoint_map: null,
98
+ },
99
+ parent_checkpoint: {
100
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
101
+ checkpoint_id: "1f07e8cf-53a8-6660-8000-f157c9cf7d66",
102
+ checkpoint_ns: "",
103
+ checkpoint_map: null,
104
+ },
105
+ },
106
+ {
107
+ values: { messages: [] },
108
+ next: ["__start__"],
109
+ tasks: [
110
+ {
111
+ id: "4233f4c0-5ea2-5117-9153-95e5fe59eee3",
112
+ name: "__start__",
113
+ error: null,
114
+ interrupts: [],
115
+ path: ["__pregel_pull", "__start__"],
116
+ checkpoint: null,
117
+ state: null,
118
+ result: { messages: [{ type: "human", content: "Fork: Hello" }] },
119
+ },
120
+ ],
121
+ metadata: {
122
+ source: "input",
123
+ step: 0,
124
+ parents: {},
125
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
126
+ },
127
+ created_at: "2025-08-21T12:47:12.326Z",
128
+ checkpoint: {
129
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
130
+ checkpoint_id: "1f07e8cf-53a8-6660-8000-f157c9cf7d66",
131
+ checkpoint_ns: "",
132
+ checkpoint_map: null,
133
+ },
134
+ parent_checkpoint: {
135
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
136
+ checkpoint_id: "1f07e8cf-4cea-6530-ffff-0995a53299c5",
137
+ checkpoint_ns: "",
138
+ checkpoint_map: null,
139
+ },
140
+ },
141
+ {
142
+ values: {
143
+ messages: [
144
+ {
145
+ content: "Hello",
146
+ additional_kwargs: {},
147
+ response_metadata: {},
148
+ id: "ec300e63-1494-4ef6-936c-60d02d7bdce1",
149
+ type: "human",
150
+ },
151
+ {
152
+ content: "Hey",
153
+ additional_kwargs: {},
154
+ response_metadata: {},
155
+ tool_call_chunks: [],
156
+ id: "run-593064bd-dd07-4ed3-99c0-a918625f4884",
157
+ tool_calls: [],
158
+ invalid_tool_calls: [],
159
+ type: "ai",
160
+ },
161
+ ],
162
+ },
163
+ next: [],
164
+ tasks: [],
165
+ metadata: {
166
+ source: "loop",
167
+ step: 1,
168
+ parents: {},
169
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
170
+ },
171
+ created_at: "2025-08-21T12:47:12.285Z",
172
+ checkpoint: {
173
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
174
+ checkpoint_id: "1f07e8cf-5344-64d0-8001-8a176e91d12f",
175
+ checkpoint_ns: "",
176
+ checkpoint_map: null,
177
+ },
178
+ parent_checkpoint: {
179
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
180
+ checkpoint_id: "1f07e8cf-4cf8-6f90-8000-7707fd155a8a",
181
+ checkpoint_ns: "",
182
+ checkpoint_map: null,
183
+ },
184
+ },
185
+ {
186
+ values: {
187
+ messages: [
188
+ {
189
+ content: "Hello",
190
+ additional_kwargs: {},
191
+ response_metadata: {},
192
+ id: "ec300e63-1494-4ef6-936c-60d02d7bdce1",
193
+ type: "human",
194
+ },
195
+ {
196
+ content: "Hey",
197
+ additional_kwargs: {},
198
+ response_metadata: {},
199
+ tool_call_chunks: [],
200
+ id: "run-b86ef558-eaff-4838-bc03-218f20554a9f",
201
+ tool_calls: [],
202
+ invalid_tool_calls: [],
203
+ type: "ai",
204
+ },
205
+ ],
206
+ },
207
+ next: [],
208
+ tasks: [],
209
+ metadata: {
210
+ source: "loop",
211
+ step: 1,
212
+ parents: {},
213
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
214
+ },
215
+ created_at: "2025-08-21T12:47:11.936Z",
216
+ checkpoint: {
217
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
218
+ checkpoint_id: "1f07e8cf-4ff0-6400-8001-a54aedf52a76",
219
+ checkpoint_ns: "",
220
+ checkpoint_map: null,
221
+ },
222
+ parent_checkpoint: {
223
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
224
+ checkpoint_id: "1f07e8cf-4cf8-6f90-8000-7707fd155a8a",
225
+ checkpoint_ns: "",
226
+ checkpoint_map: null,
227
+ },
228
+ },
229
+ {
230
+ values: {
231
+ messages: [
232
+ {
233
+ content: "Hello",
234
+ additional_kwargs: {},
235
+ response_metadata: {},
236
+ id: "ec300e63-1494-4ef6-936c-60d02d7bdce1",
237
+ type: "human",
238
+ },
239
+ ],
240
+ },
241
+ next: ["agent"],
242
+ tasks: [
243
+ {
244
+ id: "e3f503f1-73bc-5db1-8b4d-13f660ad1b51",
245
+ name: "agent",
246
+ error: null,
247
+ interrupts: [],
248
+ path: ["__pregel_pull", "agent"],
249
+ checkpoint: null,
250
+ state: null,
251
+ result: {
252
+ messages: [
253
+ {
254
+ content: "Hey",
255
+ additional_kwargs: {},
256
+ response_metadata: {},
257
+ tool_call_chunks: [],
258
+ id: "run-b86ef558-eaff-4838-bc03-218f20554a9f",
259
+ tool_calls: [],
260
+ invalid_tool_calls: [],
261
+ type: "ai",
262
+ },
263
+ ],
264
+ },
265
+ },
266
+ ],
267
+ metadata: {
268
+ source: "loop",
269
+ step: 0,
270
+ parents: {},
271
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
272
+ },
273
+ created_at: "2025-08-21T12:47:11.625Z",
274
+ checkpoint: {
275
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
276
+ checkpoint_id: "1f07e8cf-4cf8-6f90-8000-7707fd155a8a",
277
+ checkpoint_ns: "",
278
+ checkpoint_map: null,
279
+ },
280
+ parent_checkpoint: {
281
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
282
+ checkpoint_id: "1f07e8cf-4cea-6530-ffff-0995a53299c5",
283
+ checkpoint_ns: "",
284
+ checkpoint_map: null,
285
+ },
286
+ },
287
+ {
288
+ values: { messages: [] },
289
+ next: ["__start__"],
290
+ tasks: [
291
+ {
292
+ id: "cddede95-d276-59f1-bc08-8051d6448734",
293
+ name: "__start__",
294
+ error: null,
295
+ interrupts: [],
296
+ path: ["__pregel_pull", "__start__"],
297
+ checkpoint: null,
298
+ state: null,
299
+ result: { messages: [{ type: "human", content: "Hello" }] },
300
+ },
301
+ ],
302
+ metadata: {
303
+ source: "input",
304
+ step: -1,
305
+ parents: {},
306
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
307
+ },
308
+ created_at: "2025-08-21T12:47:11.619Z",
309
+ checkpoint: {
310
+ thread_id: "efa80f4d-725f-4903-b19f-216309f060bc",
311
+ checkpoint_id: "1f07e8cf-4cea-6530-ffff-0995a53299c5",
312
+ checkpoint_ns: "",
313
+ checkpoint_map: null,
314
+ },
315
+ parent_checkpoint: null,
316
+ },
317
+ ];
318
+ const node = (value, paths = []) => ({
319
+ type: "node",
320
+ value: typeof value === "number" ? history.at(value) : value,
321
+ path: paths.map((v) => {
322
+ if (typeof v === "number") {
323
+ return history.at(v)?.checkpoint?.checkpoint_id;
324
+ }
325
+ return v?.checkpoint?.checkpoint_id;
326
+ }),
327
+ });
328
+ const fork = (...items) => ({ type: "fork", items });
329
+ const sequence = (...items) => ({ type: "sequence", items });
330
+ it("full tree", async () => {
331
+ const { rootSequence, paths } = getBranchSequence(history);
332
+ expect
333
+ .soft(paths)
334
+ .toMatchObject(expect.arrayContaining([[5], [5, 4], [5, 3], [2]].map((p) => p.map((i) => history.at(i)?.checkpoint?.checkpoint_id))));
335
+ expect
336
+ .soft(rootSequence)
337
+ .toMatchObject(sequence(node(6), fork(sequence(node(5, [5]), fork(sequence(node(4, [5, 4])), sequence(node(3, [5, 3])))), sequence(node(2, [2]), node(1, [2]), node(0, [2])))));
338
+ });
339
+ it("partial tree", async () => {
340
+ expect(getBranchSequence(history.slice(0, 1))).toMatchObject({
341
+ paths: [],
342
+ rootSequence: sequence(node(0)),
343
+ });
344
+ expect(getBranchSequence(history.slice(0, 2))).toMatchObject({
345
+ paths: [],
346
+ rootSequence: sequence(node(1), node(0)),
347
+ });
348
+ expect(getBranchSequence(history.slice(0, 3))).toMatchObject({
349
+ paths: [],
350
+ rootSequence: sequence(node(2), node(1), node(0)),
351
+ });
352
+ expect(getBranchSequence(history.slice(0, 4))).toMatchObject({
353
+ paths: [],
354
+ rootSequence: sequence(node(2), node(1), node(0)),
355
+ });
356
+ expect(getBranchSequence(history.slice(0, 5))).toMatchObject({
357
+ paths: [],
358
+ rootSequence: sequence(node(2), node(1), node(0)),
359
+ });
360
+ expect(getBranchSequence(history.slice(0, 6))).toMatchObject({
361
+ paths: expect.arrayContaining([[5], [5, 4], [5, 3], [2]].map((p) => p.map((i) => history.at(i)?.checkpoint?.checkpoint_id))),
362
+ rootSequence: sequence(fork(sequence(node(5, [5]), fork(sequence(node(4, [5, 4])), sequence(node(3, [5, 3])))), sequence(node(2, [2]), node(1, [2]), node(0, [2])))),
363
+ });
364
+ expect(getBranchSequence(history.slice(0, 7))).toMatchObject({
365
+ paths: expect.arrayContaining([[5], [5, 4], [5, 3], [2]].map((p) => p.map((i) => history.at(i)?.checkpoint?.checkpoint_id))),
366
+ rootSequence: sequence(node(6), fork(sequence(node(5, [5]), fork(sequence(node(4, [5, 4])), sequence(node(3, [5, 3])))), sequence(node(2, [2]), node(1, [2]), node(0, [2])))),
367
+ });
368
+ });
@@ -189,6 +189,7 @@ class StreamManager {
189
189
  finally {
190
190
  this.setState({ isLoading: false });
191
191
  this.abortRef = new AbortController();
192
+ options.onFinish?.();
192
193
  }
193
194
  }
194
195
  });
@@ -197,10 +198,8 @@ class StreamManager {
197
198
  configurable: true,
198
199
  writable: true,
199
200
  value: async (historyValues, options) => {
200
- if (this.abortRef) {
201
- this.abortRef.abort();
202
- this.abortRef = new AbortController();
203
- }
201
+ this.abortRef.abort();
202
+ this.abortRef = new AbortController();
204
203
  options.onStop?.({ mutate: this.getMutateFn("stop", historyValues) });
205
204
  }
206
205
  });
@@ -209,7 +208,12 @@ class StreamManager {
209
208
  configurable: true,
210
209
  writable: true,
211
210
  value: () => {
211
+ // Cancel any running streams
212
+ this.abortRef.abort();
213
+ this.abortRef = new AbortController();
214
+ // Set the stream state to null
212
215
  this.setState({ error: undefined, values: null });
216
+ // Clear any pending messages
213
217
  this.messages.clear();
214
218
  }
215
219
  });
@@ -75,6 +75,7 @@ export declare class StreamManager<StateType extends Record<string, unknown>, Ba
75
75
  callbacks: StreamManagerEventCallbacks<StateType, Bag>;
76
76
  onSuccess: () => StateType | null | undefined | void | Promise<StateType | null | undefined | void>;
77
77
  onError: (error: unknown) => void | Promise<void>;
78
+ onFinish?: () => void;
78
79
  }) => Promise<void>;
79
80
  stop: (historyValues: StateType, options: {
80
81
  onStop?: (options: {
@@ -186,6 +186,7 @@ export class StreamManager {
186
186
  finally {
187
187
  this.setState({ isLoading: false });
188
188
  this.abortRef = new AbortController();
189
+ options.onFinish?.();
189
190
  }
190
191
  }
191
192
  });
@@ -194,10 +195,8 @@ export class StreamManager {
194
195
  configurable: true,
195
196
  writable: true,
196
197
  value: async (historyValues, options) => {
197
- if (this.abortRef) {
198
- this.abortRef.abort();
199
- this.abortRef = new AbortController();
200
- }
198
+ this.abortRef.abort();
199
+ this.abortRef = new AbortController();
201
200
  options.onStop?.({ mutate: this.getMutateFn("stop", historyValues) });
202
201
  }
203
202
  });
@@ -206,7 +205,12 @@ export class StreamManager {
206
205
  configurable: true,
207
206
  writable: true,
208
207
  value: () => {
208
+ // Cancel any running streams
209
+ this.abortRef.abort();
210
+ this.abortRef = new AbortController();
211
+ // Set the stream state to null
209
212
  this.setState({ error: undefined, values: null });
213
+ // Clear any pending messages
210
214
  this.messages.clear();
211
215
  }
212
216
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph-sdk",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Client library for interacting with the LangGraph API",
5
5
  "type": "module",
6
6
  "scripts": {
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes