@langchain/langgraph 0.1.1 → 0.1.2
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/README.md +2 -2
- package/dist/constants.cjs +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/graph/annotation.cjs +78 -4
- package/dist/graph/annotation.d.ts +82 -5
- package/dist/graph/annotation.js +77 -2
- package/dist/graph/graph.cjs +14 -8
- package/dist/graph/graph.d.ts +14 -5
- package/dist/graph/graph.js +14 -8
- package/dist/graph/message.cjs +6 -0
- package/dist/graph/message.d.ts +6 -0
- package/dist/graph/message.js +6 -0
- package/dist/graph/messages_annotation.cjs +5 -0
- package/dist/graph/messages_annotation.d.ts +5 -0
- package/dist/graph/messages_annotation.js +5 -0
- package/dist/graph/state.cjs +84 -3
- package/dist/graph/state.d.ts +75 -5
- package/dist/graph/state.js +86 -5
- package/dist/prebuilt/agent_executor.cjs +1 -0
- package/dist/prebuilt/agent_executor.d.ts +2 -0
- package/dist/prebuilt/agent_executor.js +1 -0
- package/dist/prebuilt/chat_agent_executor.cjs +1 -0
- package/dist/prebuilt/chat_agent_executor.d.ts +2 -0
- package/dist/prebuilt/chat_agent_executor.js +1 -0
- package/dist/pregel/algo.cjs +3 -41
- package/dist/pregel/algo.d.ts +0 -5
- package/dist/pregel/algo.js +2 -39
- package/dist/pregel/debug.d.ts +1 -1
- package/dist/pregel/index.cjs +17 -30
- package/dist/pregel/index.d.ts +2 -0
- package/dist/pregel/index.js +18 -31
- package/dist/pregel/loop.cjs +5 -2
- package/dist/pregel/loop.js +5 -2
- package/dist/pregel/read.cjs +19 -1
- package/dist/pregel/read.d.ts +5 -0
- package/dist/pregel/read.js +19 -1
- package/dist/pregel/retry.cjs +147 -0
- package/dist/pregel/retry.d.ts +11 -0
- package/dist/pregel/retry.js +143 -0
- package/dist/pregel/types.d.ts +4 -2
- package/dist/pregel/utils.d.ts +26 -0
- package/dist/web.d.ts +1 -0
- package/package.json +5 -4
package/dist/graph/state.cjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CompiledStateGraph = exports.StateGraph = void 0;
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
5
|
+
const runnables_1 = require("@langchain/core/runnables");
|
|
4
6
|
const graph_js_1 = require("./graph.cjs");
|
|
5
7
|
const write_js_1 = require("../pregel/write.cjs");
|
|
6
8
|
const read_js_1 = require("../pregel/read.cjs");
|
|
@@ -11,6 +13,68 @@ const constants_js_1 = require("../constants.cjs");
|
|
|
11
13
|
const errors_js_1 = require("../errors.cjs");
|
|
12
14
|
const annotation_js_1 = require("./annotation.cjs");
|
|
13
15
|
const ROOT = "__root__";
|
|
16
|
+
/**
|
|
17
|
+
* A graph whose nodes communicate by reading and writing to a shared state.
|
|
18
|
+
* Each node takes a defined `State` as input and returns a `Partial<State>`.
|
|
19
|
+
*
|
|
20
|
+
* Each state key can optionally be annotated with a reducer function that
|
|
21
|
+
* will be used to aggregate the values of that key received from multiple nodes.
|
|
22
|
+
* The signature of a reducer function is (left: Value, right: UpdateValue) => Value.
|
|
23
|
+
*
|
|
24
|
+
* See {@link Annotation} for more on defining state.
|
|
25
|
+
*
|
|
26
|
+
* After adding nodes and edges to your graph, you must call `.compile()` on it before
|
|
27
|
+
* you can use it.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* import {
|
|
32
|
+
* type BaseMessage,
|
|
33
|
+
* AIMessage,
|
|
34
|
+
* HumanMessage,
|
|
35
|
+
* } from "@langchain/core/messages";
|
|
36
|
+
* import { StateGraph, Annotation } from "@langchain/langgraph";
|
|
37
|
+
*
|
|
38
|
+
* // Define a state with a single key named "messages" that will
|
|
39
|
+
* // combine a returned BaseMessage or arrays of BaseMessages
|
|
40
|
+
* const StateAnnotation = Annotation.Root({
|
|
41
|
+
* sentiment: Annotation<string>,
|
|
42
|
+
* messages: Annotation<BaseMessage[]>({
|
|
43
|
+
* reducer: (left: BaseMessage[], right: BaseMessage | BaseMessage[]) => {
|
|
44
|
+
* if (Array.isArray(right)) {
|
|
45
|
+
* return left.concat(right);
|
|
46
|
+
* }
|
|
47
|
+
* return left.concat([right]);
|
|
48
|
+
* },
|
|
49
|
+
* default: () => [],
|
|
50
|
+
* }),
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* const graphBuilder = new StateGraph(StateAnnotation);
|
|
54
|
+
*
|
|
55
|
+
* // A node in the graph that returns an object with a "messages" key
|
|
56
|
+
* // will update the state by combining the existing value with the returned one.
|
|
57
|
+
* const myNode = (state: typeof StateAnnotation.State) => {
|
|
58
|
+
* return {
|
|
59
|
+
* messages: [new AIMessage("Some new response")],
|
|
60
|
+
* sentiment: "positive",
|
|
61
|
+
* };
|
|
62
|
+
* };
|
|
63
|
+
*
|
|
64
|
+
* const graph = graphBuilder
|
|
65
|
+
* .addNode("myNode", myNode)
|
|
66
|
+
* .addEdge("__start__", "myNode")
|
|
67
|
+
* .addEdge("myNode", "__end__")
|
|
68
|
+
* .compile();
|
|
69
|
+
*
|
|
70
|
+
* await graph.invoke({ messages: [new HumanMessage("how are you?")] });
|
|
71
|
+
*
|
|
72
|
+
* // {
|
|
73
|
+
* // messages: [HumanMessage("how are you?"), AIMessage("Some new response")],
|
|
74
|
+
* // sentiment: "positive",
|
|
75
|
+
* // }
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
14
78
|
class StateGraph extends graph_js_1.Graph {
|
|
15
79
|
constructor(fields) {
|
|
16
80
|
super();
|
|
@@ -55,11 +119,27 @@ class StateGraph extends graph_js_1.Graph {
|
|
|
55
119
|
...Array.from(this.waitingEdges).flatMap(([starts, end]) => starts.map((start) => [start, end])),
|
|
56
120
|
]);
|
|
57
121
|
}
|
|
58
|
-
addNode(key, action) {
|
|
122
|
+
addNode(key, action, options) {
|
|
59
123
|
if (key in this.channels) {
|
|
60
124
|
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.`);
|
|
61
125
|
}
|
|
62
|
-
|
|
126
|
+
if (key.includes(constants_js_1.CHECKPOINT_NAMESPACE_SEPARATOR)) {
|
|
127
|
+
throw new Error(`"${constants_js_1.CHECKPOINT_NAMESPACE_SEPARATOR}" is a reserved character and is not allowed in node names.`);
|
|
128
|
+
}
|
|
129
|
+
this.warnIfCompiled(`Adding a node to a graph that has already been compiled. This will not be reflected in the compiled graph.`);
|
|
130
|
+
if (key in this.nodes) {
|
|
131
|
+
throw new Error(`Node \`${key}\` already present.`);
|
|
132
|
+
}
|
|
133
|
+
if (key === graph_js_1.END || key === graph_js_1.START) {
|
|
134
|
+
throw new Error(`Node \`${key}\` is reserved.`);
|
|
135
|
+
}
|
|
136
|
+
const nodeSpec = {
|
|
137
|
+
runnable: (0, runnables_1._coerceToRunnable)(action),
|
|
138
|
+
retryPolicy: options?.retryPolicy,
|
|
139
|
+
metadata: options?.metadata,
|
|
140
|
+
};
|
|
141
|
+
this.nodes[key] = nodeSpec;
|
|
142
|
+
return this;
|
|
63
143
|
}
|
|
64
144
|
addEdge(startKey, endKey) {
|
|
65
145
|
if (typeof startKey === "string") {
|
|
@@ -198,7 +278,8 @@ class CompiledStateGraph extends graph_js_1.CompiledGraph {
|
|
|
198
278
|
writers: [
|
|
199
279
|
new write_js_1.ChannelWrite(stateWriteEntries.concat({ channel: key, value: key }), [constants_js_1.TAG_HIDDEN]),
|
|
200
280
|
],
|
|
201
|
-
bound: node,
|
|
281
|
+
bound: node?.runnable,
|
|
282
|
+
retryPolicy: node?.retryPolicy,
|
|
202
283
|
});
|
|
203
284
|
}
|
|
204
285
|
}
|
package/dist/graph/state.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RunnableLike } from "@langchain/core/runnables";
|
|
2
2
|
import { BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
3
3
|
import { BaseChannel } from "../channels/base.js";
|
|
4
|
-
import { END, CompiledGraph, Graph, START, Branch } from "./graph.js";
|
|
4
|
+
import { END, CompiledGraph, Graph, START, Branch, AddNodeOptions, NodeSpec } from "./graph.js";
|
|
5
5
|
import { All } from "../pregel/types.js";
|
|
6
6
|
import { AnnotationRoot, SingleReducer, StateDefinition, StateType, UpdateType } from "./annotation.js";
|
|
7
|
+
import type { RetryPolicy } from "../pregel/utils.js";
|
|
7
8
|
export type ChannelReducers<Channels extends object> = {
|
|
8
9
|
[K in keyof Channels]: SingleReducer<Channels[K], any>;
|
|
9
10
|
};
|
|
@@ -14,12 +15,81 @@ export interface StateGraphArgs<Channels extends object | unknown> {
|
|
|
14
15
|
__root__: Channels;
|
|
15
16
|
}>;
|
|
16
17
|
}
|
|
17
|
-
export
|
|
18
|
+
export type StateGraphNodeSpec<RunInput, RunOutput> = NodeSpec<RunInput, RunOutput> & {
|
|
19
|
+
input?: any;
|
|
20
|
+
retryPolicy?: RetryPolicy;
|
|
21
|
+
};
|
|
22
|
+
export type StateGraphAddNodeOptions = {
|
|
23
|
+
retryPolicy?: RetryPolicy;
|
|
24
|
+
} & AddNodeOptions;
|
|
25
|
+
/**
|
|
26
|
+
* A graph whose nodes communicate by reading and writing to a shared state.
|
|
27
|
+
* Each node takes a defined `State` as input and returns a `Partial<State>`.
|
|
28
|
+
*
|
|
29
|
+
* Each state key can optionally be annotated with a reducer function that
|
|
30
|
+
* will be used to aggregate the values of that key received from multiple nodes.
|
|
31
|
+
* The signature of a reducer function is (left: Value, right: UpdateValue) => Value.
|
|
32
|
+
*
|
|
33
|
+
* See {@link Annotation} for more on defining state.
|
|
34
|
+
*
|
|
35
|
+
* After adding nodes and edges to your graph, you must call `.compile()` on it before
|
|
36
|
+
* you can use it.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* import {
|
|
41
|
+
* type BaseMessage,
|
|
42
|
+
* AIMessage,
|
|
43
|
+
* HumanMessage,
|
|
44
|
+
* } from "@langchain/core/messages";
|
|
45
|
+
* import { StateGraph, Annotation } from "@langchain/langgraph";
|
|
46
|
+
*
|
|
47
|
+
* // Define a state with a single key named "messages" that will
|
|
48
|
+
* // combine a returned BaseMessage or arrays of BaseMessages
|
|
49
|
+
* const StateAnnotation = Annotation.Root({
|
|
50
|
+
* sentiment: Annotation<string>,
|
|
51
|
+
* messages: Annotation<BaseMessage[]>({
|
|
52
|
+
* reducer: (left: BaseMessage[], right: BaseMessage | BaseMessage[]) => {
|
|
53
|
+
* if (Array.isArray(right)) {
|
|
54
|
+
* return left.concat(right);
|
|
55
|
+
* }
|
|
56
|
+
* return left.concat([right]);
|
|
57
|
+
* },
|
|
58
|
+
* default: () => [],
|
|
59
|
+
* }),
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* const graphBuilder = new StateGraph(StateAnnotation);
|
|
63
|
+
*
|
|
64
|
+
* // A node in the graph that returns an object with a "messages" key
|
|
65
|
+
* // will update the state by combining the existing value with the returned one.
|
|
66
|
+
* const myNode = (state: typeof StateAnnotation.State) => {
|
|
67
|
+
* return {
|
|
68
|
+
* messages: [new AIMessage("Some new response")],
|
|
69
|
+
* sentiment: "positive",
|
|
70
|
+
* };
|
|
71
|
+
* };
|
|
72
|
+
*
|
|
73
|
+
* const graph = graphBuilder
|
|
74
|
+
* .addNode("myNode", myNode)
|
|
75
|
+
* .addEdge("__start__", "myNode")
|
|
76
|
+
* .addEdge("myNode", "__end__")
|
|
77
|
+
* .compile();
|
|
78
|
+
*
|
|
79
|
+
* await graph.invoke({ messages: [new HumanMessage("how are you?")] });
|
|
80
|
+
*
|
|
81
|
+
* // {
|
|
82
|
+
* // messages: [HumanMessage("how are you?"), AIMessage("Some new response")],
|
|
83
|
+
* // sentiment: "positive",
|
|
84
|
+
* // }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
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>> {
|
|
18
88
|
channels: Record<string, BaseChannel>;
|
|
19
89
|
waitingEdges: Set<[N[], N]>;
|
|
20
90
|
constructor(fields: SD extends StateDefinition ? SD | AnnotationRoot<SD> | StateGraphArgs<S> : StateGraphArgs<S>);
|
|
21
91
|
get allEdges(): Set<[string, string]>;
|
|
22
|
-
addNode<K extends string, NodeInput = S>(key: K, action: RunnableLike<NodeInput, U
|
|
92
|
+
addNode<K extends string, NodeInput = S>(key: K, action: RunnableLike<NodeInput, U>, options?: StateGraphAddNodeOptions): StateGraph<SD, S, U, N | K>;
|
|
23
93
|
addEdge(startKey: typeof START | N | N[], endKey: N | typeof END): this;
|
|
24
94
|
compile({ checkpointer, interruptBefore, interruptAfter, }?: {
|
|
25
95
|
checkpointer?: BaseCheckpointSaver;
|
|
@@ -30,7 +100,7 @@ export declare class StateGraph<SD extends StateDefinition | unknown, S = SD ext
|
|
|
30
100
|
export declare class CompiledStateGraph<S, U, N extends string = typeof START> extends CompiledGraph<N, S, U> {
|
|
31
101
|
builder: StateGraph<unknown, S, U, N>;
|
|
32
102
|
attachNode(key: typeof START, node?: never): void;
|
|
33
|
-
attachNode(key: N, node:
|
|
103
|
+
attachNode(key: N, node: StateGraphNodeSpec<S, U>): void;
|
|
34
104
|
attachEdge(start: N | N[] | "__start__", end: N | "__end__"): void;
|
|
35
105
|
attachBranch(start: N | typeof START, name: string, branch: Branch<S, N>): void;
|
|
36
106
|
}
|
package/dist/graph/state.js
CHANGED
|
@@ -1,13 +1,77 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
2
|
+
import { _coerceToRunnable, } from "@langchain/core/runnables";
|
|
3
|
+
import { END, CompiledGraph, Graph, START, } from "./graph.js";
|
|
2
4
|
import { ChannelWrite, PASSTHROUGH, SKIP_WRITE, } from "../pregel/write.js";
|
|
3
5
|
import { ChannelRead, PregelNode } from "../pregel/read.js";
|
|
4
6
|
import { NamedBarrierValue } from "../channels/named_barrier_value.js";
|
|
5
7
|
import { EphemeralValue } from "../channels/ephemeral_value.js";
|
|
6
8
|
import { RunnableCallable } from "../utils.js";
|
|
7
|
-
import { _isSend, TAG_HIDDEN } from "../constants.js";
|
|
9
|
+
import { _isSend, CHECKPOINT_NAMESPACE_SEPARATOR, TAG_HIDDEN, } from "../constants.js";
|
|
8
10
|
import { InvalidUpdateError } from "../errors.js";
|
|
9
11
|
import { getChannel, } from "./annotation.js";
|
|
10
12
|
const ROOT = "__root__";
|
|
13
|
+
/**
|
|
14
|
+
* A graph whose nodes communicate by reading and writing to a shared state.
|
|
15
|
+
* Each node takes a defined `State` as input and returns a `Partial<State>`.
|
|
16
|
+
*
|
|
17
|
+
* Each state key can optionally be annotated with a reducer function that
|
|
18
|
+
* will be used to aggregate the values of that key received from multiple nodes.
|
|
19
|
+
* The signature of a reducer function is (left: Value, right: UpdateValue) => Value.
|
|
20
|
+
*
|
|
21
|
+
* See {@link Annotation} for more on defining state.
|
|
22
|
+
*
|
|
23
|
+
* After adding nodes and edges to your graph, you must call `.compile()` on it before
|
|
24
|
+
* you can use it.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import {
|
|
29
|
+
* type BaseMessage,
|
|
30
|
+
* AIMessage,
|
|
31
|
+
* HumanMessage,
|
|
32
|
+
* } from "@langchain/core/messages";
|
|
33
|
+
* import { StateGraph, Annotation } from "@langchain/langgraph";
|
|
34
|
+
*
|
|
35
|
+
* // Define a state with a single key named "messages" that will
|
|
36
|
+
* // combine a returned BaseMessage or arrays of BaseMessages
|
|
37
|
+
* const StateAnnotation = Annotation.Root({
|
|
38
|
+
* sentiment: Annotation<string>,
|
|
39
|
+
* messages: Annotation<BaseMessage[]>({
|
|
40
|
+
* reducer: (left: BaseMessage[], right: BaseMessage | BaseMessage[]) => {
|
|
41
|
+
* if (Array.isArray(right)) {
|
|
42
|
+
* return left.concat(right);
|
|
43
|
+
* }
|
|
44
|
+
* return left.concat([right]);
|
|
45
|
+
* },
|
|
46
|
+
* default: () => [],
|
|
47
|
+
* }),
|
|
48
|
+
* });
|
|
49
|
+
*
|
|
50
|
+
* const graphBuilder = new StateGraph(StateAnnotation);
|
|
51
|
+
*
|
|
52
|
+
* // A node in the graph that returns an object with a "messages" key
|
|
53
|
+
* // will update the state by combining the existing value with the returned one.
|
|
54
|
+
* const myNode = (state: typeof StateAnnotation.State) => {
|
|
55
|
+
* return {
|
|
56
|
+
* messages: [new AIMessage("Some new response")],
|
|
57
|
+
* sentiment: "positive",
|
|
58
|
+
* };
|
|
59
|
+
* };
|
|
60
|
+
*
|
|
61
|
+
* const graph = graphBuilder
|
|
62
|
+
* .addNode("myNode", myNode)
|
|
63
|
+
* .addEdge("__start__", "myNode")
|
|
64
|
+
* .addEdge("myNode", "__end__")
|
|
65
|
+
* .compile();
|
|
66
|
+
*
|
|
67
|
+
* await graph.invoke({ messages: [new HumanMessage("how are you?")] });
|
|
68
|
+
*
|
|
69
|
+
* // {
|
|
70
|
+
* // messages: [HumanMessage("how are you?"), AIMessage("Some new response")],
|
|
71
|
+
* // sentiment: "positive",
|
|
72
|
+
* // }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
11
75
|
export class StateGraph extends Graph {
|
|
12
76
|
constructor(fields) {
|
|
13
77
|
super();
|
|
@@ -52,11 +116,27 @@ export class StateGraph extends Graph {
|
|
|
52
116
|
...Array.from(this.waitingEdges).flatMap(([starts, end]) => starts.map((start) => [start, end])),
|
|
53
117
|
]);
|
|
54
118
|
}
|
|
55
|
-
addNode(key, action) {
|
|
119
|
+
addNode(key, action, options) {
|
|
56
120
|
if (key in this.channels) {
|
|
57
121
|
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.`);
|
|
58
122
|
}
|
|
59
|
-
|
|
123
|
+
if (key.includes(CHECKPOINT_NAMESPACE_SEPARATOR)) {
|
|
124
|
+
throw new Error(`"${CHECKPOINT_NAMESPACE_SEPARATOR}" is a reserved character and is not allowed in node names.`);
|
|
125
|
+
}
|
|
126
|
+
this.warnIfCompiled(`Adding a node to a graph that has already been compiled. This will not be reflected in the compiled graph.`);
|
|
127
|
+
if (key in this.nodes) {
|
|
128
|
+
throw new Error(`Node \`${key}\` already present.`);
|
|
129
|
+
}
|
|
130
|
+
if (key === END || key === START) {
|
|
131
|
+
throw new Error(`Node \`${key}\` is reserved.`);
|
|
132
|
+
}
|
|
133
|
+
const nodeSpec = {
|
|
134
|
+
runnable: _coerceToRunnable(action),
|
|
135
|
+
retryPolicy: options?.retryPolicy,
|
|
136
|
+
metadata: options?.metadata,
|
|
137
|
+
};
|
|
138
|
+
this.nodes[key] = nodeSpec;
|
|
139
|
+
return this;
|
|
60
140
|
}
|
|
61
141
|
addEdge(startKey, endKey) {
|
|
62
142
|
if (typeof startKey === "string") {
|
|
@@ -194,7 +274,8 @@ export class CompiledStateGraph extends CompiledGraph {
|
|
|
194
274
|
writers: [
|
|
195
275
|
new ChannelWrite(stateWriteEntries.concat({ channel: key, value: key }), [TAG_HIDDEN]),
|
|
196
276
|
],
|
|
197
|
-
bound: node,
|
|
277
|
+
bound: node?.runnable,
|
|
278
|
+
retryPolicy: node?.retryPolicy,
|
|
198
279
|
});
|
|
199
280
|
}
|
|
200
281
|
}
|
|
@@ -4,6 +4,7 @@ exports.createAgentExecutor = void 0;
|
|
|
4
4
|
const tool_executor_js_1 = require("./tool_executor.cjs");
|
|
5
5
|
const state_js_1 = require("../graph/state.cjs");
|
|
6
6
|
const index_js_1 = require("../graph/index.cjs");
|
|
7
|
+
/** @ignore */
|
|
7
8
|
function createAgentExecutor({ agentRunnable, tools, }) {
|
|
8
9
|
let toolExecutor;
|
|
9
10
|
if (!Array.isArray(tools)) {
|
|
@@ -7,12 +7,14 @@ interface Step {
|
|
|
7
7
|
action: AgentAction | AgentFinish;
|
|
8
8
|
observation: unknown;
|
|
9
9
|
}
|
|
10
|
+
/** @ignore */
|
|
10
11
|
export interface AgentExecutorState {
|
|
11
12
|
agentOutcome?: AgentAction | AgentFinish;
|
|
12
13
|
steps: Array<Step>;
|
|
13
14
|
input: string;
|
|
14
15
|
chatHistory?: BaseMessage[];
|
|
15
16
|
}
|
|
17
|
+
/** @ignore */
|
|
16
18
|
export declare function createAgentExecutor({ agentRunnable, tools, }: {
|
|
17
19
|
agentRunnable: Runnable;
|
|
18
20
|
tools: Array<Tool> | ToolExecutor;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ToolExecutor } from "./tool_executor.js";
|
|
2
2
|
import { StateGraph } from "../graph/state.js";
|
|
3
3
|
import { END, START } from "../graph/index.js";
|
|
4
|
+
/** @ignore */
|
|
4
5
|
export function createAgentExecutor({ agentRunnable, tools, }) {
|
|
5
6
|
let toolExecutor;
|
|
6
7
|
if (!Array.isArray(tools)) {
|
|
@@ -7,6 +7,7 @@ const runnables_1 = require("@langchain/core/runnables");
|
|
|
7
7
|
const tool_executor_js_1 = require("./tool_executor.cjs");
|
|
8
8
|
const state_js_1 = require("../graph/state.cjs");
|
|
9
9
|
const index_js_1 = require("../graph/index.cjs");
|
|
10
|
+
/** @ignore */
|
|
10
11
|
function createFunctionCallingExecutor({ model, tools, }) {
|
|
11
12
|
let toolExecutor;
|
|
12
13
|
let toolClasses;
|
|
@@ -4,9 +4,11 @@ import { RunnableToolLike } from "@langchain/core/runnables";
|
|
|
4
4
|
import { ToolExecutor } from "./tool_executor.js";
|
|
5
5
|
import { CompiledStateGraph } from "../graph/state.js";
|
|
6
6
|
import { START } from "../graph/index.js";
|
|
7
|
+
/** @ignore */
|
|
7
8
|
export type FunctionCallingExecutorState = {
|
|
8
9
|
messages: Array<BaseMessage>;
|
|
9
10
|
};
|
|
11
|
+
/** @ignore */
|
|
10
12
|
export declare function createFunctionCallingExecutor<Model extends object>({ model, tools, }: {
|
|
11
13
|
model: Model;
|
|
12
14
|
tools: Array<StructuredToolInterface | RunnableToolLike> | ToolExecutor;
|
|
@@ -4,6 +4,7 @@ import { RunnableLambda, } from "@langchain/core/runnables";
|
|
|
4
4
|
import { ToolExecutor } from "./tool_executor.js";
|
|
5
5
|
import { StateGraph, } from "../graph/state.js";
|
|
6
6
|
import { END, START } from "../graph/index.js";
|
|
7
|
+
/** @ignore */
|
|
7
8
|
export function createFunctionCallingExecutor({ model, tools, }) {
|
|
8
9
|
let toolExecutor;
|
|
9
10
|
let toolClasses;
|
package/dist/pregel/algo.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports._prepareNextTasks = exports._applyWrites = exports._localWrite = exports._localRead = exports.shouldInterrupt = exports.
|
|
3
|
+
exports._prepareNextTasks = exports._applyWrites = exports._localWrite = exports._localRead = exports.shouldInterrupt = exports.increment = void 0;
|
|
4
4
|
/* eslint-disable no-param-reassign */
|
|
5
5
|
const runnables_1 = require("@langchain/core/runnables");
|
|
6
6
|
const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
|
|
@@ -13,46 +13,6 @@ const increment = (current) => {
|
|
|
13
13
|
return current !== undefined ? current + 1 : 1;
|
|
14
14
|
};
|
|
15
15
|
exports.increment = increment;
|
|
16
|
-
async function* executeTasks(tasks, stepTimeout, signal
|
|
17
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
-
) {
|
|
19
|
-
if (stepTimeout && signal) {
|
|
20
|
-
if ("any" in AbortSignal) {
|
|
21
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
-
signal = AbortSignal.any([
|
|
23
|
-
signal,
|
|
24
|
-
AbortSignal.timeout(stepTimeout),
|
|
25
|
-
]);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
else if (stepTimeout) {
|
|
29
|
-
signal = AbortSignal.timeout(stepTimeout);
|
|
30
|
-
}
|
|
31
|
-
// Abort if signal is aborted
|
|
32
|
-
signal?.throwIfAborted();
|
|
33
|
-
// Start all tasks
|
|
34
|
-
const executingTasks = Object.fromEntries(Object.entries(tasks).map(([taskId, task]) => {
|
|
35
|
-
return [taskId, task()];
|
|
36
|
-
}));
|
|
37
|
-
let listener;
|
|
38
|
-
const signalPromise = new Promise((_resolve, reject) => {
|
|
39
|
-
listener = () => reject(new Error("Abort"));
|
|
40
|
-
signal?.addEventListener("abort", listener);
|
|
41
|
-
}).finally(() => signal?.removeEventListener("abort", listener));
|
|
42
|
-
while (Object.keys(executingTasks).length > 0) {
|
|
43
|
-
const { task, error } = await Promise.race([
|
|
44
|
-
...Object.values(executingTasks),
|
|
45
|
-
signalPromise,
|
|
46
|
-
]);
|
|
47
|
-
if (error !== undefined) {
|
|
48
|
-
// TODO: don't stop others if exception is interrupt
|
|
49
|
-
throw error;
|
|
50
|
-
}
|
|
51
|
-
yield task;
|
|
52
|
-
delete executingTasks[task.id];
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
exports.executeTasks = executeTasks;
|
|
56
16
|
function shouldInterrupt(checkpoint, interruptNodes, tasks) {
|
|
57
17
|
const versionValues = Object.values(checkpoint.channel_versions);
|
|
58
18
|
const versionType = versionValues.length > 0 ? typeof versionValues[0] : undefined;
|
|
@@ -253,6 +213,7 @@ function _prepareNextTasks(checkpoint, processes, channels, config, forExecution
|
|
|
253
213
|
},
|
|
254
214
|
}),
|
|
255
215
|
id: taskId,
|
|
216
|
+
retry_policy: proc.retryPolicy,
|
|
256
217
|
});
|
|
257
218
|
}
|
|
258
219
|
}
|
|
@@ -325,6 +286,7 @@ function _prepareNextTasks(checkpoint, processes, channels, config, forExecution
|
|
|
325
286
|
},
|
|
326
287
|
}),
|
|
327
288
|
id: taskId,
|
|
289
|
+
retry_policy: proc.retryPolicy,
|
|
328
290
|
});
|
|
329
291
|
}
|
|
330
292
|
}
|
package/dist/pregel/algo.d.ts
CHANGED
|
@@ -16,11 +16,6 @@ export type WritesProtocol<C = string> = {
|
|
|
16
16
|
triggers: string[];
|
|
17
17
|
};
|
|
18
18
|
export declare const increment: (current?: number) => number;
|
|
19
|
-
export declare function executeTasks(tasks: Record<string, () => Promise<{
|
|
20
|
-
task: PregelExecutableTask<any, any>;
|
|
21
|
-
result: any;
|
|
22
|
-
error: Error;
|
|
23
|
-
}>>, stepTimeout?: number, signal?: AbortSignal): AsyncGenerator<PregelExecutableTask<any, any>>;
|
|
24
19
|
export declare function shouldInterrupt<N extends PropertyKey, C extends PropertyKey>(checkpoint: Checkpoint, interruptNodes: All | N[], tasks: PregelExecutableTask<N, C>[]): boolean;
|
|
25
20
|
export declare function _localRead<Cc extends StrRecord<string, BaseChannel>>(checkpoint: ReadonlyCheckpoint, channels: Cc, task: WritesProtocol<keyof Cc>, select: Array<keyof Cc> | keyof Cc, fresh?: boolean): Record<string, unknown> | unknown;
|
|
26
21
|
export declare function _localWrite(commit: (writes: [string, any][]) => void, processes: Record<string, PregelNode>, channels: Record<string, BaseChannel>, writes: [string, any][]): void;
|
package/dist/pregel/algo.js
CHANGED
|
@@ -9,45 +9,6 @@ import { _getIdMetadata, getNullChannelVersion } from "./utils.js";
|
|
|
9
9
|
export const increment = (current) => {
|
|
10
10
|
return current !== undefined ? current + 1 : 1;
|
|
11
11
|
};
|
|
12
|
-
export async function* executeTasks(tasks, stepTimeout, signal
|
|
13
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
-
) {
|
|
15
|
-
if (stepTimeout && signal) {
|
|
16
|
-
if ("any" in AbortSignal) {
|
|
17
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
-
signal = AbortSignal.any([
|
|
19
|
-
signal,
|
|
20
|
-
AbortSignal.timeout(stepTimeout),
|
|
21
|
-
]);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
else if (stepTimeout) {
|
|
25
|
-
signal = AbortSignal.timeout(stepTimeout);
|
|
26
|
-
}
|
|
27
|
-
// Abort if signal is aborted
|
|
28
|
-
signal?.throwIfAborted();
|
|
29
|
-
// Start all tasks
|
|
30
|
-
const executingTasks = Object.fromEntries(Object.entries(tasks).map(([taskId, task]) => {
|
|
31
|
-
return [taskId, task()];
|
|
32
|
-
}));
|
|
33
|
-
let listener;
|
|
34
|
-
const signalPromise = new Promise((_resolve, reject) => {
|
|
35
|
-
listener = () => reject(new Error("Abort"));
|
|
36
|
-
signal?.addEventListener("abort", listener);
|
|
37
|
-
}).finally(() => signal?.removeEventListener("abort", listener));
|
|
38
|
-
while (Object.keys(executingTasks).length > 0) {
|
|
39
|
-
const { task, error } = await Promise.race([
|
|
40
|
-
...Object.values(executingTasks),
|
|
41
|
-
signalPromise,
|
|
42
|
-
]);
|
|
43
|
-
if (error !== undefined) {
|
|
44
|
-
// TODO: don't stop others if exception is interrupt
|
|
45
|
-
throw error;
|
|
46
|
-
}
|
|
47
|
-
yield task;
|
|
48
|
-
delete executingTasks[task.id];
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
12
|
export function shouldInterrupt(checkpoint, interruptNodes, tasks) {
|
|
52
13
|
const versionValues = Object.values(checkpoint.channel_versions);
|
|
53
14
|
const versionType = versionValues.length > 0 ? typeof versionValues[0] : undefined;
|
|
@@ -244,6 +205,7 @@ export function _prepareNextTasks(checkpoint, processes, channels, config, forEx
|
|
|
244
205
|
},
|
|
245
206
|
}),
|
|
246
207
|
id: taskId,
|
|
208
|
+
retry_policy: proc.retryPolicy,
|
|
247
209
|
});
|
|
248
210
|
}
|
|
249
211
|
}
|
|
@@ -316,6 +278,7 @@ export function _prepareNextTasks(checkpoint, processes, channels, config, forEx
|
|
|
316
278
|
},
|
|
317
279
|
}),
|
|
318
280
|
id: taskId,
|
|
281
|
+
retry_policy: proc.retryPolicy,
|
|
319
282
|
});
|
|
320
283
|
}
|
|
321
284
|
}
|
package/dist/pregel/debug.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export declare function mapDebugCheckpoint<N extends PropertyKey, C extends Prop
|
|
|
29
29
|
timestamp: string;
|
|
30
30
|
step: number;
|
|
31
31
|
payload: {
|
|
32
|
-
config: Partial<Record<"
|
|
32
|
+
config: Partial<Record<"configurable" | "timeout" | "signal" | "tags" | "metadata" | "callbacks" | "recursion_limit" | "max_concurrency" | "run_name" | "run_id", unknown>>;
|
|
33
33
|
values: any;
|
|
34
34
|
metadata: CheckpointMetadata;
|
|
35
35
|
next: N[];
|
package/dist/pregel/index.cjs
CHANGED
|
@@ -16,6 +16,7 @@ const algo_js_1 = require("./algo.cjs");
|
|
|
16
16
|
const utils_js_1 = require("../utils.cjs");
|
|
17
17
|
const utils_js_2 = require("./utils.cjs");
|
|
18
18
|
const loop_js_1 = require("./loop.cjs");
|
|
19
|
+
const retry_js_1 = require("./retry.cjs");
|
|
19
20
|
function isString(value) {
|
|
20
21
|
return typeof value === "string";
|
|
21
22
|
}
|
|
@@ -159,6 +160,12 @@ class Pregel extends runnables_1.Runnable {
|
|
|
159
160
|
writable: true,
|
|
160
161
|
value: void 0
|
|
161
162
|
});
|
|
163
|
+
Object.defineProperty(this, "retryPolicy", {
|
|
164
|
+
enumerable: true,
|
|
165
|
+
configurable: true,
|
|
166
|
+
writable: true,
|
|
167
|
+
value: void 0
|
|
168
|
+
});
|
|
162
169
|
let { streamMode } = fields;
|
|
163
170
|
if (streamMode != null && !Array.isArray(streamMode)) {
|
|
164
171
|
streamMode = [streamMode];
|
|
@@ -175,6 +182,7 @@ class Pregel extends runnables_1.Runnable {
|
|
|
175
182
|
this.stepTimeout = fields.stepTimeout ?? this.stepTimeout;
|
|
176
183
|
this.debug = fields.debug ?? this.debug;
|
|
177
184
|
this.checkpointer = fields.checkpointer;
|
|
185
|
+
this.retryPolicy = fields.retryPolicy;
|
|
178
186
|
if (this.autoValidate) {
|
|
179
187
|
this.validate();
|
|
180
188
|
}
|
|
@@ -344,12 +352,11 @@ class Pregel extends runnables_1.Runnable {
|
|
|
344
352
|
writers.length > 1 ? runnables_1.RunnableSequence.from(writers) : writers[0],
|
|
345
353
|
writes: [],
|
|
346
354
|
triggers: [constants_js_1.INTERRUPT],
|
|
347
|
-
config: undefined,
|
|
348
355
|
id: (0, langgraph_checkpoint_1.uuid5)(constants_js_1.INTERRUPT, checkpoint.id),
|
|
349
356
|
};
|
|
350
357
|
// execute task
|
|
351
358
|
await task.proc.invoke(task.input, (0, runnables_1.patchConfig)(config, {
|
|
352
|
-
runName: `${this.
|
|
359
|
+
runName: config.runName ?? `${this.getName()}UpdateState`,
|
|
353
360
|
configurable: {
|
|
354
361
|
[constants_js_1.CONFIG_KEY_SEND]: (items) => task.writes.push(...items),
|
|
355
362
|
[constants_js_1.CONFIG_KEY_READ]: algo_js_1._localRead.bind(undefined, checkpoint, channels,
|
|
@@ -490,35 +497,15 @@ class Pregel extends runnables_1.Runnable {
|
|
|
490
497
|
if (debug) {
|
|
491
498
|
(0, debug_js_1.printStepTasks)(loop.step, loop.tasks);
|
|
492
499
|
}
|
|
493
|
-
// execute tasks, and wait for one to fail or all to finish.
|
|
494
|
-
// each task is independent from all other concurrent tasks
|
|
495
|
-
// yield updates/debug output as each task finishes
|
|
496
|
-
const tasks = Object.fromEntries(loop.tasks
|
|
497
|
-
.filter((task) => task.writes.length === 0)
|
|
498
|
-
.map((pregelTask) => {
|
|
499
|
-
return [
|
|
500
|
-
pregelTask.id,
|
|
501
|
-
async () => {
|
|
502
|
-
let error;
|
|
503
|
-
let result;
|
|
504
|
-
try {
|
|
505
|
-
result = await pregelTask.proc.invoke(pregelTask.input, pregelTask.config);
|
|
506
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
507
|
-
}
|
|
508
|
-
catch (e) {
|
|
509
|
-
error = e;
|
|
510
|
-
error.pregelTaskId = pregelTask.id;
|
|
511
|
-
}
|
|
512
|
-
return {
|
|
513
|
-
task: pregelTask,
|
|
514
|
-
result,
|
|
515
|
-
error,
|
|
516
|
-
};
|
|
517
|
-
},
|
|
518
|
-
];
|
|
519
|
-
}));
|
|
520
500
|
try {
|
|
521
|
-
for
|
|
501
|
+
// execute tasks, and wait for one to fail or all to finish.
|
|
502
|
+
// each task is independent from all other concurrent tasks
|
|
503
|
+
// yield updates/debug output as each task finishes
|
|
504
|
+
for await (const task of (0, retry_js_1.executeTasksWithRetry)(loop.tasks.filter((task) => task.writes.length === 0), {
|
|
505
|
+
stepTimeout: this.stepTimeout,
|
|
506
|
+
signal: config.signal,
|
|
507
|
+
retryPolicy: this.retryPolicy,
|
|
508
|
+
})) {
|
|
522
509
|
loop.putWrites(task.id, task.writes);
|
|
523
510
|
if (streamMode.includes("updates")) {
|
|
524
511
|
yield* (0, utils_js_1.prefixGenerator)((0, io_js_1.mapOutputUpdates)(outputKeys, [task]), streamMode.length > 1 ? "updates" : undefined);
|
package/dist/pregel/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { PregelNode } from "./read.js";
|
|
|
6
6
|
import { ChannelWrite } from "./write.js";
|
|
7
7
|
import { All, PregelInterface, PregelParams, StateSnapshot, StreamMode } from "./types.js";
|
|
8
8
|
import { StrRecord } from "./algo.js";
|
|
9
|
+
import { RetryPolicy } from "./utils.js";
|
|
9
10
|
type WriteValue = Runnable | RunnableFunc<unknown, unknown> | unknown;
|
|
10
11
|
export declare class Channel {
|
|
11
12
|
static subscribeTo(channels: string, options?: {
|
|
@@ -50,6 +51,7 @@ export declare class Pregel<Nn extends StrRecord<string, PregelNode>, Cc extends
|
|
|
50
51
|
stepTimeout?: number;
|
|
51
52
|
debug: boolean;
|
|
52
53
|
checkpointer?: BaseCheckpointSaver;
|
|
54
|
+
retryPolicy?: RetryPolicy;
|
|
53
55
|
constructor(fields: PregelParams<Nn, Cc>);
|
|
54
56
|
validate(): this;
|
|
55
57
|
get streamChannelsList(): Array<keyof Cc>;
|