@langchain/langgraph 0.2.27 → 0.2.28
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/constants.cjs +33 -2
- package/dist/constants.d.ts +13 -4
- package/dist/constants.js +32 -1
- package/dist/errors.cjs +23 -1
- package/dist/errors.d.ts +7 -1
- package/dist/errors.js +20 -0
- package/dist/graph/graph.cjs +34 -8
- package/dist/graph/graph.d.ts +6 -5
- package/dist/graph/graph.js +35 -9
- package/dist/graph/state.cjs +76 -16
- package/dist/graph/state.d.ts +3 -1
- package/dist/graph/state.js +79 -19
- package/dist/prebuilt/tool_node.cjs +7 -0
- package/dist/prebuilt/tool_node.js +7 -0
- package/dist/pregel/algo.cjs +32 -1
- package/dist/pregel/algo.d.ts +3 -2
- package/dist/pregel/algo.js +32 -1
- package/dist/pregel/index.cjs +13 -2
- package/dist/pregel/index.js +14 -3
- package/dist/pregel/io.cjs +35 -0
- package/dist/pregel/io.d.ts +3 -0
- package/dist/pregel/io.js +37 -2
- package/dist/pregel/loop.cjs +17 -16
- package/dist/pregel/loop.js +17 -16
- package/dist/pregel/retry.cjs +23 -0
- package/dist/pregel/retry.js +24 -1
- package/dist/pregel/types.d.ts +1 -0
- package/dist/pregel/write.cjs +27 -24
- package/dist/pregel/write.d.ts +1 -2
- package/dist/pregel/write.js +27 -24
- package/dist/web.d.ts +1 -1
- package/dist/web.js +1 -1
- package/package.json +1 -1
package/dist/constants.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports._isCommand = exports.Command = exports._isSend = exports.Send = exports._isSendInterface = exports.CHECKPOINT_NAMESPACE_END = exports.CHECKPOINT_NAMESPACE_SEPARATOR = exports.RESERVED = exports.NULL_TASK_ID = exports.TASK_NAMESPACE = exports.PULL = exports.PUSH = exports.TASKS = exports.TAG_NOSTREAM = exports.TAG_HIDDEN = exports.RECURSION_LIMIT_DEFAULT = exports.RUNTIME_PLACEHOLDER = exports.RESUME = exports.INTERRUPT = exports.CONFIG_KEY_CHECKPOINT_MAP = exports.CONFIG_KEY_RESUME_VALUE = exports.CONFIG_KEY_STREAM = exports.CONFIG_KEY_TASK_ID = exports.CONFIG_KEY_RESUMING = exports.CONFIG_KEY_CHECKPOINTER = exports.CONFIG_KEY_READ = exports.CONFIG_KEY_SEND = exports.ERROR = exports.INPUT = exports.MISSING = void 0;
|
|
3
|
+
exports._isCommand = exports.Command = exports._isSend = exports.Send = exports._isSendInterface = exports.CHECKPOINT_NAMESPACE_END = exports.CHECKPOINT_NAMESPACE_SEPARATOR = exports.RESERVED = exports.NULL_TASK_ID = exports.TASK_NAMESPACE = exports.PULL = exports.PUSH = exports.TASKS = exports.SELF = exports.TAG_NOSTREAM = exports.TAG_HIDDEN = exports.RECURSION_LIMIT_DEFAULT = exports.RUNTIME_PLACEHOLDER = exports.RESUME = exports.INTERRUPT = exports.CONFIG_KEY_CHECKPOINT_MAP = exports.CONFIG_KEY_RESUME_VALUE = exports.CONFIG_KEY_STREAM = exports.CONFIG_KEY_TASK_ID = exports.CONFIG_KEY_RESUMING = exports.CONFIG_KEY_CHECKPOINTER = exports.CONFIG_KEY_READ = exports.CONFIG_KEY_SEND = exports.ERROR = exports.INPUT = exports.MISSING = void 0;
|
|
4
4
|
exports.MISSING = Symbol.for("__missing__");
|
|
5
5
|
exports.INPUT = "__input__";
|
|
6
6
|
exports.ERROR = "__error__";
|
|
@@ -19,6 +19,7 @@ exports.RUNTIME_PLACEHOLDER = "__pregel_runtime_placeholder__";
|
|
|
19
19
|
exports.RECURSION_LIMIT_DEFAULT = 25;
|
|
20
20
|
exports.TAG_HIDDEN = "langsmith:hidden";
|
|
21
21
|
exports.TAG_NOSTREAM = "langsmith:nostream";
|
|
22
|
+
exports.SELF = "__self__";
|
|
22
23
|
exports.TASKS = "__pregel_tasks";
|
|
23
24
|
exports.PUSH = "__pregel_push";
|
|
24
25
|
exports.PULL = "__pregel_pull";
|
|
@@ -117,7 +118,7 @@ class Send {
|
|
|
117
118
|
exports.Send = Send;
|
|
118
119
|
function _isSend(x) {
|
|
119
120
|
const operation = x;
|
|
120
|
-
return operation.lg_name === "Send";
|
|
121
|
+
return operation !== undefined && operation.lg_name === "Send";
|
|
121
122
|
}
|
|
122
123
|
exports._isSend = _isSend;
|
|
123
124
|
class Command {
|
|
@@ -134,10 +135,40 @@ class Command {
|
|
|
134
135
|
writable: true,
|
|
135
136
|
value: void 0
|
|
136
137
|
});
|
|
138
|
+
Object.defineProperty(this, "graph", {
|
|
139
|
+
enumerable: true,
|
|
140
|
+
configurable: true,
|
|
141
|
+
writable: true,
|
|
142
|
+
value: void 0
|
|
143
|
+
});
|
|
144
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
145
|
+
Object.defineProperty(this, "update", {
|
|
146
|
+
enumerable: true,
|
|
147
|
+
configurable: true,
|
|
148
|
+
writable: true,
|
|
149
|
+
value: void 0
|
|
150
|
+
});
|
|
151
|
+
Object.defineProperty(this, "goto", {
|
|
152
|
+
enumerable: true,
|
|
153
|
+
configurable: true,
|
|
154
|
+
writable: true,
|
|
155
|
+
value: []
|
|
156
|
+
});
|
|
137
157
|
this.resume = args.resume;
|
|
158
|
+
this.graph = args.graph;
|
|
159
|
+
this.update = args.update;
|
|
160
|
+
if (args.goto) {
|
|
161
|
+
this.goto = Array.isArray(args.goto) ? args.goto : [args.goto];
|
|
162
|
+
}
|
|
138
163
|
}
|
|
139
164
|
}
|
|
140
165
|
exports.Command = Command;
|
|
166
|
+
Object.defineProperty(Command, "PARENT", {
|
|
167
|
+
enumerable: true,
|
|
168
|
+
configurable: true,
|
|
169
|
+
writable: true,
|
|
170
|
+
value: "__parent__"
|
|
171
|
+
});
|
|
141
172
|
function _isCommand(x) {
|
|
142
173
|
return typeof x === "object" && !!x && x.lg_name === "Command";
|
|
143
174
|
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export declare const RUNTIME_PLACEHOLDER = "__pregel_runtime_placeholder__";
|
|
|
15
15
|
export declare const RECURSION_LIMIT_DEFAULT = 25;
|
|
16
16
|
export declare const TAG_HIDDEN = "langsmith:hidden";
|
|
17
17
|
export declare const TAG_NOSTREAM = "langsmith:nostream";
|
|
18
|
+
export declare const SELF = "__self__";
|
|
18
19
|
export declare const TASKS = "__pregel_tasks";
|
|
19
20
|
export declare const PUSH = "__pregel_push";
|
|
20
21
|
export declare const PULL = "__pregel_pull";
|
|
@@ -87,11 +88,19 @@ export type Interrupt = {
|
|
|
87
88
|
resumable?: boolean;
|
|
88
89
|
ns?: string[];
|
|
89
90
|
};
|
|
91
|
+
export type CommandParams<R> = {
|
|
92
|
+
resume?: R;
|
|
93
|
+
graph?: string;
|
|
94
|
+
update?: Record<string, any>;
|
|
95
|
+
goto?: string | Send | (string | Send)[];
|
|
96
|
+
};
|
|
90
97
|
export declare class Command<R = unknown> {
|
|
91
98
|
lg_name: string;
|
|
92
|
-
resume
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
resume?: R;
|
|
100
|
+
graph?: string;
|
|
101
|
+
update?: Record<string, any>;
|
|
102
|
+
goto: string | Send | (string | Send)[];
|
|
103
|
+
static PARENT: string;
|
|
104
|
+
constructor(args: CommandParams<R>);
|
|
96
105
|
}
|
|
97
106
|
export declare function _isCommand(x: unknown): x is Command;
|
package/dist/constants.js
CHANGED
|
@@ -16,6 +16,7 @@ export const RUNTIME_PLACEHOLDER = "__pregel_runtime_placeholder__";
|
|
|
16
16
|
export const RECURSION_LIMIT_DEFAULT = 25;
|
|
17
17
|
export const TAG_HIDDEN = "langsmith:hidden";
|
|
18
18
|
export const TAG_NOSTREAM = "langsmith:nostream";
|
|
19
|
+
export const SELF = "__self__";
|
|
19
20
|
export const TASKS = "__pregel_tasks";
|
|
20
21
|
export const PUSH = "__pregel_push";
|
|
21
22
|
export const PULL = "__pregel_pull";
|
|
@@ -112,7 +113,7 @@ export class Send {
|
|
|
112
113
|
}
|
|
113
114
|
export function _isSend(x) {
|
|
114
115
|
const operation = x;
|
|
115
|
-
return operation.lg_name === "Send";
|
|
116
|
+
return operation !== undefined && operation.lg_name === "Send";
|
|
116
117
|
}
|
|
117
118
|
export class Command {
|
|
118
119
|
constructor(args) {
|
|
@@ -128,9 +129,39 @@ export class Command {
|
|
|
128
129
|
writable: true,
|
|
129
130
|
value: void 0
|
|
130
131
|
});
|
|
132
|
+
Object.defineProperty(this, "graph", {
|
|
133
|
+
enumerable: true,
|
|
134
|
+
configurable: true,
|
|
135
|
+
writable: true,
|
|
136
|
+
value: void 0
|
|
137
|
+
});
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
139
|
+
Object.defineProperty(this, "update", {
|
|
140
|
+
enumerable: true,
|
|
141
|
+
configurable: true,
|
|
142
|
+
writable: true,
|
|
143
|
+
value: void 0
|
|
144
|
+
});
|
|
145
|
+
Object.defineProperty(this, "goto", {
|
|
146
|
+
enumerable: true,
|
|
147
|
+
configurable: true,
|
|
148
|
+
writable: true,
|
|
149
|
+
value: []
|
|
150
|
+
});
|
|
131
151
|
this.resume = args.resume;
|
|
152
|
+
this.graph = args.graph;
|
|
153
|
+
this.update = args.update;
|
|
154
|
+
if (args.goto) {
|
|
155
|
+
this.goto = Array.isArray(args.goto) ? args.goto : [args.goto];
|
|
156
|
+
}
|
|
132
157
|
}
|
|
133
158
|
}
|
|
159
|
+
Object.defineProperty(Command, "PARENT", {
|
|
160
|
+
enumerable: true,
|
|
161
|
+
configurable: true,
|
|
162
|
+
writable: true,
|
|
163
|
+
value: "__parent__"
|
|
164
|
+
});
|
|
134
165
|
export function _isCommand(x) {
|
|
135
166
|
return typeof x === "object" && !!x && x.lg_name === "Command";
|
|
136
167
|
}
|
package/dist/errors.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getSubgraphsSeenSet = exports.RemoteException = exports.MultipleSubgraphsError = exports.InvalidUpdateError = exports.EmptyChannelError = exports.EmptyInputError = exports.isGraphInterrupt = exports.isGraphBubbleUp = exports.NodeInterrupt = exports.GraphInterrupt = exports.GraphValueError = exports.GraphRecursionError = exports.GraphBubbleUp = exports.BaseLangGraphError = void 0;
|
|
3
|
+
exports.getSubgraphsSeenSet = exports.RemoteException = exports.MultipleSubgraphsError = exports.InvalidUpdateError = exports.EmptyChannelError = exports.EmptyInputError = exports.isGraphInterrupt = exports.isGraphBubbleUp = exports.isParentCommand = exports.ParentCommand = exports.NodeInterrupt = exports.GraphInterrupt = exports.GraphValueError = exports.GraphRecursionError = exports.GraphBubbleUp = exports.BaseLangGraphError = void 0;
|
|
4
4
|
// TODO: Merge with base LangChain error class when we drop support for core@0.2.0
|
|
5
5
|
class BaseLangGraphError extends Error {
|
|
6
6
|
constructor(message, fields) {
|
|
@@ -79,6 +79,28 @@ class NodeInterrupt extends GraphInterrupt {
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
exports.NodeInterrupt = NodeInterrupt;
|
|
82
|
+
class ParentCommand extends GraphBubbleUp {
|
|
83
|
+
constructor(command) {
|
|
84
|
+
super();
|
|
85
|
+
Object.defineProperty(this, "command", {
|
|
86
|
+
enumerable: true,
|
|
87
|
+
configurable: true,
|
|
88
|
+
writable: true,
|
|
89
|
+
value: void 0
|
|
90
|
+
});
|
|
91
|
+
this.name = "ParentCommand";
|
|
92
|
+
this.command = command;
|
|
93
|
+
}
|
|
94
|
+
static get unminifiable_name() {
|
|
95
|
+
return "ParentCommand";
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
exports.ParentCommand = ParentCommand;
|
|
99
|
+
function isParentCommand(e) {
|
|
100
|
+
return (e !== undefined &&
|
|
101
|
+
e.name === ParentCommand.unminifiable_name);
|
|
102
|
+
}
|
|
103
|
+
exports.isParentCommand = isParentCommand;
|
|
82
104
|
function isGraphBubbleUp(e) {
|
|
83
105
|
return e !== undefined && e.is_bubble_up === true;
|
|
84
106
|
}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Interrupt } from "./constants.js";
|
|
1
|
+
import { Command, Interrupt } from "./constants.js";
|
|
2
2
|
export type BaseLangGraphErrorFields = {
|
|
3
3
|
lc_error_code?: string;
|
|
4
4
|
};
|
|
@@ -27,6 +27,12 @@ export declare class NodeInterrupt extends GraphInterrupt {
|
|
|
27
27
|
constructor(message: any, fields?: BaseLangGraphErrorFields);
|
|
28
28
|
static get unminifiable_name(): string;
|
|
29
29
|
}
|
|
30
|
+
export declare class ParentCommand extends GraphBubbleUp {
|
|
31
|
+
command: Command;
|
|
32
|
+
constructor(command: Command);
|
|
33
|
+
static get unminifiable_name(): string;
|
|
34
|
+
}
|
|
35
|
+
export declare function isParentCommand(e?: Error): e is ParentCommand;
|
|
30
36
|
export declare function isGraphBubbleUp(e?: Error): e is GraphBubbleUp;
|
|
31
37
|
export declare function isGraphInterrupt(e?: GraphInterrupt | Error): e is GraphInterrupt;
|
|
32
38
|
export declare class EmptyInputError extends BaseLangGraphError {
|
package/dist/errors.js
CHANGED
|
@@ -70,6 +70,26 @@ export class NodeInterrupt extends GraphInterrupt {
|
|
|
70
70
|
return "NodeInterrupt";
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
+
export class ParentCommand extends GraphBubbleUp {
|
|
74
|
+
constructor(command) {
|
|
75
|
+
super();
|
|
76
|
+
Object.defineProperty(this, "command", {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
configurable: true,
|
|
79
|
+
writable: true,
|
|
80
|
+
value: void 0
|
|
81
|
+
});
|
|
82
|
+
this.name = "ParentCommand";
|
|
83
|
+
this.command = command;
|
|
84
|
+
}
|
|
85
|
+
static get unminifiable_name() {
|
|
86
|
+
return "ParentCommand";
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export function isParentCommand(e) {
|
|
90
|
+
return (e !== undefined &&
|
|
91
|
+
e.name === ParentCommand.unminifiable_name);
|
|
92
|
+
}
|
|
73
93
|
export function isGraphBubbleUp(e) {
|
|
74
94
|
return e !== undefined && e.is_bubble_up === true;
|
|
75
95
|
}
|
package/dist/graph/graph.cjs
CHANGED
|
@@ -32,7 +32,14 @@ class Branch {
|
|
|
32
32
|
writable: true,
|
|
33
33
|
value: void 0
|
|
34
34
|
});
|
|
35
|
-
|
|
35
|
+
if (runnables_1.Runnable.isRunnable(options.path)) {
|
|
36
|
+
this.condition = options.path;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.condition = (0, runnables_1._coerceToRunnable)(options.path).withConfig({
|
|
40
|
+
runName: `Branch`,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
36
43
|
this.ends = Array.isArray(options.pathMap)
|
|
37
44
|
? options.pathMap.reduce((acc, n) => {
|
|
38
45
|
acc[n] = n;
|
|
@@ -40,7 +47,7 @@ class Branch {
|
|
|
40
47
|
}, {})
|
|
41
48
|
: options.pathMap;
|
|
42
49
|
}
|
|
43
|
-
|
|
50
|
+
run(writer, reader) {
|
|
44
51
|
return write_js_1.ChannelWrite.registerWriter(new utils_js_1.RunnableCallable({
|
|
45
52
|
trace: false,
|
|
46
53
|
func: async (input, config) => {
|
|
@@ -59,8 +66,10 @@ class Branch {
|
|
|
59
66
|
},
|
|
60
67
|
}));
|
|
61
68
|
}
|
|
62
|
-
async _route(input, config, writer, reader
|
|
63
|
-
|
|
69
|
+
async _route(input, config, writer, reader
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
71
|
+
) {
|
|
72
|
+
let result = await this.condition.invoke(reader ? reader(config) : input, config);
|
|
64
73
|
if (!Array.isArray(result)) {
|
|
65
74
|
result = [result];
|
|
66
75
|
}
|
|
@@ -77,7 +86,8 @@ class Branch {
|
|
|
77
86
|
if (destinations.filter(constants_js_1._isSend).some((packet) => packet.node === exports.END)) {
|
|
78
87
|
throw new errors_js_1.InvalidUpdateError("Cannot send a packet to the END node");
|
|
79
88
|
}
|
|
80
|
-
|
|
89
|
+
const writeResult = await writer(destinations, config);
|
|
90
|
+
return writeResult ?? input;
|
|
81
91
|
}
|
|
82
92
|
}
|
|
83
93
|
exports.Branch = Branch;
|
|
@@ -168,10 +178,26 @@ class Graph {
|
|
|
168
178
|
return this;
|
|
169
179
|
}
|
|
170
180
|
addConditionalEdges(source, path, pathMap) {
|
|
171
|
-
const options = typeof source === "object"
|
|
181
|
+
const options = typeof source === "object"
|
|
182
|
+
? source
|
|
183
|
+
: {
|
|
184
|
+
source,
|
|
185
|
+
path: path,
|
|
186
|
+
pathMap,
|
|
187
|
+
};
|
|
172
188
|
this.warnIfCompiled("Adding an edge to a graph that has already been compiled. This will not be reflected in the compiled graph.");
|
|
189
|
+
if (!runnables_1.Runnable.isRunnable(options.path)) {
|
|
190
|
+
const pathDisplayValues = Array.isArray(options.pathMap)
|
|
191
|
+
? options.pathMap.join(",")
|
|
192
|
+
: Object.keys(options.pathMap ?? {}).join(",");
|
|
193
|
+
options.path = (0, runnables_1._coerceToRunnable)(options.path).withConfig({
|
|
194
|
+
runName: `Branch<${options.source}${pathDisplayValues !== "" ? `,${pathDisplayValues}` : ""}>`.slice(0, 63),
|
|
195
|
+
});
|
|
196
|
+
}
|
|
173
197
|
// find a name for condition
|
|
174
|
-
const name = options.path.
|
|
198
|
+
const name = options.path.getName() === "RunnableLambda"
|
|
199
|
+
? "condition"
|
|
200
|
+
: options.path.getName();
|
|
175
201
|
// validate condition
|
|
176
202
|
if (this.branches[options.source] && this.branches[options.source][name]) {
|
|
177
203
|
throw new Error(`Condition \`${name}\` already present for node \`${source}\``);
|
|
@@ -328,7 +354,7 @@ class CompiledGraph extends index_js_1.Pregel {
|
|
|
328
354
|
this.nodes[exports.START] = index_js_1.Channel.subscribeTo(exports.START, { tags: [constants_js_1.TAG_HIDDEN] });
|
|
329
355
|
}
|
|
330
356
|
// attach branch writer
|
|
331
|
-
this.nodes[start].pipe(branch.
|
|
357
|
+
this.nodes[start].pipe(branch.run((dests) => {
|
|
332
358
|
const writes = dests.map((dest) => {
|
|
333
359
|
if ((0, constants_js_1._isSend)(dest)) {
|
|
334
360
|
return dest;
|
package/dist/graph/graph.d.ts
CHANGED
|
@@ -15,15 +15,16 @@ export declare const START = "__start__";
|
|
|
15
15
|
export declare const END = "__end__";
|
|
16
16
|
export interface BranchOptions<IO, N extends string, CallOptions extends LangGraphRunnableConfig = LangGraphRunnableConfig> {
|
|
17
17
|
source: N;
|
|
18
|
-
path:
|
|
18
|
+
path: RunnableLike<IO, BranchPathReturnValue, CallOptions>;
|
|
19
19
|
pathMap?: Record<string, N | typeof END> | (N | typeof END)[];
|
|
20
20
|
}
|
|
21
|
+
export type BranchPathReturnValue = string | Send | (string | Send)[] | Promise<string | Send | (string | Send)[]>;
|
|
21
22
|
export declare class Branch<IO, N extends string, CallOptions extends LangGraphRunnableConfig = LangGraphRunnableConfig> {
|
|
22
|
-
condition:
|
|
23
|
+
condition: Runnable<IO, BranchPathReturnValue, CallOptions>;
|
|
23
24
|
ends?: Record<string, N | typeof END>;
|
|
24
25
|
constructor(options: Omit<BranchOptions<IO, N, CallOptions>, "source">);
|
|
25
|
-
|
|
26
|
-
_route(input: IO, config: CallOptions, writer: (dests: (string | Send)[]) => Runnable |
|
|
26
|
+
run(writer: (dests: (string | Send)[], config: LangGraphRunnableConfig) => Runnable | void | Promise<void>, reader?: (config: CallOptions) => IO): RunnableCallable<unknown, unknown>;
|
|
27
|
+
_route(input: IO, config: CallOptions, writer: (dests: (string | Send)[], config: LangGraphRunnableConfig) => Runnable | void | Promise<void>, reader?: (config: CallOptions) => IO): Promise<Runnable | any>;
|
|
27
28
|
}
|
|
28
29
|
export type NodeSpec<RunInput, RunOutput> = {
|
|
29
30
|
runnable: Runnable<RunInput, RunOutput>;
|
|
@@ -46,7 +47,7 @@ export declare class Graph<N extends string = typeof END, RunInput = any, RunOut
|
|
|
46
47
|
addNode<K extends string, NodeInput = RunInput>(key: K, action: RunnableLike<NodeInput, RunOutput extends object ? RunOutput & Record<string, any> : RunOutput, LangGraphRunnableConfig<StateType<C>>>, options?: AddNodeOptions): Graph<N | K, RunInput, RunOutput>;
|
|
47
48
|
addEdge(startKey: N | typeof START, endKey: N | typeof END): this;
|
|
48
49
|
addConditionalEdges(source: BranchOptions<RunInput, N, LangGraphRunnableConfig<StateType<C>>>): this;
|
|
49
|
-
addConditionalEdges(source: N, path:
|
|
50
|
+
addConditionalEdges(source: N, path: RunnableLike<RunInput, BranchPathReturnValue, LangGraphRunnableConfig<StateType<C>>>, pathMap?: BranchOptions<RunInput, N, LangGraphRunnableConfig<StateType<C>>>["pathMap"]): this;
|
|
50
51
|
/**
|
|
51
52
|
* @deprecated use `addEdge(START, key)` instead
|
|
52
53
|
*/
|
package/dist/graph/graph.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
2
|
-
import { _coerceToRunnable, } from "@langchain/core/runnables";
|
|
2
|
+
import { _coerceToRunnable, Runnable, } from "@langchain/core/runnables";
|
|
3
3
|
import { Graph as DrawableGraph, } from "@langchain/core/runnables/graph";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { validate as isUuid } from "uuid";
|
|
@@ -29,7 +29,14 @@ export class Branch {
|
|
|
29
29
|
writable: true,
|
|
30
30
|
value: void 0
|
|
31
31
|
});
|
|
32
|
-
|
|
32
|
+
if (Runnable.isRunnable(options.path)) {
|
|
33
|
+
this.condition = options.path;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
this.condition = _coerceToRunnable(options.path).withConfig({
|
|
37
|
+
runName: `Branch`,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
33
40
|
this.ends = Array.isArray(options.pathMap)
|
|
34
41
|
? options.pathMap.reduce((acc, n) => {
|
|
35
42
|
acc[n] = n;
|
|
@@ -37,7 +44,7 @@ export class Branch {
|
|
|
37
44
|
}, {})
|
|
38
45
|
: options.pathMap;
|
|
39
46
|
}
|
|
40
|
-
|
|
47
|
+
run(writer, reader) {
|
|
41
48
|
return ChannelWrite.registerWriter(new RunnableCallable({
|
|
42
49
|
trace: false,
|
|
43
50
|
func: async (input, config) => {
|
|
@@ -56,8 +63,10 @@ export class Branch {
|
|
|
56
63
|
},
|
|
57
64
|
}));
|
|
58
65
|
}
|
|
59
|
-
async _route(input, config, writer, reader
|
|
60
|
-
|
|
66
|
+
async _route(input, config, writer, reader
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
+
) {
|
|
69
|
+
let result = await this.condition.invoke(reader ? reader(config) : input, config);
|
|
61
70
|
if (!Array.isArray(result)) {
|
|
62
71
|
result = [result];
|
|
63
72
|
}
|
|
@@ -74,7 +83,8 @@ export class Branch {
|
|
|
74
83
|
if (destinations.filter(_isSend).some((packet) => packet.node === END)) {
|
|
75
84
|
throw new InvalidUpdateError("Cannot send a packet to the END node");
|
|
76
85
|
}
|
|
77
|
-
|
|
86
|
+
const writeResult = await writer(destinations, config);
|
|
87
|
+
return writeResult ?? input;
|
|
78
88
|
}
|
|
79
89
|
}
|
|
80
90
|
export class Graph {
|
|
@@ -164,10 +174,26 @@ export class Graph {
|
|
|
164
174
|
return this;
|
|
165
175
|
}
|
|
166
176
|
addConditionalEdges(source, path, pathMap) {
|
|
167
|
-
const options = typeof source === "object"
|
|
177
|
+
const options = typeof source === "object"
|
|
178
|
+
? source
|
|
179
|
+
: {
|
|
180
|
+
source,
|
|
181
|
+
path: path,
|
|
182
|
+
pathMap,
|
|
183
|
+
};
|
|
168
184
|
this.warnIfCompiled("Adding an edge to a graph that has already been compiled. This will not be reflected in the compiled graph.");
|
|
185
|
+
if (!Runnable.isRunnable(options.path)) {
|
|
186
|
+
const pathDisplayValues = Array.isArray(options.pathMap)
|
|
187
|
+
? options.pathMap.join(",")
|
|
188
|
+
: Object.keys(options.pathMap ?? {}).join(",");
|
|
189
|
+
options.path = _coerceToRunnable(options.path).withConfig({
|
|
190
|
+
runName: `Branch<${options.source}${pathDisplayValues !== "" ? `,${pathDisplayValues}` : ""}>`.slice(0, 63),
|
|
191
|
+
});
|
|
192
|
+
}
|
|
169
193
|
// find a name for condition
|
|
170
|
-
const name = options.path.
|
|
194
|
+
const name = options.path.getName() === "RunnableLambda"
|
|
195
|
+
? "condition"
|
|
196
|
+
: options.path.getName();
|
|
171
197
|
// validate condition
|
|
172
198
|
if (this.branches[options.source] && this.branches[options.source][name]) {
|
|
173
199
|
throw new Error(`Condition \`${name}\` already present for node \`${source}\``);
|
|
@@ -323,7 +349,7 @@ export class CompiledGraph extends Pregel {
|
|
|
323
349
|
this.nodes[START] = Channel.subscribeTo(START, { tags: [TAG_HIDDEN] });
|
|
324
350
|
}
|
|
325
351
|
// attach branch writer
|
|
326
|
-
this.nodes[start].pipe(branch.
|
|
352
|
+
this.nodes[start].pipe(branch.run((dests) => {
|
|
327
353
|
const writes = dests.map((dest) => {
|
|
328
354
|
if (_isSend(dest)) {
|
|
329
355
|
return dest;
|
package/dist/graph/state.cjs
CHANGED
|
@@ -303,6 +303,14 @@ class StateGraph extends graph_js_1.Graph {
|
|
|
303
303
|
for (const [key, node] of Object.entries(this.nodes)) {
|
|
304
304
|
compiled.attachNode(key, node);
|
|
305
305
|
}
|
|
306
|
+
compiled.attachBranch(graph_js_1.START, constants_js_1.SELF, _getControlBranch(), {
|
|
307
|
+
withReader: false,
|
|
308
|
+
});
|
|
309
|
+
for (const [key] of Object.entries(this.nodes)) {
|
|
310
|
+
compiled.attachBranch(key, constants_js_1.SELF, _getControlBranch(), {
|
|
311
|
+
withReader: false,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
306
314
|
for (const [start, end] of this.edges) {
|
|
307
315
|
compiled.attachEdge(start, end);
|
|
308
316
|
}
|
|
@@ -339,13 +347,30 @@ function _getChannels(schema) {
|
|
|
339
347
|
class CompiledStateGraph extends graph_js_1.CompiledGraph {
|
|
340
348
|
attachNode(key, node) {
|
|
341
349
|
const stateKeys = Object.keys(this.builder.channels);
|
|
350
|
+
function _getRoot(input) {
|
|
351
|
+
if ((0, constants_js_1._isCommand)(input)) {
|
|
352
|
+
if (input.graph === constants_js_1.Command.PARENT) {
|
|
353
|
+
return write_js_1.SKIP_WRITE;
|
|
354
|
+
}
|
|
355
|
+
return input.update;
|
|
356
|
+
}
|
|
357
|
+
return input;
|
|
358
|
+
}
|
|
359
|
+
// to avoid name collision below
|
|
360
|
+
const nodeKey = key;
|
|
342
361
|
function getStateKey(key, input) {
|
|
343
362
|
if (!input) {
|
|
344
363
|
return write_js_1.SKIP_WRITE;
|
|
345
364
|
}
|
|
365
|
+
else if ((0, constants_js_1._isCommand)(input)) {
|
|
366
|
+
if (input.graph === constants_js_1.Command.PARENT) {
|
|
367
|
+
return write_js_1.SKIP_WRITE;
|
|
368
|
+
}
|
|
369
|
+
return getStateKey(key, input.update);
|
|
370
|
+
}
|
|
346
371
|
else if (typeof input !== "object" || Array.isArray(input)) {
|
|
347
372
|
const typeofInput = Array.isArray(input) ? "array" : typeof input;
|
|
348
|
-
throw new errors_js_1.InvalidUpdateError(`Expected node "${
|
|
373
|
+
throw new errors_js_1.InvalidUpdateError(`Expected node "${nodeKey.toString()}" to return an object, received ${typeofInput}`, {
|
|
349
374
|
lc_error_code: "INVALID_GRAPH_NODE_RETURN_VALUE",
|
|
350
375
|
});
|
|
351
376
|
}
|
|
@@ -355,7 +380,16 @@ class CompiledStateGraph extends graph_js_1.CompiledGraph {
|
|
|
355
380
|
}
|
|
356
381
|
// state updaters
|
|
357
382
|
const stateWriteEntries = stateKeys.map((key) => key === ROOT
|
|
358
|
-
? {
|
|
383
|
+
? {
|
|
384
|
+
channel: key,
|
|
385
|
+
value: write_js_1.PASSTHROUGH,
|
|
386
|
+
skipNone: true,
|
|
387
|
+
mapper: new utils_js_1.RunnableCallable({
|
|
388
|
+
func: _getRoot,
|
|
389
|
+
trace: false,
|
|
390
|
+
recurse: false,
|
|
391
|
+
}),
|
|
392
|
+
}
|
|
359
393
|
: {
|
|
360
394
|
channel: key,
|
|
361
395
|
value: write_js_1.PASSTHROUGH,
|
|
@@ -430,28 +464,29 @@ class CompiledStateGraph extends graph_js_1.CompiledGraph {
|
|
|
430
464
|
this.nodes[end].triggers.push(start);
|
|
431
465
|
}
|
|
432
466
|
}
|
|
433
|
-
attachBranch(start, name, branch) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
(dests) => {
|
|
438
|
-
const filteredDests = dests.filter((dest) => dest !== graph_js_1.END);
|
|
439
|
-
if (!filteredDests.length) {
|
|
467
|
+
attachBranch(start, name, branch, options = { withReader: true }) {
|
|
468
|
+
const branchWriter = async (packets, config) => {
|
|
469
|
+
const filteredPackets = packets.filter((p) => p !== graph_js_1.END);
|
|
470
|
+
if (!filteredPackets.length) {
|
|
440
471
|
return;
|
|
441
472
|
}
|
|
442
|
-
const writes =
|
|
443
|
-
if ((0, constants_js_1._isSend)(
|
|
444
|
-
return
|
|
473
|
+
const writes = filteredPackets.map((p) => {
|
|
474
|
+
if ((0, constants_js_1._isSend)(p)) {
|
|
475
|
+
return p;
|
|
445
476
|
}
|
|
446
477
|
return {
|
|
447
|
-
channel: `branch:${start}:${name}:${
|
|
478
|
+
channel: `branch:${start}:${name}:${p}`,
|
|
448
479
|
value: start,
|
|
449
480
|
};
|
|
450
481
|
});
|
|
451
|
-
|
|
452
|
-
}
|
|
482
|
+
await write_js_1.ChannelWrite.doWrite({ ...config, tags: (config.tags ?? []).concat([constants_js_1.TAG_HIDDEN]) }, writes);
|
|
483
|
+
};
|
|
484
|
+
// attach branch publisher
|
|
485
|
+
this.nodes[start].writers.push(branch.run(branchWriter,
|
|
453
486
|
// reader
|
|
454
|
-
|
|
487
|
+
options.withReader
|
|
488
|
+
? (config) => read_js_1.ChannelRead.doRead(config, this.streamChannels ?? this.outputChannels, true)
|
|
489
|
+
: undefined));
|
|
455
490
|
// attach branch subscribers
|
|
456
491
|
const ends = branch.ends
|
|
457
492
|
? Object.values(branch.ends)
|
|
@@ -499,3 +534,28 @@ function isStateGraphArgsWithInputOutputSchemas(obj) {
|
|
|
499
534
|
obj.input !== undefined &&
|
|
500
535
|
obj.output !== undefined);
|
|
501
536
|
}
|
|
537
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
538
|
+
function _controlBranch(value) {
|
|
539
|
+
if ((0, constants_js_1._isSend)(value)) {
|
|
540
|
+
return [value];
|
|
541
|
+
}
|
|
542
|
+
if (!(0, constants_js_1._isCommand)(value)) {
|
|
543
|
+
return [];
|
|
544
|
+
}
|
|
545
|
+
if (value.graph === constants_js_1.Command.PARENT) {
|
|
546
|
+
throw new errors_js_1.ParentCommand(value);
|
|
547
|
+
}
|
|
548
|
+
return Array.isArray(value.goto) ? value.goto : [value.goto];
|
|
549
|
+
}
|
|
550
|
+
function _getControlBranch() {
|
|
551
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
552
|
+
const CONTROL_BRANCH_PATH = new utils_js_1.RunnableCallable({
|
|
553
|
+
func: _controlBranch,
|
|
554
|
+
tags: [constants_js_1.TAG_HIDDEN],
|
|
555
|
+
trace: false,
|
|
556
|
+
recurse: false,
|
|
557
|
+
});
|
|
558
|
+
return new graph_js_1.Branch({
|
|
559
|
+
path: CONTROL_BRANCH_PATH,
|
|
560
|
+
});
|
|
561
|
+
}
|
package/dist/graph/state.d.ts
CHANGED
|
@@ -133,5 +133,7 @@ export declare class CompiledStateGraph<S, U, N extends string = typeof START, I
|
|
|
133
133
|
attachNode(key: typeof START, node?: never): void;
|
|
134
134
|
attachNode(key: N, node: StateGraphNodeSpec<S, U>): void;
|
|
135
135
|
attachEdge(start: N | N[] | "__start__", end: N | "__end__"): void;
|
|
136
|
-
attachBranch(start: N | typeof START, name: string, branch: Branch<S, N
|
|
136
|
+
attachBranch(start: N | typeof START, name: string, branch: Branch<S, N>, options?: {
|
|
137
|
+
withReader?: boolean;
|
|
138
|
+
}): void;
|
|
137
139
|
}
|