@langchain/langgraph 0.1.9 → 0.1.10-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/graph/graph.d.ts +1 -2
- package/dist/graph/state.cjs +85 -18
- package/dist/graph/state.d.ts +20 -8
- package/dist/graph/state.js +85 -18
- package/dist/prebuilt/agent_executor.d.ts +1 -1
- package/dist/prebuilt/react_agent_executor.d.ts +1 -2
- package/dist/pregel/algo.d.ts +2 -2
- package/dist/pregel/index.cjs +3 -1
- package/dist/pregel/index.d.ts +2 -2
- package/dist/pregel/index.js +3 -1
- package/dist/pregel/loop.cjs +33 -35
- package/dist/pregel/loop.d.ts +11 -8
- package/dist/pregel/loop.js +33 -35
- package/dist/pregel/types.d.ts +1 -2
- package/dist/pregel/validate.d.ts +1 -1
- package/package.json +1 -1
package/dist/graph/graph.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Runnable, RunnableConfig, RunnableLike } from "@langchain/core/runnables";
|
|
2
2
|
import { Graph as RunnableGraph } from "@langchain/core/runnables/graph";
|
|
3
|
-
import { BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
3
|
+
import { All, BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
4
4
|
import { PregelNode } from "../pregel/read.js";
|
|
5
5
|
import { Pregel } from "../pregel/index.js";
|
|
6
6
|
import type { PregelParams } from "../pregel/types.js";
|
|
7
7
|
import { BaseChannel } from "../channels/base.js";
|
|
8
|
-
import { All } from "../pregel/types.js";
|
|
9
8
|
import { Send } from "../constants.js";
|
|
10
9
|
import { RunnableCallable } from "../utils.js";
|
|
11
10
|
/** Special reserved node name denoting the start of a graph. */
|
package/dist/graph/state.cjs
CHANGED
|
@@ -82,7 +82,7 @@ class StateGraph extends graph_js_1.Graph {
|
|
|
82
82
|
enumerable: true,
|
|
83
83
|
configurable: true,
|
|
84
84
|
writable: true,
|
|
85
|
-
value:
|
|
85
|
+
value: {}
|
|
86
86
|
});
|
|
87
87
|
// TODO: this doesn't dedupe edges as in py, so worth fixing at some point
|
|
88
88
|
Object.defineProperty(this, "waitingEdges", {
|
|
@@ -91,21 +91,50 @@ class StateGraph extends graph_js_1.Graph {
|
|
|
91
91
|
writable: true,
|
|
92
92
|
value: new Set()
|
|
93
93
|
});
|
|
94
|
-
|
|
94
|
+
Object.defineProperty(this, "schema", {
|
|
95
|
+
enumerable: true,
|
|
96
|
+
configurable: true,
|
|
97
|
+
writable: true,
|
|
98
|
+
value: void 0
|
|
99
|
+
});
|
|
100
|
+
Object.defineProperty(this, "input", {
|
|
101
|
+
enumerable: true,
|
|
102
|
+
configurable: true,
|
|
103
|
+
writable: true,
|
|
104
|
+
value: void 0
|
|
105
|
+
});
|
|
106
|
+
Object.defineProperty(this, "output", {
|
|
107
|
+
enumerable: true,
|
|
108
|
+
configurable: true,
|
|
109
|
+
writable: true,
|
|
110
|
+
value: void 0
|
|
111
|
+
});
|
|
112
|
+
if (isStateGraphArgsWithInputOutputSchemas(fields)) {
|
|
113
|
+
this.schema = fields.input.spec;
|
|
114
|
+
this.input = fields.input.spec;
|
|
115
|
+
this.output = fields.output.spec;
|
|
116
|
+
}
|
|
117
|
+
else if (isStateGraphArgsWithStateSchema(fields)) {
|
|
118
|
+
this.schema = fields.stateSchema.spec;
|
|
119
|
+
this.input = (fields.input?.spec ?? this.schema);
|
|
120
|
+
this.output = (fields.output?.spec ?? this.schema);
|
|
121
|
+
}
|
|
122
|
+
else if (isStateDefinition(fields) || isAnnotationRoot(fields)) {
|
|
95
123
|
const spec = isAnnotationRoot(fields) ? fields.spec : fields;
|
|
96
|
-
this.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
else {
|
|
102
|
-
this.channels[key] = val;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
124
|
+
this.schema = spec;
|
|
125
|
+
}
|
|
126
|
+
else if (isStateGraphArgs(fields)) {
|
|
127
|
+
const spec = _getChannels(fields.channels);
|
|
128
|
+
this.schema = spec;
|
|
105
129
|
}
|
|
106
130
|
else {
|
|
107
|
-
|
|
131
|
+
throw new Error("Invalid StateGraph input.");
|
|
108
132
|
}
|
|
133
|
+
this.input = this.input ?? this.schema;
|
|
134
|
+
this.output = this.output ?? this.schema;
|
|
135
|
+
this._addSchema(this.schema);
|
|
136
|
+
this._addSchema(this.input);
|
|
137
|
+
this._addSchema(this.output);
|
|
109
138
|
for (const c of Object.values(this.channels)) {
|
|
110
139
|
if (c.lc_graph_name === "BinaryOperatorAggregate") {
|
|
111
140
|
this.supportMultipleEdges = true;
|
|
@@ -119,6 +148,27 @@ class StateGraph extends graph_js_1.Graph {
|
|
|
119
148
|
...Array.from(this.waitingEdges).flatMap(([starts, end]) => starts.map((start) => [start, end])),
|
|
120
149
|
]);
|
|
121
150
|
}
|
|
151
|
+
_addSchema(stateDefinition) {
|
|
152
|
+
for (const [key, val] of Object.entries(stateDefinition)) {
|
|
153
|
+
let channel;
|
|
154
|
+
if (typeof val === "function") {
|
|
155
|
+
channel = val();
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
channel = val;
|
|
159
|
+
}
|
|
160
|
+
if (this.channels[key] !== undefined) {
|
|
161
|
+
if (this.channels[key].lc_graph_name !== channel.lc_graph_name) {
|
|
162
|
+
if (channel.lc_graph_name !== "LastValue") {
|
|
163
|
+
throw new Error(`Channel "${key}" already exists with a different type.`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
this.channels[key] = channel;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
122
172
|
addNode(key, action, options) {
|
|
123
173
|
if (key in this.channels) {
|
|
124
174
|
throw new Error(`${key} is already being used as a state attribute (a.k.a. a channel), cannot also be used as a node name.`);
|
|
@@ -173,10 +223,10 @@ class StateGraph extends graph_js_1.Graph {
|
|
|
173
223
|
...(Array.isArray(interruptAfter) ? interruptAfter : []),
|
|
174
224
|
]);
|
|
175
225
|
// prepare output channels
|
|
176
|
-
const stateKeys = Object.keys(this.
|
|
177
|
-
const outputChannels = stateKeys.length === 1 && stateKeys[0] === ROOT
|
|
178
|
-
|
|
179
|
-
|
|
226
|
+
const stateKeys = Object.keys(this.schema);
|
|
227
|
+
const outputChannels = stateKeys.length === 1 && stateKeys[0] === ROOT ? ROOT : stateKeys;
|
|
228
|
+
const outputKeys = Object.keys(this.output);
|
|
229
|
+
const streamChannels = outputKeys.length === 1 && outputKeys[0] === ROOT ? ROOT : outputKeys;
|
|
180
230
|
// create empty compiled graph
|
|
181
231
|
const compiled = new CompiledStateGraph({
|
|
182
232
|
builder: this,
|
|
@@ -191,7 +241,7 @@ class StateGraph extends graph_js_1.Graph {
|
|
|
191
241
|
},
|
|
192
242
|
inputChannels: graph_js_1.START,
|
|
193
243
|
outputChannels,
|
|
194
|
-
streamChannels
|
|
244
|
+
streamChannels,
|
|
195
245
|
streamMode: "updates",
|
|
196
246
|
});
|
|
197
247
|
// attach nodes, edges and branches
|
|
@@ -229,7 +279,7 @@ function _getChannels(schema) {
|
|
|
229
279
|
}
|
|
230
280
|
class CompiledStateGraph extends graph_js_1.CompiledGraph {
|
|
231
281
|
attachNode(key, node) {
|
|
232
|
-
const stateKeys = Object.keys(this.builder.
|
|
282
|
+
const stateKeys = Object.keys(this.builder.input);
|
|
233
283
|
function getStateKey(key, input) {
|
|
234
284
|
if (!input) {
|
|
235
285
|
return write_js_1.SKIP_WRITE;
|
|
@@ -367,3 +417,20 @@ function isAnnotationRoot(obj) {
|
|
|
367
417
|
"lc_graph_name" in obj &&
|
|
368
418
|
obj.lc_graph_name === "AnnotationRoot");
|
|
369
419
|
}
|
|
420
|
+
function isStateGraphArgs(obj) {
|
|
421
|
+
return (typeof obj === "object" &&
|
|
422
|
+
obj !== null &&
|
|
423
|
+
obj.channels !== undefined);
|
|
424
|
+
}
|
|
425
|
+
function isStateGraphArgsWithStateSchema(obj) {
|
|
426
|
+
return (typeof obj === "object" &&
|
|
427
|
+
obj !== null &&
|
|
428
|
+
obj.stateSchema !== undefined);
|
|
429
|
+
}
|
|
430
|
+
function isStateGraphArgsWithInputOutputSchemas(obj) {
|
|
431
|
+
return (typeof obj === "object" &&
|
|
432
|
+
obj !== null &&
|
|
433
|
+
obj.stateSchema === undefined &&
|
|
434
|
+
obj.input !== undefined &&
|
|
435
|
+
obj.output !== undefined);
|
|
436
|
+
}
|
package/dist/graph/state.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { RunnableLike } from "@langchain/core/runnables";
|
|
2
|
-
import { BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
2
|
+
import { All, BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
3
3
|
import { BaseChannel } from "../channels/base.js";
|
|
4
4
|
import { END, CompiledGraph, Graph, START, Branch, AddNodeOptions, NodeSpec } from "./graph.js";
|
|
5
|
-
import { All } from "../pregel/types.js";
|
|
6
5
|
import { AnnotationRoot, SingleReducer, StateDefinition, StateType, UpdateType } from "./annotation.js";
|
|
7
6
|
import type { RetryPolicy } from "../pregel/utils.js";
|
|
8
7
|
export type ChannelReducers<Channels extends object> = {
|
|
@@ -22,6 +21,15 @@ export type StateGraphNodeSpec<RunInput, RunOutput> = NodeSpec<RunInput, RunOutp
|
|
|
22
21
|
export type StateGraphAddNodeOptions = {
|
|
23
22
|
retryPolicy?: RetryPolicy;
|
|
24
23
|
} & AddNodeOptions;
|
|
24
|
+
export type StateGraphArgsWithStateSchema<SD extends StateDefinition, I extends StateDefinition, O extends StateDefinition> = {
|
|
25
|
+
stateSchema: AnnotationRoot<SD>;
|
|
26
|
+
input?: AnnotationRoot<I>;
|
|
27
|
+
output?: AnnotationRoot<O>;
|
|
28
|
+
};
|
|
29
|
+
export type StateGraphArgsWithInputOutputSchemas<SD extends StateDefinition, O extends StateDefinition = SD> = {
|
|
30
|
+
input: AnnotationRoot<SD>;
|
|
31
|
+
output: AnnotationRoot<O>;
|
|
32
|
+
};
|
|
25
33
|
/**
|
|
26
34
|
* A graph whose nodes communicate by reading and writing to a shared state.
|
|
27
35
|
* Each node takes a defined `State` as input and returns a `Partial<State>`.
|
|
@@ -84,21 +92,25 @@ export type StateGraphAddNodeOptions = {
|
|
|
84
92
|
* // }
|
|
85
93
|
* ```
|
|
86
94
|
*/
|
|
87
|
-
export declare class StateGraph<SD extends StateDefinition | unknown, S = SD extends StateDefinition ? StateType<SD> : SD, U = SD extends StateDefinition ? UpdateType<SD> : Partial<S>, N extends string = typeof START> extends Graph<N, S, U, StateGraphNodeSpec<S, U>> {
|
|
95
|
+
export declare class StateGraph<SD extends StateDefinition | unknown, S = SD extends StateDefinition ? StateType<SD> : SD, U = SD extends StateDefinition ? UpdateType<SD> : Partial<S>, N extends string = typeof START, I extends StateDefinition = SD extends StateDefinition ? SD : StateDefinition, O extends StateDefinition = SD extends StateDefinition ? SD : StateDefinition> extends Graph<N, S, U, StateGraphNodeSpec<S, U>> {
|
|
88
96
|
channels: Record<string, BaseChannel>;
|
|
89
97
|
waitingEdges: Set<[N[], N]>;
|
|
90
|
-
|
|
98
|
+
schema: StateDefinition;
|
|
99
|
+
input: I;
|
|
100
|
+
output: O;
|
|
101
|
+
constructor(fields: SD extends StateDefinition ? SD | AnnotationRoot<SD> | StateGraphArgs<S> | StateGraphArgsWithStateSchema<SD, I, O> | StateGraphArgsWithInputOutputSchemas<SD, O> : StateGraphArgs<S>);
|
|
91
102
|
get allEdges(): Set<[string, string]>;
|
|
92
|
-
|
|
103
|
+
_addSchema(stateDefinition: StateDefinition): void;
|
|
104
|
+
addNode<K extends string, NodeInput = S>(key: K, action: RunnableLike<NodeInput, U>, options?: StateGraphAddNodeOptions): StateGraph<SD, S, U, N | K, I, O>;
|
|
93
105
|
addEdge(startKey: typeof START | N | N[], endKey: N | typeof END): this;
|
|
94
106
|
compile({ checkpointer, interruptBefore, interruptAfter, }?: {
|
|
95
107
|
checkpointer?: BaseCheckpointSaver;
|
|
96
108
|
interruptBefore?: N[] | All;
|
|
97
109
|
interruptAfter?: N[] | All;
|
|
98
|
-
}): CompiledStateGraph<S, U, N>;
|
|
110
|
+
}): CompiledStateGraph<S, U, N, I, O>;
|
|
99
111
|
}
|
|
100
|
-
export declare class CompiledStateGraph<S, U, N extends string = typeof START> extends CompiledGraph<N, S, U> {
|
|
101
|
-
builder: StateGraph<unknown, S, U, N>;
|
|
112
|
+
export declare class CompiledStateGraph<S, U, N extends string = typeof START, I extends StateDefinition = StateDefinition, O extends StateDefinition = StateDefinition> extends CompiledGraph<N, S, U> {
|
|
113
|
+
builder: StateGraph<unknown, S, U, N, I, O>;
|
|
102
114
|
attachNode(key: typeof START, node?: never): void;
|
|
103
115
|
attachNode(key: N, node: StateGraphNodeSpec<S, U>): void;
|
|
104
116
|
attachEdge(start: N | N[] | "__start__", end: N | "__end__"): void;
|
package/dist/graph/state.js
CHANGED
|
@@ -79,7 +79,7 @@ export class StateGraph extends Graph {
|
|
|
79
79
|
enumerable: true,
|
|
80
80
|
configurable: true,
|
|
81
81
|
writable: true,
|
|
82
|
-
value:
|
|
82
|
+
value: {}
|
|
83
83
|
});
|
|
84
84
|
// TODO: this doesn't dedupe edges as in py, so worth fixing at some point
|
|
85
85
|
Object.defineProperty(this, "waitingEdges", {
|
|
@@ -88,21 +88,50 @@ export class StateGraph extends Graph {
|
|
|
88
88
|
writable: true,
|
|
89
89
|
value: new Set()
|
|
90
90
|
});
|
|
91
|
-
|
|
91
|
+
Object.defineProperty(this, "schema", {
|
|
92
|
+
enumerable: true,
|
|
93
|
+
configurable: true,
|
|
94
|
+
writable: true,
|
|
95
|
+
value: void 0
|
|
96
|
+
});
|
|
97
|
+
Object.defineProperty(this, "input", {
|
|
98
|
+
enumerable: true,
|
|
99
|
+
configurable: true,
|
|
100
|
+
writable: true,
|
|
101
|
+
value: void 0
|
|
102
|
+
});
|
|
103
|
+
Object.defineProperty(this, "output", {
|
|
104
|
+
enumerable: true,
|
|
105
|
+
configurable: true,
|
|
106
|
+
writable: true,
|
|
107
|
+
value: void 0
|
|
108
|
+
});
|
|
109
|
+
if (isStateGraphArgsWithInputOutputSchemas(fields)) {
|
|
110
|
+
this.schema = fields.input.spec;
|
|
111
|
+
this.input = fields.input.spec;
|
|
112
|
+
this.output = fields.output.spec;
|
|
113
|
+
}
|
|
114
|
+
else if (isStateGraphArgsWithStateSchema(fields)) {
|
|
115
|
+
this.schema = fields.stateSchema.spec;
|
|
116
|
+
this.input = (fields.input?.spec ?? this.schema);
|
|
117
|
+
this.output = (fields.output?.spec ?? this.schema);
|
|
118
|
+
}
|
|
119
|
+
else if (isStateDefinition(fields) || isAnnotationRoot(fields)) {
|
|
92
120
|
const spec = isAnnotationRoot(fields) ? fields.spec : fields;
|
|
93
|
-
this.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
else {
|
|
99
|
-
this.channels[key] = val;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
121
|
+
this.schema = spec;
|
|
122
|
+
}
|
|
123
|
+
else if (isStateGraphArgs(fields)) {
|
|
124
|
+
const spec = _getChannels(fields.channels);
|
|
125
|
+
this.schema = spec;
|
|
102
126
|
}
|
|
103
127
|
else {
|
|
104
|
-
|
|
128
|
+
throw new Error("Invalid StateGraph input.");
|
|
105
129
|
}
|
|
130
|
+
this.input = this.input ?? this.schema;
|
|
131
|
+
this.output = this.output ?? this.schema;
|
|
132
|
+
this._addSchema(this.schema);
|
|
133
|
+
this._addSchema(this.input);
|
|
134
|
+
this._addSchema(this.output);
|
|
106
135
|
for (const c of Object.values(this.channels)) {
|
|
107
136
|
if (c.lc_graph_name === "BinaryOperatorAggregate") {
|
|
108
137
|
this.supportMultipleEdges = true;
|
|
@@ -116,6 +145,27 @@ export class StateGraph extends Graph {
|
|
|
116
145
|
...Array.from(this.waitingEdges).flatMap(([starts, end]) => starts.map((start) => [start, end])),
|
|
117
146
|
]);
|
|
118
147
|
}
|
|
148
|
+
_addSchema(stateDefinition) {
|
|
149
|
+
for (const [key, val] of Object.entries(stateDefinition)) {
|
|
150
|
+
let channel;
|
|
151
|
+
if (typeof val === "function") {
|
|
152
|
+
channel = val();
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
channel = val;
|
|
156
|
+
}
|
|
157
|
+
if (this.channels[key] !== undefined) {
|
|
158
|
+
if (this.channels[key].lc_graph_name !== channel.lc_graph_name) {
|
|
159
|
+
if (channel.lc_graph_name !== "LastValue") {
|
|
160
|
+
throw new Error(`Channel "${key}" already exists with a different type.`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
this.channels[key] = channel;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
119
169
|
addNode(key, action, options) {
|
|
120
170
|
if (key in this.channels) {
|
|
121
171
|
throw new Error(`${key} is already being used as a state attribute (a.k.a. a channel), cannot also be used as a node name.`);
|
|
@@ -170,10 +220,10 @@ export class StateGraph extends Graph {
|
|
|
170
220
|
...(Array.isArray(interruptAfter) ? interruptAfter : []),
|
|
171
221
|
]);
|
|
172
222
|
// prepare output channels
|
|
173
|
-
const stateKeys = Object.keys(this.
|
|
174
|
-
const outputChannels = stateKeys.length === 1 && stateKeys[0] === ROOT
|
|
175
|
-
|
|
176
|
-
|
|
223
|
+
const stateKeys = Object.keys(this.schema);
|
|
224
|
+
const outputChannels = stateKeys.length === 1 && stateKeys[0] === ROOT ? ROOT : stateKeys;
|
|
225
|
+
const outputKeys = Object.keys(this.output);
|
|
226
|
+
const streamChannels = outputKeys.length === 1 && outputKeys[0] === ROOT ? ROOT : outputKeys;
|
|
177
227
|
// create empty compiled graph
|
|
178
228
|
const compiled = new CompiledStateGraph({
|
|
179
229
|
builder: this,
|
|
@@ -188,7 +238,7 @@ export class StateGraph extends Graph {
|
|
|
188
238
|
},
|
|
189
239
|
inputChannels: START,
|
|
190
240
|
outputChannels,
|
|
191
|
-
streamChannels
|
|
241
|
+
streamChannels,
|
|
192
242
|
streamMode: "updates",
|
|
193
243
|
});
|
|
194
244
|
// attach nodes, edges and branches
|
|
@@ -225,7 +275,7 @@ function _getChannels(schema) {
|
|
|
225
275
|
}
|
|
226
276
|
export class CompiledStateGraph extends CompiledGraph {
|
|
227
277
|
attachNode(key, node) {
|
|
228
|
-
const stateKeys = Object.keys(this.builder.
|
|
278
|
+
const stateKeys = Object.keys(this.builder.input);
|
|
229
279
|
function getStateKey(key, input) {
|
|
230
280
|
if (!input) {
|
|
231
281
|
return SKIP_WRITE;
|
|
@@ -362,3 +412,20 @@ function isAnnotationRoot(obj) {
|
|
|
362
412
|
"lc_graph_name" in obj &&
|
|
363
413
|
obj.lc_graph_name === "AnnotationRoot");
|
|
364
414
|
}
|
|
415
|
+
function isStateGraphArgs(obj) {
|
|
416
|
+
return (typeof obj === "object" &&
|
|
417
|
+
obj !== null &&
|
|
418
|
+
obj.channels !== undefined);
|
|
419
|
+
}
|
|
420
|
+
function isStateGraphArgsWithStateSchema(obj) {
|
|
421
|
+
return (typeof obj === "object" &&
|
|
422
|
+
obj !== null &&
|
|
423
|
+
obj.stateSchema !== undefined);
|
|
424
|
+
}
|
|
425
|
+
function isStateGraphArgsWithInputOutputSchemas(obj) {
|
|
426
|
+
return (typeof obj === "object" &&
|
|
427
|
+
obj !== null &&
|
|
428
|
+
obj.stateSchema === undefined &&
|
|
429
|
+
obj.input !== undefined &&
|
|
430
|
+
obj.output !== undefined);
|
|
431
|
+
}
|
|
@@ -18,5 +18,5 @@ export interface AgentExecutorState {
|
|
|
18
18
|
export declare function createAgentExecutor({ agentRunnable, tools, }: {
|
|
19
19
|
agentRunnable: Runnable;
|
|
20
20
|
tools: Array<Tool> | ToolExecutor;
|
|
21
|
-
}): import("../graph/state.js").CompiledStateGraph<AgentExecutorState, Partial<AgentExecutorState>, "__start__" | "agent" | "action">;
|
|
21
|
+
}): import("../graph/state.js").CompiledStateGraph<AgentExecutorState, Partial<AgentExecutorState>, "__start__" | "agent" | "action", import("../graph/annotation.js").StateDefinition, import("../graph/annotation.js").StateDefinition>;
|
|
22
22
|
export {};
|
|
@@ -2,11 +2,10 @@ import { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
|
2
2
|
import { BaseMessage, SystemMessage } from "@langchain/core/messages";
|
|
3
3
|
import { Runnable, RunnableToolLike } from "@langchain/core/runnables";
|
|
4
4
|
import { StructuredToolInterface } from "@langchain/core/tools";
|
|
5
|
-
import { BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
5
|
+
import { All, BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
6
6
|
import { START } from "../graph/index.js";
|
|
7
7
|
import { MessagesAnnotation } from "../graph/messages_annotation.js";
|
|
8
8
|
import { CompiledStateGraph } from "../graph/state.js";
|
|
9
|
-
import { All } from "../pregel/types.js";
|
|
10
9
|
import { ToolNode } from "./tool_node.js";
|
|
11
10
|
export interface AgentState {
|
|
12
11
|
messages: BaseMessage[];
|
package/dist/pregel/algo.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { RunnableConfig } from "@langchain/core/runnables";
|
|
2
2
|
import { CallbackManagerForChainRun } from "@langchain/core/callbacks/manager";
|
|
3
|
-
import { BaseCheckpointSaver, Checkpoint, ReadonlyCheckpoint, type PendingWrite } from "@langchain/langgraph-checkpoint";
|
|
3
|
+
import { All, BaseCheckpointSaver, Checkpoint, ReadonlyCheckpoint, type PendingWrite } from "@langchain/langgraph-checkpoint";
|
|
4
4
|
import { BaseChannel } from "../channels/base.js";
|
|
5
5
|
import { PregelNode } from "./read.js";
|
|
6
|
-
import {
|
|
6
|
+
import { PregelExecutableTask, PregelTaskDescription } from "./types.js";
|
|
7
7
|
/**
|
|
8
8
|
* Construct a type with a set of properties K of type T
|
|
9
9
|
*/
|
package/dist/pregel/index.cjs
CHANGED
|
@@ -464,13 +464,15 @@ class Pregel extends runnables_1.Runnable {
|
|
|
464
464
|
input,
|
|
465
465
|
config,
|
|
466
466
|
checkpointer,
|
|
467
|
-
|
|
467
|
+
nodes: this.nodes,
|
|
468
|
+
channelSpecs: this.channels,
|
|
468
469
|
onBackgroundError,
|
|
469
470
|
outputKeys,
|
|
470
471
|
streamKeys: this.streamChannelsAsIs,
|
|
471
472
|
});
|
|
472
473
|
while (backgroundError === undefined &&
|
|
473
474
|
(await loop.tick({
|
|
475
|
+
inputKeys: this.inputChannels,
|
|
474
476
|
interruptAfter,
|
|
475
477
|
interruptBefore,
|
|
476
478
|
manager: runManager,
|
package/dist/pregel/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Runnable, RunnableConfig, RunnableFunc } from "@langchain/core/runnables";
|
|
2
2
|
import { IterableReadableStream } from "@langchain/core/utils/stream";
|
|
3
|
-
import { BaseCheckpointSaver, CheckpointListOptions } from "@langchain/langgraph-checkpoint";
|
|
3
|
+
import { All, BaseCheckpointSaver, CheckpointListOptions } from "@langchain/langgraph-checkpoint";
|
|
4
4
|
import { BaseChannel } from "../channels/base.js";
|
|
5
5
|
import { PregelNode } from "./read.js";
|
|
6
6
|
import { ChannelWrite } from "./write.js";
|
|
7
|
-
import {
|
|
7
|
+
import { PregelInterface, PregelParams, StateSnapshot, StreamMode } from "./types.js";
|
|
8
8
|
import { StrRecord } from "./algo.js";
|
|
9
9
|
import { RetryPolicy } from "./utils.js";
|
|
10
10
|
type WriteValue = Runnable | RunnableFunc<unknown, unknown> | unknown;
|
package/dist/pregel/index.js
CHANGED
|
@@ -460,13 +460,15 @@ export class Pregel extends Runnable {
|
|
|
460
460
|
input,
|
|
461
461
|
config,
|
|
462
462
|
checkpointer,
|
|
463
|
-
|
|
463
|
+
nodes: this.nodes,
|
|
464
|
+
channelSpecs: this.channels,
|
|
464
465
|
onBackgroundError,
|
|
465
466
|
outputKeys,
|
|
466
467
|
streamKeys: this.streamChannelsAsIs,
|
|
467
468
|
});
|
|
468
469
|
while (backgroundError === undefined &&
|
|
469
470
|
(await loop.tick({
|
|
471
|
+
inputKeys: this.inputChannels,
|
|
470
472
|
interruptAfter,
|
|
471
473
|
interruptBefore,
|
|
472
474
|
manager: runManager,
|
package/dist/pregel/loop.cjs
CHANGED
|
@@ -47,14 +47,6 @@ class PregelLoop {
|
|
|
47
47
|
writable: true,
|
|
48
48
|
value: void 0
|
|
49
49
|
});
|
|
50
|
-
// TODO: Fix typing
|
|
51
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
52
|
-
Object.defineProperty(this, "graph", {
|
|
53
|
-
enumerable: true,
|
|
54
|
-
configurable: true,
|
|
55
|
-
writable: true,
|
|
56
|
-
value: void 0
|
|
57
|
-
});
|
|
58
50
|
Object.defineProperty(this, "channels", {
|
|
59
51
|
enumerable: true,
|
|
60
52
|
configurable: true,
|
|
@@ -103,6 +95,24 @@ class PregelLoop {
|
|
|
103
95
|
writable: true,
|
|
104
96
|
value: void 0
|
|
105
97
|
});
|
|
98
|
+
Object.defineProperty(this, "outputKeys", {
|
|
99
|
+
enumerable: true,
|
|
100
|
+
configurable: true,
|
|
101
|
+
writable: true,
|
|
102
|
+
value: void 0
|
|
103
|
+
});
|
|
104
|
+
Object.defineProperty(this, "streamKeys", {
|
|
105
|
+
enumerable: true,
|
|
106
|
+
configurable: true,
|
|
107
|
+
writable: true,
|
|
108
|
+
value: void 0
|
|
109
|
+
});
|
|
110
|
+
Object.defineProperty(this, "nodes", {
|
|
111
|
+
enumerable: true,
|
|
112
|
+
configurable: true,
|
|
113
|
+
writable: true,
|
|
114
|
+
value: void 0
|
|
115
|
+
});
|
|
106
116
|
Object.defineProperty(this, "status", {
|
|
107
117
|
enumerable: true,
|
|
108
118
|
configurable: true,
|
|
@@ -135,18 +145,6 @@ class PregelLoop {
|
|
|
135
145
|
writable: true,
|
|
136
146
|
value: Promise.resolve()
|
|
137
147
|
});
|
|
138
|
-
Object.defineProperty(this, "outputKeys", {
|
|
139
|
-
enumerable: true,
|
|
140
|
-
configurable: true,
|
|
141
|
-
writable: true,
|
|
142
|
-
value: void 0
|
|
143
|
-
});
|
|
144
|
-
Object.defineProperty(this, "streamKeys", {
|
|
145
|
-
enumerable: true,
|
|
146
|
-
configurable: true,
|
|
147
|
-
writable: true,
|
|
148
|
-
value: void 0
|
|
149
|
-
});
|
|
150
148
|
Object.defineProperty(this, "onBackgroundError", {
|
|
151
149
|
enumerable: true,
|
|
152
150
|
configurable: true,
|
|
@@ -164,7 +162,6 @@ class PregelLoop {
|
|
|
164
162
|
else {
|
|
165
163
|
this.checkpointerGetNextVersion = algo_js_1.increment;
|
|
166
164
|
}
|
|
167
|
-
this.graph = params.graph;
|
|
168
165
|
this.checkpoint = params.checkpoint;
|
|
169
166
|
this.checkpointConfig = params.checkpointConfig;
|
|
170
167
|
this.checkpointMetadata = params.checkpointMetadata;
|
|
@@ -176,6 +173,7 @@ class PregelLoop {
|
|
|
176
173
|
this.isNested = constants_js_1.CONFIG_KEY_READ in (this.config.configurable ?? {});
|
|
177
174
|
this.outputKeys = params.outputKeys;
|
|
178
175
|
this.streamKeys = params.streamKeys;
|
|
176
|
+
this.nodes = params.nodes;
|
|
179
177
|
this.onBackgroundError = params.onBackgroundError;
|
|
180
178
|
}
|
|
181
179
|
static async initialize(params) {
|
|
@@ -200,7 +198,7 @@ class PregelLoop {
|
|
|
200
198
|
const checkpoint = (0, langgraph_checkpoint_1.copyCheckpoint)(saved.checkpoint);
|
|
201
199
|
const checkpointMetadata = { ...saved.metadata };
|
|
202
200
|
const checkpointPendingWrites = saved.pendingWrites ?? [];
|
|
203
|
-
const channels = (0, base_js_1.emptyChannels)(params.
|
|
201
|
+
const channels = (0, base_js_1.emptyChannels)(params.channelSpecs, checkpoint);
|
|
204
202
|
const step = (checkpointMetadata.step ?? 0) + 1;
|
|
205
203
|
const stop = step + (params.config.recursionLimit ?? DEFAULT_LOOP_LIMIT) + 1;
|
|
206
204
|
const checkpointPreviousVersions = { ...checkpoint.channel_versions };
|
|
@@ -208,7 +206,6 @@ class PregelLoop {
|
|
|
208
206
|
input: params.input,
|
|
209
207
|
config: params.config,
|
|
210
208
|
checkpointer: params.checkpointer,
|
|
211
|
-
graph: params.graph,
|
|
212
209
|
checkpoint,
|
|
213
210
|
checkpointMetadata,
|
|
214
211
|
checkpointConfig,
|
|
@@ -217,8 +214,9 @@ class PregelLoop {
|
|
|
217
214
|
stop,
|
|
218
215
|
checkpointPreviousVersions,
|
|
219
216
|
checkpointPendingWrites,
|
|
220
|
-
outputKeys: params.outputKeys,
|
|
221
|
-
streamKeys: params.streamKeys,
|
|
217
|
+
outputKeys: params.outputKeys ?? [],
|
|
218
|
+
streamKeys: params.streamKeys ?? [],
|
|
219
|
+
nodes: params.nodes,
|
|
222
220
|
onBackgroundError: params.onBackgroundError,
|
|
223
221
|
});
|
|
224
222
|
}
|
|
@@ -267,12 +265,12 @@ class PregelLoop {
|
|
|
267
265
|
* @param params
|
|
268
266
|
*/
|
|
269
267
|
async tick(params) {
|
|
270
|
-
const { interruptAfter = [], interruptBefore = [], manager } = params;
|
|
268
|
+
const { inputKeys = [], interruptAfter = [], interruptBefore = [], manager, } = params;
|
|
271
269
|
if (this.status !== "pending") {
|
|
272
270
|
throw new Error(`Cannot tick when status is no longer "pending". Current status: "${this.status}"`);
|
|
273
271
|
}
|
|
274
272
|
if (![INPUT_DONE, INPUT_RESUMING].includes(this.input)) {
|
|
275
|
-
await this._first();
|
|
273
|
+
await this._first(inputKeys);
|
|
276
274
|
}
|
|
277
275
|
else if (this.tasks.every((task) => task.writes.length > 0)) {
|
|
278
276
|
const writes = this.tasks.flatMap((t) => t.writes);
|
|
@@ -283,10 +281,9 @@ class PregelLoop {
|
|
|
283
281
|
this.stream.push(...valuesOutput);
|
|
284
282
|
// clear pending writes
|
|
285
283
|
this.checkpointPendingWrites = [];
|
|
286
|
-
const metadataWrites = (0, io_js_1.mapOutputUpdates)(this.outputKeys, this.tasks).next().value;
|
|
287
284
|
await this._putCheckpoint({
|
|
288
285
|
source: "loop",
|
|
289
|
-
writes:
|
|
286
|
+
writes: (0, io_js_1.mapOutputUpdates)(this.outputKeys, this.tasks).next().value ?? null,
|
|
290
287
|
});
|
|
291
288
|
// after execution, check if we should interrupt
|
|
292
289
|
if ((0, algo_js_1.shouldInterrupt)(this.checkpoint, interruptAfter, this.tasks)) {
|
|
@@ -306,7 +303,7 @@ class PregelLoop {
|
|
|
306
303
|
this.status = "out_of_steps";
|
|
307
304
|
return false;
|
|
308
305
|
}
|
|
309
|
-
const nextTasks = (0, algo_js_1._prepareNextTasks)(this.checkpoint, this.
|
|
306
|
+
const nextTasks = (0, algo_js_1._prepareNextTasks)(this.checkpoint, this.nodes, this.channels, this.config, true, {
|
|
310
307
|
step: this.step,
|
|
311
308
|
checkpointer: this.checkpointer,
|
|
312
309
|
isResuming: this.input === INPUT_RESUMING,
|
|
@@ -316,7 +313,7 @@ class PregelLoop {
|
|
|
316
313
|
// Produce debug output
|
|
317
314
|
if (this.checkpointer) {
|
|
318
315
|
this.stream.push(...(await (0, utils_js_1.gatherIterator)((0, utils_js_1.prefixGenerator)((0, debug_js_1.mapDebugCheckpoint)(this.step - 1, // printing checkpoint for previous step
|
|
319
|
-
this.checkpointConfig, this.channels, this.
|
|
316
|
+
this.checkpointConfig, this.channels, this.streamKeys, this.checkpointMetadata, this.tasks, this.checkpointPendingWrites), "debug"))));
|
|
320
317
|
}
|
|
321
318
|
if (this.tasks.length === 0) {
|
|
322
319
|
this.status = "done";
|
|
@@ -337,6 +334,7 @@ class PregelLoop {
|
|
|
337
334
|
// if all tasks have finished, re-tick
|
|
338
335
|
if (this.tasks.every((task) => task.writes.length > 0)) {
|
|
339
336
|
return this.tick({
|
|
337
|
+
inputKeys,
|
|
340
338
|
interruptAfter,
|
|
341
339
|
interruptBefore,
|
|
342
340
|
manager,
|
|
@@ -362,7 +360,7 @@ class PregelLoop {
|
|
|
362
360
|
* - finding a previous checkpoint
|
|
363
361
|
* - receiving None input (outer graph) or RESUMING flag (subgraph)
|
|
364
362
|
*/
|
|
365
|
-
async _first() {
|
|
363
|
+
async _first(inputKeys) {
|
|
366
364
|
const isResuming = (Object.keys(this.checkpoint.channel_versions).length !== 0 &&
|
|
367
365
|
this.config.configurable?.[constants_js_1.CONFIG_KEY_RESUMING] !== undefined) ||
|
|
368
366
|
this.input === null;
|
|
@@ -379,11 +377,11 @@ class PregelLoop {
|
|
|
379
377
|
// map inputs to channel updates
|
|
380
378
|
}
|
|
381
379
|
else {
|
|
382
|
-
const inputWrites = await (0, utils_js_1.gatherIterator)((0, io_js_1.mapInput)(
|
|
380
|
+
const inputWrites = await (0, utils_js_1.gatherIterator)((0, io_js_1.mapInput)(inputKeys, this.input));
|
|
383
381
|
if (inputWrites.length === 0) {
|
|
384
|
-
throw new errors_js_1.EmptyInputError(`Received no input writes for ${JSON.stringify(
|
|
382
|
+
throw new errors_js_1.EmptyInputError(`Received no input writes for ${JSON.stringify(inputKeys, null, 2)}`);
|
|
385
383
|
}
|
|
386
|
-
const discardTasks = (0, algo_js_1._prepareNextTasks)(this.checkpoint, this.
|
|
384
|
+
const discardTasks = (0, algo_js_1._prepareNextTasks)(this.checkpoint, this.nodes, this.channels, this.config, true, { step: this.step });
|
|
387
385
|
(0, algo_js_1._applyWrites)(this.checkpoint, this.channels, discardTasks.concat([
|
|
388
386
|
{
|
|
389
387
|
name: constants_js_1.INPUT,
|
package/dist/pregel/loop.d.ts
CHANGED
|
@@ -3,21 +3,22 @@ import type { RunnableConfig } from "@langchain/core/runnables";
|
|
|
3
3
|
import type { CallbackManagerForChainRun } from "@langchain/core/callbacks/manager";
|
|
4
4
|
import { BaseCheckpointSaver, Checkpoint, PendingWrite, CheckpointPendingWrite, CheckpointMetadata, All } from "@langchain/langgraph-checkpoint";
|
|
5
5
|
import { BaseChannel } from "../channels/base.js";
|
|
6
|
-
import { PregelExecutableTask,
|
|
6
|
+
import { PregelExecutableTask, StreamMode } from "./types.js";
|
|
7
|
+
import { PregelNode } from "./read.js";
|
|
7
8
|
export type PregelLoopInitializeParams = {
|
|
8
9
|
input?: any;
|
|
9
10
|
config: RunnableConfig;
|
|
10
11
|
checkpointer?: BaseCheckpointSaver;
|
|
11
|
-
|
|
12
|
+
onBackgroundError: (e: Error) => void;
|
|
12
13
|
outputKeys: string | string[];
|
|
13
14
|
streamKeys: string | string[];
|
|
14
|
-
|
|
15
|
+
nodes: Record<string, PregelNode>;
|
|
16
|
+
channelSpecs: Record<string, BaseChannel>;
|
|
15
17
|
};
|
|
16
18
|
type PregelLoopParams = {
|
|
17
19
|
input?: any;
|
|
18
20
|
config: RunnableConfig;
|
|
19
21
|
checkpointer?: BaseCheckpointSaver;
|
|
20
|
-
graph: PregelInterface<any, any>;
|
|
21
22
|
checkpoint: Checkpoint;
|
|
22
23
|
checkpointMetadata: CheckpointMetadata;
|
|
23
24
|
checkpointPreviousVersions: Record<string, string | number>;
|
|
@@ -29,13 +30,13 @@ type PregelLoopParams = {
|
|
|
29
30
|
outputKeys: string | string[];
|
|
30
31
|
streamKeys: string | string[];
|
|
31
32
|
onBackgroundError: (e: Error) => void;
|
|
33
|
+
nodes: Record<string, PregelNode>;
|
|
32
34
|
};
|
|
33
35
|
export declare class PregelLoop {
|
|
34
36
|
protected input?: any;
|
|
35
37
|
config: RunnableConfig;
|
|
36
38
|
protected checkpointer?: BaseCheckpointSaver;
|
|
37
39
|
protected checkpointerGetNextVersion: (current: number | undefined, channel: BaseChannel) => number;
|
|
38
|
-
protected graph: PregelInterface<any, any>;
|
|
39
40
|
channels: Record<string, BaseChannel>;
|
|
40
41
|
protected checkpoint: Checkpoint;
|
|
41
42
|
protected checkpointConfig: RunnableConfig;
|
|
@@ -44,13 +45,14 @@ export declare class PregelLoop {
|
|
|
44
45
|
protected checkpointPreviousVersions: Record<string, string | number>;
|
|
45
46
|
step: number;
|
|
46
47
|
protected stop: number;
|
|
48
|
+
protected outputKeys: string | string[];
|
|
49
|
+
protected streamKeys: string | string[];
|
|
50
|
+
protected nodes: Record<string, PregelNode>;
|
|
47
51
|
status: "pending" | "done" | "interrupt_before" | "interrupt_after" | "out_of_steps";
|
|
48
52
|
tasks: PregelExecutableTask<any, any>[];
|
|
49
53
|
stream: Deque<[StreamMode, any]>;
|
|
50
54
|
protected isNested: boolean;
|
|
51
55
|
protected _putCheckpointPromise: Promise<unknown>;
|
|
52
|
-
outputKeys: string | string[];
|
|
53
|
-
streamKeys: string | string[];
|
|
54
56
|
onBackgroundError: (e: Error) => void;
|
|
55
57
|
get backgroundTasksPromise(): Promise<unknown>;
|
|
56
58
|
constructor(params: PregelLoopParams);
|
|
@@ -73,6 +75,7 @@ export declare class PregelLoop {
|
|
|
73
75
|
* @param params
|
|
74
76
|
*/
|
|
75
77
|
tick(params: {
|
|
78
|
+
inputKeys?: string | string[];
|
|
76
79
|
interruptAfter: string[] | All;
|
|
77
80
|
interruptBefore: string[] | All;
|
|
78
81
|
manager?: CallbackManagerForChainRun;
|
|
@@ -82,7 +85,7 @@ export declare class PregelLoop {
|
|
|
82
85
|
* - finding a previous checkpoint
|
|
83
86
|
* - receiving None input (outer graph) or RESUMING flag (subgraph)
|
|
84
87
|
*/
|
|
85
|
-
protected _first(): Promise<void>;
|
|
88
|
+
protected _first(inputKeys: string | string[]): Promise<void>;
|
|
86
89
|
protected _putCheckpoint(inputMetadata: Omit<CheckpointMetadata, "step">): Promise<void>;
|
|
87
90
|
}
|
|
88
91
|
export {};
|
package/dist/pregel/loop.js
CHANGED
|
@@ -41,14 +41,6 @@ export class PregelLoop {
|
|
|
41
41
|
writable: true,
|
|
42
42
|
value: void 0
|
|
43
43
|
});
|
|
44
|
-
// TODO: Fix typing
|
|
45
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
|
-
Object.defineProperty(this, "graph", {
|
|
47
|
-
enumerable: true,
|
|
48
|
-
configurable: true,
|
|
49
|
-
writable: true,
|
|
50
|
-
value: void 0
|
|
51
|
-
});
|
|
52
44
|
Object.defineProperty(this, "channels", {
|
|
53
45
|
enumerable: true,
|
|
54
46
|
configurable: true,
|
|
@@ -97,6 +89,24 @@ export class PregelLoop {
|
|
|
97
89
|
writable: true,
|
|
98
90
|
value: void 0
|
|
99
91
|
});
|
|
92
|
+
Object.defineProperty(this, "outputKeys", {
|
|
93
|
+
enumerable: true,
|
|
94
|
+
configurable: true,
|
|
95
|
+
writable: true,
|
|
96
|
+
value: void 0
|
|
97
|
+
});
|
|
98
|
+
Object.defineProperty(this, "streamKeys", {
|
|
99
|
+
enumerable: true,
|
|
100
|
+
configurable: true,
|
|
101
|
+
writable: true,
|
|
102
|
+
value: void 0
|
|
103
|
+
});
|
|
104
|
+
Object.defineProperty(this, "nodes", {
|
|
105
|
+
enumerable: true,
|
|
106
|
+
configurable: true,
|
|
107
|
+
writable: true,
|
|
108
|
+
value: void 0
|
|
109
|
+
});
|
|
100
110
|
Object.defineProperty(this, "status", {
|
|
101
111
|
enumerable: true,
|
|
102
112
|
configurable: true,
|
|
@@ -129,18 +139,6 @@ export class PregelLoop {
|
|
|
129
139
|
writable: true,
|
|
130
140
|
value: Promise.resolve()
|
|
131
141
|
});
|
|
132
|
-
Object.defineProperty(this, "outputKeys", {
|
|
133
|
-
enumerable: true,
|
|
134
|
-
configurable: true,
|
|
135
|
-
writable: true,
|
|
136
|
-
value: void 0
|
|
137
|
-
});
|
|
138
|
-
Object.defineProperty(this, "streamKeys", {
|
|
139
|
-
enumerable: true,
|
|
140
|
-
configurable: true,
|
|
141
|
-
writable: true,
|
|
142
|
-
value: void 0
|
|
143
|
-
});
|
|
144
142
|
Object.defineProperty(this, "onBackgroundError", {
|
|
145
143
|
enumerable: true,
|
|
146
144
|
configurable: true,
|
|
@@ -158,7 +156,6 @@ export class PregelLoop {
|
|
|
158
156
|
else {
|
|
159
157
|
this.checkpointerGetNextVersion = increment;
|
|
160
158
|
}
|
|
161
|
-
this.graph = params.graph;
|
|
162
159
|
this.checkpoint = params.checkpoint;
|
|
163
160
|
this.checkpointConfig = params.checkpointConfig;
|
|
164
161
|
this.checkpointMetadata = params.checkpointMetadata;
|
|
@@ -170,6 +167,7 @@ export class PregelLoop {
|
|
|
170
167
|
this.isNested = CONFIG_KEY_READ in (this.config.configurable ?? {});
|
|
171
168
|
this.outputKeys = params.outputKeys;
|
|
172
169
|
this.streamKeys = params.streamKeys;
|
|
170
|
+
this.nodes = params.nodes;
|
|
173
171
|
this.onBackgroundError = params.onBackgroundError;
|
|
174
172
|
}
|
|
175
173
|
static async initialize(params) {
|
|
@@ -194,7 +192,7 @@ export class PregelLoop {
|
|
|
194
192
|
const checkpoint = copyCheckpoint(saved.checkpoint);
|
|
195
193
|
const checkpointMetadata = { ...saved.metadata };
|
|
196
194
|
const checkpointPendingWrites = saved.pendingWrites ?? [];
|
|
197
|
-
const channels = emptyChannels(params.
|
|
195
|
+
const channels = emptyChannels(params.channelSpecs, checkpoint);
|
|
198
196
|
const step = (checkpointMetadata.step ?? 0) + 1;
|
|
199
197
|
const stop = step + (params.config.recursionLimit ?? DEFAULT_LOOP_LIMIT) + 1;
|
|
200
198
|
const checkpointPreviousVersions = { ...checkpoint.channel_versions };
|
|
@@ -202,7 +200,6 @@ export class PregelLoop {
|
|
|
202
200
|
input: params.input,
|
|
203
201
|
config: params.config,
|
|
204
202
|
checkpointer: params.checkpointer,
|
|
205
|
-
graph: params.graph,
|
|
206
203
|
checkpoint,
|
|
207
204
|
checkpointMetadata,
|
|
208
205
|
checkpointConfig,
|
|
@@ -211,8 +208,9 @@ export class PregelLoop {
|
|
|
211
208
|
stop,
|
|
212
209
|
checkpointPreviousVersions,
|
|
213
210
|
checkpointPendingWrites,
|
|
214
|
-
outputKeys: params.outputKeys,
|
|
215
|
-
streamKeys: params.streamKeys,
|
|
211
|
+
outputKeys: params.outputKeys ?? [],
|
|
212
|
+
streamKeys: params.streamKeys ?? [],
|
|
213
|
+
nodes: params.nodes,
|
|
216
214
|
onBackgroundError: params.onBackgroundError,
|
|
217
215
|
});
|
|
218
216
|
}
|
|
@@ -261,12 +259,12 @@ export class PregelLoop {
|
|
|
261
259
|
* @param params
|
|
262
260
|
*/
|
|
263
261
|
async tick(params) {
|
|
264
|
-
const { interruptAfter = [], interruptBefore = [], manager } = params;
|
|
262
|
+
const { inputKeys = [], interruptAfter = [], interruptBefore = [], manager, } = params;
|
|
265
263
|
if (this.status !== "pending") {
|
|
266
264
|
throw new Error(`Cannot tick when status is no longer "pending". Current status: "${this.status}"`);
|
|
267
265
|
}
|
|
268
266
|
if (![INPUT_DONE, INPUT_RESUMING].includes(this.input)) {
|
|
269
|
-
await this._first();
|
|
267
|
+
await this._first(inputKeys);
|
|
270
268
|
}
|
|
271
269
|
else if (this.tasks.every((task) => task.writes.length > 0)) {
|
|
272
270
|
const writes = this.tasks.flatMap((t) => t.writes);
|
|
@@ -277,10 +275,9 @@ export class PregelLoop {
|
|
|
277
275
|
this.stream.push(...valuesOutput);
|
|
278
276
|
// clear pending writes
|
|
279
277
|
this.checkpointPendingWrites = [];
|
|
280
|
-
const metadataWrites = mapOutputUpdates(this.outputKeys, this.tasks).next().value;
|
|
281
278
|
await this._putCheckpoint({
|
|
282
279
|
source: "loop",
|
|
283
|
-
writes:
|
|
280
|
+
writes: mapOutputUpdates(this.outputKeys, this.tasks).next().value ?? null,
|
|
284
281
|
});
|
|
285
282
|
// after execution, check if we should interrupt
|
|
286
283
|
if (shouldInterrupt(this.checkpoint, interruptAfter, this.tasks)) {
|
|
@@ -300,7 +297,7 @@ export class PregelLoop {
|
|
|
300
297
|
this.status = "out_of_steps";
|
|
301
298
|
return false;
|
|
302
299
|
}
|
|
303
|
-
const nextTasks = _prepareNextTasks(this.checkpoint, this.
|
|
300
|
+
const nextTasks = _prepareNextTasks(this.checkpoint, this.nodes, this.channels, this.config, true, {
|
|
304
301
|
step: this.step,
|
|
305
302
|
checkpointer: this.checkpointer,
|
|
306
303
|
isResuming: this.input === INPUT_RESUMING,
|
|
@@ -310,7 +307,7 @@ export class PregelLoop {
|
|
|
310
307
|
// Produce debug output
|
|
311
308
|
if (this.checkpointer) {
|
|
312
309
|
this.stream.push(...(await gatherIterator(prefixGenerator(mapDebugCheckpoint(this.step - 1, // printing checkpoint for previous step
|
|
313
|
-
this.checkpointConfig, this.channels, this.
|
|
310
|
+
this.checkpointConfig, this.channels, this.streamKeys, this.checkpointMetadata, this.tasks, this.checkpointPendingWrites), "debug"))));
|
|
314
311
|
}
|
|
315
312
|
if (this.tasks.length === 0) {
|
|
316
313
|
this.status = "done";
|
|
@@ -331,6 +328,7 @@ export class PregelLoop {
|
|
|
331
328
|
// if all tasks have finished, re-tick
|
|
332
329
|
if (this.tasks.every((task) => task.writes.length > 0)) {
|
|
333
330
|
return this.tick({
|
|
331
|
+
inputKeys,
|
|
334
332
|
interruptAfter,
|
|
335
333
|
interruptBefore,
|
|
336
334
|
manager,
|
|
@@ -356,7 +354,7 @@ export class PregelLoop {
|
|
|
356
354
|
* - finding a previous checkpoint
|
|
357
355
|
* - receiving None input (outer graph) or RESUMING flag (subgraph)
|
|
358
356
|
*/
|
|
359
|
-
async _first() {
|
|
357
|
+
async _first(inputKeys) {
|
|
360
358
|
const isResuming = (Object.keys(this.checkpoint.channel_versions).length !== 0 &&
|
|
361
359
|
this.config.configurable?.[CONFIG_KEY_RESUMING] !== undefined) ||
|
|
362
360
|
this.input === null;
|
|
@@ -373,11 +371,11 @@ export class PregelLoop {
|
|
|
373
371
|
// map inputs to channel updates
|
|
374
372
|
}
|
|
375
373
|
else {
|
|
376
|
-
const inputWrites = await gatherIterator(mapInput(
|
|
374
|
+
const inputWrites = await gatherIterator(mapInput(inputKeys, this.input));
|
|
377
375
|
if (inputWrites.length === 0) {
|
|
378
|
-
throw new EmptyInputError(`Received no input writes for ${JSON.stringify(
|
|
376
|
+
throw new EmptyInputError(`Received no input writes for ${JSON.stringify(inputKeys, null, 2)}`);
|
|
379
377
|
}
|
|
380
|
-
const discardTasks = _prepareNextTasks(this.checkpoint, this.
|
|
378
|
+
const discardTasks = _prepareNextTasks(this.checkpoint, this.nodes, this.channels, this.config, true, { step: this.step });
|
|
381
379
|
_applyWrites(this.checkpoint, this.channels, discardTasks.concat([
|
|
382
380
|
{
|
|
383
381
|
name: INPUT,
|
package/dist/pregel/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Runnable, RunnableConfig } from "@langchain/core/runnables";
|
|
2
|
-
import type { PendingWrite, CheckpointMetadata, BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
2
|
+
import type { All, PendingWrite, CheckpointMetadata, BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
3
3
|
import type { BaseChannel } from "../channels/base.js";
|
|
4
4
|
import type { PregelNode } from "./read.js";
|
|
5
5
|
import { RetryPolicy } from "./utils.js";
|
|
@@ -93,5 +93,4 @@ export interface StateSnapshot {
|
|
|
93
93
|
*/
|
|
94
94
|
readonly tasks: PregelTaskDescription[];
|
|
95
95
|
}
|
|
96
|
-
export type All = "*";
|
|
97
96
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { All } from "@langchain/langgraph-checkpoint";
|
|
1
2
|
import { BaseChannel } from "../channels/index.js";
|
|
2
3
|
import { PregelNode } from "./read.js";
|
|
3
|
-
import { All } from "./types.js";
|
|
4
4
|
export declare class GraphValidationError extends Error {
|
|
5
5
|
constructor(message?: string);
|
|
6
6
|
}
|