@langchain/langgraph 0.2.46 → 0.2.48
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/func/index.cjs +0 -15
- package/dist/func/index.d.ts +0 -40
- package/dist/func/index.js +0 -15
- package/dist/prebuilt/index.cjs +2 -1
- package/dist/prebuilt/index.d.ts +1 -1
- package/dist/prebuilt/index.js +1 -1
- package/dist/prebuilt/react_agent_executor.cjs +4 -1
- package/dist/prebuilt/react_agent_executor.d.ts +1 -1
- package/dist/prebuilt/react_agent_executor.js +4 -1
- package/dist/pregel/index.cjs +314 -33
- package/dist/pregel/index.d.ts +374 -61
- package/dist/pregel/index.js +314 -33
- package/dist/pregel/io.cjs +49 -24
- package/dist/pregel/io.d.ts +8 -1
- package/dist/pregel/io.js +49 -24
- package/dist/pregel/loop.cjs +11 -0
- package/dist/pregel/loop.d.ts +1 -0
- package/dist/pregel/loop.js +12 -1
- package/dist/pregel/runner.cjs +24 -22
- package/dist/pregel/runner.d.ts +0 -3
- package/dist/pregel/runner.js +25 -23
- package/dist/pregel/types.d.ts +154 -30
- package/dist/web.d.ts +1 -1
- package/package.json +4 -4
package/dist/pregel/index.js
CHANGED
|
@@ -22,9 +22,20 @@ import { IterableReadableWritableStream } from "./stream.js";
|
|
|
22
22
|
function isString(value) {
|
|
23
23
|
return typeof value === "string";
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Utility class for working with channels in the Pregel system.
|
|
27
|
+
* Provides static methods for subscribing to channels and writing to them.
|
|
28
|
+
*
|
|
29
|
+
* Channels are the communication pathways between nodes in a Pregel graph.
|
|
30
|
+
* They enable message passing and state updates between different parts of the graph.
|
|
31
|
+
*/
|
|
25
32
|
export class Channel {
|
|
26
33
|
static subscribeTo(channels, options) {
|
|
27
|
-
const { key, tags } =
|
|
34
|
+
const { key, tags } = {
|
|
35
|
+
key: undefined,
|
|
36
|
+
tags: undefined,
|
|
37
|
+
...(options ?? {}),
|
|
38
|
+
};
|
|
28
39
|
if (Array.isArray(channels) && key !== undefined) {
|
|
29
40
|
throw new Error("Can't specify a key when subscribing to multiple channels");
|
|
30
41
|
}
|
|
@@ -47,7 +58,32 @@ export class Channel {
|
|
|
47
58
|
tags,
|
|
48
59
|
});
|
|
49
60
|
}
|
|
50
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Creates a ChannelWrite that specifies how to write values to channels.
|
|
63
|
+
* This is used to define how nodes send output to channels.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* // Write to multiple channels
|
|
68
|
+
* const write = Channel.writeTo(["output", "state"]);
|
|
69
|
+
*
|
|
70
|
+
* // Write with specific values
|
|
71
|
+
* const write = Channel.writeTo(["output"], {
|
|
72
|
+
* state: "completed",
|
|
73
|
+
* result: calculateResult()
|
|
74
|
+
* });
|
|
75
|
+
*
|
|
76
|
+
* // Write with a transformation function
|
|
77
|
+
* const write = Channel.writeTo(["output"], {
|
|
78
|
+
* result: (x) => processResult(x)
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* @param channels - Array of channel names to write to
|
|
83
|
+
* @param writes - Optional map of channel names to values or transformations
|
|
84
|
+
* @returns A ChannelWrite object that can be used to write to the specified channels
|
|
85
|
+
*/
|
|
86
|
+
static writeTo(channels, writes) {
|
|
51
87
|
const channelWriteEntries = [];
|
|
52
88
|
for (const channel of channels) {
|
|
53
89
|
channelWriteEntries.push({
|
|
@@ -56,7 +92,7 @@ export class Channel {
|
|
|
56
92
|
skipNone: false,
|
|
57
93
|
});
|
|
58
94
|
}
|
|
59
|
-
for (const [key, value] of Object.entries(
|
|
95
|
+
for (const [key, value] of Object.entries(writes ?? {})) {
|
|
60
96
|
if (Runnable.isRunnable(value) || typeof value === "function") {
|
|
61
97
|
channelWriteEntries.push({
|
|
62
98
|
channel: key,
|
|
@@ -76,109 +112,222 @@ export class Channel {
|
|
|
76
112
|
return new ChannelWrite(channelWriteEntries);
|
|
77
113
|
}
|
|
78
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* The Pregel class is the core runtime engine of LangGraph, implementing a message-passing graph computation model
|
|
117
|
+
* inspired by [Google's Pregel system](https://research.google/pubs/pregel-a-system-for-large-scale-graph-processing/).
|
|
118
|
+
* It provides the foundation for building reliable, controllable agent workflows that can evolve state over time.
|
|
119
|
+
*
|
|
120
|
+
* Key features:
|
|
121
|
+
* - Message passing between nodes in discrete "supersteps"
|
|
122
|
+
* - Built-in persistence layer through checkpointers
|
|
123
|
+
* - First-class streaming support for values, updates, and events
|
|
124
|
+
* - Human-in-the-loop capabilities via interrupts
|
|
125
|
+
* - Support for parallel node execution within supersteps
|
|
126
|
+
*
|
|
127
|
+
* The Pregel class is not intended to be instantiated directly by consumers. Instead, use the following higher-level APIs:
|
|
128
|
+
* - {@link StateGraph}: The main graph class for building agent workflows
|
|
129
|
+
* - Compiling a {@link StateGraph} will return a {@link CompiledGraph} instance, which extends `Pregel`
|
|
130
|
+
* - Functional API: A declarative approach using tasks and entrypoints
|
|
131
|
+
* - A `Pregel` instance is returned by the {@link entrypoint} function
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* // Using StateGraph API
|
|
136
|
+
* const graph = new StateGraph(annotation)
|
|
137
|
+
* .addNode("nodeA", myNodeFunction)
|
|
138
|
+
* .addEdge("nodeA", "nodeB")
|
|
139
|
+
* .compile();
|
|
140
|
+
*
|
|
141
|
+
* // The compiled graph is a Pregel instance
|
|
142
|
+
* const result = await graph.invoke(input);
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* // Using Functional API
|
|
148
|
+
* import { task, entrypoint } from "@langchain/langgraph";
|
|
149
|
+
* import { MemorySaver } from "@langchain/langgraph-checkpoint";
|
|
150
|
+
*
|
|
151
|
+
* // Define tasks that can be composed
|
|
152
|
+
* const addOne = task("add", async (x: number) => x + 1);
|
|
153
|
+
*
|
|
154
|
+
* // Create a workflow using the entrypoint function
|
|
155
|
+
* const workflow = entrypoint({
|
|
156
|
+
* name: "workflow",
|
|
157
|
+
* checkpointer: new MemorySaver()
|
|
158
|
+
* }, async (numbers: number[]) => {
|
|
159
|
+
* // Tasks can be run in parallel
|
|
160
|
+
* const results = await Promise.all(numbers.map(n => addOne(n)));
|
|
161
|
+
* return results;
|
|
162
|
+
* });
|
|
163
|
+
*
|
|
164
|
+
* // The workflow is a Pregel instance
|
|
165
|
+
* const result = await workflow.invoke([1, 2, 3]); // Returns [2, 3, 4]
|
|
166
|
+
* ```
|
|
167
|
+
*
|
|
168
|
+
* @typeParam Nodes - Mapping of node names to their {@link PregelNode} implementations
|
|
169
|
+
* @typeParam Channels - Mapping of channel names to their {@link BaseChannel} or {@link ManagedValueSpec} implementations
|
|
170
|
+
* @typeParam ConfigurableFieldType - Type of configurable fields that can be passed to the graph
|
|
171
|
+
* @typeParam InputType - Type of input values accepted by the graph
|
|
172
|
+
* @typeParam OutputType - Type of output values produced by the graph
|
|
173
|
+
*/
|
|
79
174
|
export class Pregel extends Runnable {
|
|
175
|
+
/**
|
|
176
|
+
* Name of the class when serialized
|
|
177
|
+
* @internal
|
|
178
|
+
*/
|
|
80
179
|
static lc_name() {
|
|
81
180
|
return "LangGraph";
|
|
82
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Constructor for Pregel - meant for internal use only.
|
|
184
|
+
*
|
|
185
|
+
* @internal
|
|
186
|
+
*/
|
|
83
187
|
constructor(fields) {
|
|
84
188
|
super(fields);
|
|
85
|
-
|
|
189
|
+
/** @internal LangChain namespace for serialization necessary because Pregel extends Runnable */
|
|
86
190
|
Object.defineProperty(this, "lc_namespace", {
|
|
87
191
|
enumerable: true,
|
|
88
192
|
configurable: true,
|
|
89
193
|
writable: true,
|
|
90
194
|
value: ["langgraph", "pregel"]
|
|
91
195
|
});
|
|
196
|
+
/** @internal Flag indicating this is a Pregel instance - necessary for serialization */
|
|
92
197
|
Object.defineProperty(this, "lg_is_pregel", {
|
|
93
198
|
enumerable: true,
|
|
94
199
|
configurable: true,
|
|
95
200
|
writable: true,
|
|
96
201
|
value: true
|
|
97
202
|
});
|
|
203
|
+
/** The nodes in the graph, mapping node names to their PregelNode instances */
|
|
98
204
|
Object.defineProperty(this, "nodes", {
|
|
99
205
|
enumerable: true,
|
|
100
206
|
configurable: true,
|
|
101
207
|
writable: true,
|
|
102
208
|
value: void 0
|
|
103
209
|
});
|
|
210
|
+
/** The channels in the graph, mapping channel names to their BaseChannel or ManagedValueSpec instances */
|
|
104
211
|
Object.defineProperty(this, "channels", {
|
|
105
212
|
enumerable: true,
|
|
106
213
|
configurable: true,
|
|
107
214
|
writable: true,
|
|
108
215
|
value: void 0
|
|
109
216
|
});
|
|
217
|
+
/**
|
|
218
|
+
* The input channels for the graph. These channels receive the initial input when the graph is invoked.
|
|
219
|
+
* Can be a single channel key or an array of channel keys.
|
|
220
|
+
*/
|
|
110
221
|
Object.defineProperty(this, "inputChannels", {
|
|
111
222
|
enumerable: true,
|
|
112
223
|
configurable: true,
|
|
113
224
|
writable: true,
|
|
114
225
|
value: void 0
|
|
115
226
|
});
|
|
227
|
+
/**
|
|
228
|
+
* The output channels for the graph. These channels contain the final output when the graph completes.
|
|
229
|
+
* Can be a single channel key or an array of channel keys.
|
|
230
|
+
*/
|
|
116
231
|
Object.defineProperty(this, "outputChannels", {
|
|
117
232
|
enumerable: true,
|
|
118
233
|
configurable: true,
|
|
119
234
|
writable: true,
|
|
120
235
|
value: void 0
|
|
121
236
|
});
|
|
237
|
+
/** Whether to automatically validate the graph structure when it is compiled. Defaults to true. */
|
|
122
238
|
Object.defineProperty(this, "autoValidate", {
|
|
123
239
|
enumerable: true,
|
|
124
240
|
configurable: true,
|
|
125
241
|
writable: true,
|
|
126
242
|
value: true
|
|
127
243
|
});
|
|
244
|
+
/**
|
|
245
|
+
* The streaming modes enabled for this graph. Defaults to ["values"].
|
|
246
|
+
* Supported modes:
|
|
247
|
+
* - "values": Streams the full state after each step
|
|
248
|
+
* - "updates": Streams state updates after each step
|
|
249
|
+
* - "messages": Streams messages from within nodes
|
|
250
|
+
* - "custom": Streams custom events from within nodes
|
|
251
|
+
* - "debug": Streams events related to the execution of the graph - useful for tracing & debugging graph execution
|
|
252
|
+
*/
|
|
128
253
|
Object.defineProperty(this, "streamMode", {
|
|
129
254
|
enumerable: true,
|
|
130
255
|
configurable: true,
|
|
131
256
|
writable: true,
|
|
132
257
|
value: ["values"]
|
|
133
258
|
});
|
|
259
|
+
/**
|
|
260
|
+
* Optional channels to stream. If not specified, all channels will be streamed.
|
|
261
|
+
* Can be a single channel key or an array of channel keys.
|
|
262
|
+
*/
|
|
134
263
|
Object.defineProperty(this, "streamChannels", {
|
|
135
264
|
enumerable: true,
|
|
136
265
|
configurable: true,
|
|
137
266
|
writable: true,
|
|
138
267
|
value: void 0
|
|
139
268
|
});
|
|
269
|
+
/**
|
|
270
|
+
* Optional array of node names or "all" to interrupt after executing these nodes.
|
|
271
|
+
* Used for implementing human-in-the-loop workflows.
|
|
272
|
+
*/
|
|
140
273
|
Object.defineProperty(this, "interruptAfter", {
|
|
141
274
|
enumerable: true,
|
|
142
275
|
configurable: true,
|
|
143
276
|
writable: true,
|
|
144
277
|
value: void 0
|
|
145
278
|
});
|
|
279
|
+
/**
|
|
280
|
+
* Optional array of node names or "all" to interrupt before executing these nodes.
|
|
281
|
+
* Used for implementing human-in-the-loop workflows.
|
|
282
|
+
*/
|
|
146
283
|
Object.defineProperty(this, "interruptBefore", {
|
|
147
284
|
enumerable: true,
|
|
148
285
|
configurable: true,
|
|
149
286
|
writable: true,
|
|
150
287
|
value: void 0
|
|
151
288
|
});
|
|
289
|
+
/** Optional timeout in milliseconds for the execution of each superstep */
|
|
152
290
|
Object.defineProperty(this, "stepTimeout", {
|
|
153
291
|
enumerable: true,
|
|
154
292
|
configurable: true,
|
|
155
293
|
writable: true,
|
|
156
294
|
value: void 0
|
|
157
295
|
});
|
|
296
|
+
/** Whether to enable debug logging. Defaults to false. */
|
|
158
297
|
Object.defineProperty(this, "debug", {
|
|
159
298
|
enumerable: true,
|
|
160
299
|
configurable: true,
|
|
161
300
|
writable: true,
|
|
162
301
|
value: false
|
|
163
302
|
});
|
|
303
|
+
/**
|
|
304
|
+
* Optional checkpointer for persisting graph state.
|
|
305
|
+
* When provided, saves a checkpoint of the graph state at every superstep.
|
|
306
|
+
* When false or undefined, checkpointing is disabled, and the graph will not be able to save or restore state.
|
|
307
|
+
*/
|
|
164
308
|
Object.defineProperty(this, "checkpointer", {
|
|
165
309
|
enumerable: true,
|
|
166
310
|
configurable: true,
|
|
167
311
|
writable: true,
|
|
168
312
|
value: void 0
|
|
169
313
|
});
|
|
314
|
+
/** Optional retry policy for handling failures in node execution */
|
|
170
315
|
Object.defineProperty(this, "retryPolicy", {
|
|
171
316
|
enumerable: true,
|
|
172
317
|
configurable: true,
|
|
173
318
|
writable: true,
|
|
174
319
|
value: void 0
|
|
175
320
|
});
|
|
321
|
+
/** The default configuration for graph execution, can be overridden on a per-invocation basis */
|
|
176
322
|
Object.defineProperty(this, "config", {
|
|
177
323
|
enumerable: true,
|
|
178
324
|
configurable: true,
|
|
179
325
|
writable: true,
|
|
180
326
|
value: void 0
|
|
181
327
|
});
|
|
328
|
+
/**
|
|
329
|
+
* Optional long-term memory store for the graph, allows for persistance & retrieval of data across threads
|
|
330
|
+
*/
|
|
182
331
|
Object.defineProperty(this, "store", {
|
|
183
332
|
enumerable: true,
|
|
184
333
|
configurable: true,
|
|
@@ -209,6 +358,25 @@ export class Pregel extends Runnable {
|
|
|
209
358
|
this.validate();
|
|
210
359
|
}
|
|
211
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* Creates a new instance of the Pregel graph with updated configuration.
|
|
363
|
+
* This method follows the immutable pattern - instead of modifying the current instance,
|
|
364
|
+
* it returns a new instance with the merged configuration.
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* ```typescript
|
|
368
|
+
* // Create a new instance with debug enabled
|
|
369
|
+
* const debugGraph = graph.withConfig({ debug: true });
|
|
370
|
+
*
|
|
371
|
+
* // Create a new instance with a specific thread ID
|
|
372
|
+
* const threadGraph = graph.withConfig({
|
|
373
|
+
* configurable: { thread_id: "123" }
|
|
374
|
+
* });
|
|
375
|
+
* ```
|
|
376
|
+
*
|
|
377
|
+
* @param config - The configuration to merge with the current configuration
|
|
378
|
+
* @returns A new Pregel instance with the merged configuration
|
|
379
|
+
*/
|
|
212
380
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
213
381
|
// @ts-ignore Remove ignore when we remove support for 0.2 versions of core
|
|
214
382
|
withConfig(config) {
|
|
@@ -216,6 +384,16 @@ export class Pregel extends Runnable {
|
|
|
216
384
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
217
385
|
return new this.constructor({ ...this, config: mergedConfig });
|
|
218
386
|
}
|
|
387
|
+
/**
|
|
388
|
+
* Validates the graph structure to ensure it is well-formed.
|
|
389
|
+
* Checks for:
|
|
390
|
+
* - No orphaned nodes
|
|
391
|
+
* - Valid input/output channel configurations
|
|
392
|
+
* - Valid interrupt configurations
|
|
393
|
+
*
|
|
394
|
+
* @returns this - The Pregel instance for method chaining
|
|
395
|
+
* @throws {GraphValidationError} If the graph structure is invalid
|
|
396
|
+
*/
|
|
219
397
|
validate() {
|
|
220
398
|
validateGraph({
|
|
221
399
|
nodes: this.nodes,
|
|
@@ -228,6 +406,13 @@ export class Pregel extends Runnable {
|
|
|
228
406
|
});
|
|
229
407
|
return this;
|
|
230
408
|
}
|
|
409
|
+
/**
|
|
410
|
+
* Gets a list of all channels that should be streamed.
|
|
411
|
+
* If streamChannels is specified, returns those channels.
|
|
412
|
+
* Otherwise, returns all channels in the graph.
|
|
413
|
+
*
|
|
414
|
+
* @returns Array of channel keys to stream
|
|
415
|
+
*/
|
|
231
416
|
get streamChannelsList() {
|
|
232
417
|
if (Array.isArray(this.streamChannels)) {
|
|
233
418
|
return this.streamChannels;
|
|
@@ -239,6 +424,13 @@ export class Pregel extends Runnable {
|
|
|
239
424
|
return Object.keys(this.channels);
|
|
240
425
|
}
|
|
241
426
|
}
|
|
427
|
+
/**
|
|
428
|
+
* Gets the channels to stream in their original format.
|
|
429
|
+
* If streamChannels is specified, returns it as-is (either single key or array).
|
|
430
|
+
* Otherwise, returns all channels in the graph as an array.
|
|
431
|
+
*
|
|
432
|
+
* @returns Channel keys to stream, either as a single key or array
|
|
433
|
+
*/
|
|
242
434
|
get streamChannelsAsIs() {
|
|
243
435
|
if (this.streamChannels) {
|
|
244
436
|
return this.streamChannels;
|
|
@@ -247,10 +439,25 @@ export class Pregel extends Runnable {
|
|
|
247
439
|
return Object.keys(this.channels);
|
|
248
440
|
}
|
|
249
441
|
}
|
|
442
|
+
/**
|
|
443
|
+
* Gets a drawable representation of the graph structure.
|
|
444
|
+
* This is an async version of getGraph() and is the preferred method to use.
|
|
445
|
+
*
|
|
446
|
+
* @param config - Configuration for generating the graph visualization
|
|
447
|
+
* @returns A representation of the graph that can be visualized
|
|
448
|
+
*/
|
|
250
449
|
async getGraphAsync(config) {
|
|
251
450
|
return this.getGraph(config);
|
|
252
451
|
}
|
|
253
|
-
/**
|
|
452
|
+
/**
|
|
453
|
+
* Gets all subgraphs within this graph.
|
|
454
|
+
* A subgraph is a Pregel instance that is nested within a node of this graph.
|
|
455
|
+
*
|
|
456
|
+
* @deprecated Use getSubgraphsAsync instead. The async method will become the default in the next minor release.
|
|
457
|
+
* @param namespace - Optional namespace to filter subgraphs
|
|
458
|
+
* @param recurse - Whether to recursively get subgraphs of subgraphs
|
|
459
|
+
* @returns Generator yielding tuples of [name, subgraph]
|
|
460
|
+
*/
|
|
254
461
|
*getSubgraphs(namespace, recurse
|
|
255
462
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
256
463
|
) {
|
|
@@ -288,11 +495,29 @@ export class Pregel extends Runnable {
|
|
|
288
495
|
}
|
|
289
496
|
}
|
|
290
497
|
}
|
|
498
|
+
/**
|
|
499
|
+
* Gets all subgraphs within this graph asynchronously.
|
|
500
|
+
* A subgraph is a Pregel instance that is nested within a node of this graph.
|
|
501
|
+
*
|
|
502
|
+
* @param namespace - Optional namespace to filter subgraphs
|
|
503
|
+
* @param recurse - Whether to recursively get subgraphs of subgraphs
|
|
504
|
+
* @returns AsyncGenerator yielding tuples of [name, subgraph]
|
|
505
|
+
*/
|
|
291
506
|
async *getSubgraphsAsync(namespace, recurse
|
|
292
507
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
293
508
|
) {
|
|
294
509
|
yield* this.getSubgraphs(namespace, recurse);
|
|
295
510
|
}
|
|
511
|
+
/**
|
|
512
|
+
* Prepares a state snapshot from saved checkpoint data.
|
|
513
|
+
* This is an internal method used by getState and getStateHistory.
|
|
514
|
+
*
|
|
515
|
+
* @param config - Configuration for preparing the snapshot
|
|
516
|
+
* @param saved - Optional saved checkpoint data
|
|
517
|
+
* @param subgraphCheckpointer - Optional checkpointer for subgraphs
|
|
518
|
+
* @returns A snapshot of the graph state
|
|
519
|
+
* @internal
|
|
520
|
+
*/
|
|
296
521
|
async _prepareStateSnapshot({ config, saved, subgraphCheckpointer, }) {
|
|
297
522
|
if (saved === undefined) {
|
|
298
523
|
return {
|
|
@@ -368,7 +593,13 @@ export class Pregel extends Runnable {
|
|
|
368
593
|
};
|
|
369
594
|
}
|
|
370
595
|
/**
|
|
371
|
-
*
|
|
596
|
+
* Gets the current state of the graph.
|
|
597
|
+
* Requires a checkpointer to be configured.
|
|
598
|
+
*
|
|
599
|
+
* @param config - Configuration for retrieving the state
|
|
600
|
+
* @param options - Additional options
|
|
601
|
+
* @returns A snapshot of the current graph state
|
|
602
|
+
* @throws {GraphValueError} If no checkpointer is configured
|
|
372
603
|
*/
|
|
373
604
|
async getState(config, options) {
|
|
374
605
|
const checkpointer = config.configurable?.[CONFIG_KEY_CHECKPOINTER] ?? this.checkpointer;
|
|
@@ -402,7 +633,17 @@ export class Pregel extends Runnable {
|
|
|
402
633
|
return snapshot;
|
|
403
634
|
}
|
|
404
635
|
/**
|
|
405
|
-
*
|
|
636
|
+
* Gets the history of graph states.
|
|
637
|
+
* Requires a checkpointer to be configured.
|
|
638
|
+
* Useful for:
|
|
639
|
+
* - Debugging execution history
|
|
640
|
+
* - Implementing time travel
|
|
641
|
+
* - Analyzing graph behavior
|
|
642
|
+
*
|
|
643
|
+
* @param config - Configuration for retrieving the history
|
|
644
|
+
* @param options - Options for filtering the history
|
|
645
|
+
* @returns An async iterator of state snapshots
|
|
646
|
+
* @throws {Error} If no checkpointer is configured
|
|
406
647
|
*/
|
|
407
648
|
async *getStateHistory(config, options) {
|
|
408
649
|
const checkpointer = config.configurable?.[CONFIG_KEY_CHECKPOINTER] ?? this.checkpointer;
|
|
@@ -438,9 +679,20 @@ export class Pregel extends Runnable {
|
|
|
438
679
|
}
|
|
439
680
|
}
|
|
440
681
|
/**
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
682
|
+
* Updates the state of the graph with new values.
|
|
683
|
+
* Requires a checkpointer to be configured.
|
|
684
|
+
*
|
|
685
|
+
* This method can be used for:
|
|
686
|
+
* - Implementing human-in-the-loop workflows
|
|
687
|
+
* - Modifying graph state during breakpoints
|
|
688
|
+
* - Integrating external inputs into the graph
|
|
689
|
+
*
|
|
690
|
+
* @param inputConfig - Configuration for the update
|
|
691
|
+
* @param values - The values to update the state with
|
|
692
|
+
* @param asNode - Optional node name to attribute the update to
|
|
693
|
+
* @returns Updated configuration
|
|
694
|
+
* @throws {GraphValueError} If no checkpointer is configured
|
|
695
|
+
* @throws {InvalidUpdateError} If the update cannot be attributed to a node
|
|
444
696
|
*/
|
|
445
697
|
async updateState(inputConfig, values, asNode) {
|
|
446
698
|
const checkpointer = inputConfig.configurable?.[CONFIG_KEY_CHECKPOINTER] ?? this.checkpointer;
|
|
@@ -693,6 +945,24 @@ export class Pregel extends Runnable {
|
|
|
693
945
|
}
|
|
694
946
|
return patchCheckpointMap(nextConfig, saved ? saved.metadata : undefined);
|
|
695
947
|
}
|
|
948
|
+
/**
|
|
949
|
+
* Gets the default values for various graph configuration options.
|
|
950
|
+
* This is an internal method used to process and normalize configuration options.
|
|
951
|
+
*
|
|
952
|
+
* @param config - The input configuration options
|
|
953
|
+
* @returns A tuple containing normalized values for:
|
|
954
|
+
* - debug mode
|
|
955
|
+
* - stream modes
|
|
956
|
+
* - input keys
|
|
957
|
+
* - output keys
|
|
958
|
+
* - remaining config
|
|
959
|
+
* - interrupt before nodes
|
|
960
|
+
* - interrupt after nodes
|
|
961
|
+
* - checkpointer
|
|
962
|
+
* - store
|
|
963
|
+
* - whether stream mode is single
|
|
964
|
+
* @internal
|
|
965
|
+
*/
|
|
696
966
|
_defaults(config) {
|
|
697
967
|
const { debug, streamMode, inputKeys, outputKeys, interruptAfter, interruptBefore, ...rest } = config;
|
|
698
968
|
let streamModeSingle = true;
|
|
@@ -752,19 +1022,20 @@ export class Pregel extends Runnable {
|
|
|
752
1022
|
];
|
|
753
1023
|
}
|
|
754
1024
|
/**
|
|
755
|
-
*
|
|
756
|
-
*
|
|
757
|
-
*
|
|
758
|
-
*
|
|
759
|
-
*
|
|
760
|
-
*
|
|
761
|
-
*
|
|
762
|
-
*
|
|
763
|
-
*
|
|
764
|
-
*
|
|
765
|
-
*
|
|
766
|
-
* @param
|
|
767
|
-
* @param options
|
|
1025
|
+
* Streams the execution of the graph, emitting state updates as they occur.
|
|
1026
|
+
* This is the primary method for observing graph execution in real-time.
|
|
1027
|
+
*
|
|
1028
|
+
* Stream modes:
|
|
1029
|
+
* - "values": Emits complete state after each step
|
|
1030
|
+
* - "updates": Emits only state changes after each step
|
|
1031
|
+
* - "debug": Emits detailed debug information
|
|
1032
|
+
* - "messages": Emits messages from within nodes
|
|
1033
|
+
*
|
|
1034
|
+
* For more details, see the [Streaming how-to guides](../../how-tos/#streaming_1).
|
|
1035
|
+
*
|
|
1036
|
+
* @param input - The input to start graph execution with
|
|
1037
|
+
* @param options - Configuration options for streaming
|
|
1038
|
+
* @returns An async iterable stream of graph state updates
|
|
768
1039
|
*/
|
|
769
1040
|
async stream(input, options) {
|
|
770
1041
|
// The ensureConfig method called internally defaults recursionLimit to 25 if not
|
|
@@ -778,6 +1049,17 @@ export class Pregel extends Runnable {
|
|
|
778
1049
|
};
|
|
779
1050
|
return super.stream(input, config);
|
|
780
1051
|
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Prepares channel specifications and managed values for graph execution.
|
|
1054
|
+
* This is an internal method used to set up the graph's communication channels
|
|
1055
|
+
* and managed state before execution.
|
|
1056
|
+
*
|
|
1057
|
+
* @param config - Configuration for preparing specs
|
|
1058
|
+
* @param options - Additional options
|
|
1059
|
+
* @param options.skipManaged - Whether to skip initialization of managed values
|
|
1060
|
+
* @returns Object containing channel specs and managed value mapping
|
|
1061
|
+
* @internal
|
|
1062
|
+
*/
|
|
781
1063
|
async prepareSpecs(config, options) {
|
|
782
1064
|
const configForManaged = {
|
|
783
1065
|
...config,
|
|
@@ -822,6 +1104,15 @@ export class Pregel extends Runnable {
|
|
|
822
1104
|
managed,
|
|
823
1105
|
};
|
|
824
1106
|
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Internal iterator used by stream() to generate state updates.
|
|
1109
|
+
* This method handles the core logic of graph execution and streaming.
|
|
1110
|
+
*
|
|
1111
|
+
* @param input - The input to start graph execution with
|
|
1112
|
+
* @param options - Configuration options for streaming
|
|
1113
|
+
* @returns AsyncGenerator yielding state updates
|
|
1114
|
+
* @internal
|
|
1115
|
+
*/
|
|
825
1116
|
async *_streamIterator(input, options) {
|
|
826
1117
|
const streamSubgraphs = options?.subgraphs;
|
|
827
1118
|
const inputConfig = ensureLangGraphConfig(this.config, options);
|
|
@@ -971,16 +1262,6 @@ export class Pregel extends Runnable {
|
|
|
971
1262
|
* Run the graph with a single input and config.
|
|
972
1263
|
* @param input The input to the graph.
|
|
973
1264
|
* @param options The configuration to use for the run.
|
|
974
|
-
* @param options.streamMode The mode to stream output. Defaults to value set on initialization.
|
|
975
|
-
* Options are "values", "updates", and "debug". Default is "values".
|
|
976
|
-
* values: Emit the current values of the state for each step.
|
|
977
|
-
* updates: Emit only the updates to the state for each step.
|
|
978
|
-
* Output is a dict with the node name as key and the updated values as value.
|
|
979
|
-
* debug: Emit debug events for each step.
|
|
980
|
-
* @param options.outputKeys The keys to stream. Defaults to all non-context channels.
|
|
981
|
-
* @param options.interruptBefore Nodes to interrupt before.
|
|
982
|
-
* @param options.interruptAfter Nodes to interrupt after.
|
|
983
|
-
* @param options.debug Whether to print debug information during execution.
|
|
984
1265
|
*/
|
|
985
1266
|
async invoke(input, options) {
|
|
986
1267
|
const streamMode = options?.streamMode ?? "values";
|
package/dist/pregel/io.cjs
CHANGED
|
@@ -157,10 +157,15 @@ function* mapOutputValues(outputChannels, pendingWrites, channels
|
|
|
157
157
|
exports.mapOutputValues = mapOutputValues;
|
|
158
158
|
/**
|
|
159
159
|
* Map pending writes (a sequence of tuples (channel, value)) to output chunk.
|
|
160
|
+
* @internal
|
|
161
|
+
*
|
|
162
|
+
* @param outputChannels - The channels to output.
|
|
163
|
+
* @param tasks - The tasks to output.
|
|
164
|
+
* @param cached - Whether the output is cached.
|
|
165
|
+
*
|
|
166
|
+
* @returns A generator that yields the output chunk (if any).
|
|
160
167
|
*/
|
|
161
|
-
function* mapOutputUpdates(outputChannels, tasks, cached
|
|
162
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
163
|
-
) {
|
|
168
|
+
function* mapOutputUpdates(outputChannels, tasks, cached) {
|
|
164
169
|
const outputTasks = tasks.filter(([task, ww]) => {
|
|
165
170
|
return ((task.config === undefined || !task.config.tags?.includes(constants_js_1.TAG_HIDDEN)) &&
|
|
166
171
|
ww[0][0] !== constants_js_1.ERROR &&
|
|
@@ -169,47 +174,67 @@ function* mapOutputUpdates(outputChannels, tasks, cached
|
|
|
169
174
|
if (!outputTasks.length) {
|
|
170
175
|
return;
|
|
171
176
|
}
|
|
172
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
173
177
|
let updated;
|
|
174
178
|
if (outputTasks.some(([task]) => task.writes.some(([chan, _]) => chan === constants_js_1.RETURN))) {
|
|
179
|
+
// TODO: probably should assert that RETURN is the only "non-special" channel (starts with "__")
|
|
175
180
|
updated = outputTasks.flatMap(([task]) => task.writes
|
|
176
181
|
.filter(([chan, _]) => chan === constants_js_1.RETURN)
|
|
177
182
|
.map(([_, value]) => [task.name, value]));
|
|
178
183
|
}
|
|
179
184
|
else if (!Array.isArray(outputChannels)) {
|
|
185
|
+
// special case where graph state is a single channel (MessageGraph)
|
|
186
|
+
// probably using this in functional API, too
|
|
180
187
|
updated = outputTasks.flatMap(([task]) => task.writes
|
|
181
188
|
.filter(([chan, _]) => chan === outputChannels)
|
|
182
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
183
189
|
.map(([_, value]) => [task.name, value]));
|
|
184
190
|
}
|
|
185
191
|
else {
|
|
186
|
-
updated = outputTasks
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
192
|
+
updated = outputTasks.flatMap(([task]) => {
|
|
193
|
+
const { writes } = task;
|
|
194
|
+
const counts = {};
|
|
195
|
+
for (const [chan] of writes) {
|
|
196
|
+
if (outputChannels.includes(chan)) {
|
|
197
|
+
counts[chan] = (counts[chan] || 0) + 1;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (Object.values(counts).some((count) => count > 1)) {
|
|
201
|
+
// Multiple writes to the same channel: create separate entries
|
|
202
|
+
return writes
|
|
203
|
+
.filter(([chan]) => outputChannels.includes(chan))
|
|
204
|
+
.map(([chan, value]) => [task.name, { [chan]: value }]);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
// Single write to each channel: create a single combined entry
|
|
208
|
+
return [
|
|
209
|
+
[
|
|
210
|
+
task.name,
|
|
211
|
+
Object.fromEntries(writes.filter(([chan]) => outputChannels.includes(chan))),
|
|
212
|
+
],
|
|
213
|
+
];
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
const grouped = {};
|
|
196
218
|
for (const [node, value] of updated) {
|
|
219
|
+
if (!(node in grouped)) {
|
|
220
|
+
grouped[node] = [];
|
|
221
|
+
}
|
|
197
222
|
grouped[node].push(value);
|
|
198
223
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
224
|
+
const flattened = {};
|
|
225
|
+
for (const node in grouped) {
|
|
226
|
+
if (grouped[node].length === 1) {
|
|
227
|
+
const [write] = grouped[node];
|
|
228
|
+
flattened[node] = write;
|
|
202
229
|
}
|
|
203
|
-
else
|
|
204
|
-
|
|
205
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
206
|
-
grouped[node] = value[0];
|
|
230
|
+
else {
|
|
231
|
+
flattened[node] = grouped[node];
|
|
207
232
|
}
|
|
208
233
|
}
|
|
209
234
|
if (cached) {
|
|
210
|
-
|
|
235
|
+
flattened["__metadata__"] = { cached };
|
|
211
236
|
}
|
|
212
|
-
yield
|
|
237
|
+
yield flattened;
|
|
213
238
|
}
|
|
214
239
|
exports.mapOutputUpdates = mapOutputUpdates;
|
|
215
240
|
function single(iter) {
|