@langchain/langgraph 0.0.33 → 0.0.34-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/README.md +1 -1
- package/dist/channels/base.cjs +1 -0
- package/dist/channels/base.js +1 -0
- package/dist/channels/ephemeral_value.cjs +1 -1
- package/dist/channels/ephemeral_value.js +1 -1
- package/dist/checkpoint/base.cjs +2 -0
- package/dist/checkpoint/base.d.ts +6 -0
- package/dist/checkpoint/base.js +2 -0
- package/dist/constants.cjs +79 -1
- package/dist/constants.d.ts +56 -0
- package/dist/constants.js +75 -0
- package/dist/graph/annotation.cjs +51 -0
- package/dist/graph/annotation.d.ts +41 -0
- package/dist/graph/annotation.js +45 -0
- package/dist/graph/graph.cjs +19 -4
- package/dist/graph/graph.d.ts +5 -4
- package/dist/graph/graph.js +20 -5
- package/dist/graph/index.cjs +3 -1
- package/dist/graph/index.d.ts +1 -0
- package/dist/graph/index.js +1 -0
- package/dist/graph/message.d.ts +1 -1
- package/dist/graph/state.cjs +24 -39
- package/dist/graph/state.d.ts +4 -29
- package/dist/graph/state.js +22 -36
- package/dist/pregel/index.cjs +111 -16
- package/dist/pregel/index.d.ts +7 -2
- package/dist/pregel/index.js +110 -16
- package/dist/pregel/io.cjs +31 -28
- package/dist/pregel/io.d.ts +1 -1
- package/dist/pregel/io.js +31 -28
- package/dist/pregel/read.cjs +4 -1
- package/dist/pregel/read.js +4 -1
- package/dist/pregel/write.cjs +60 -24
- package/dist/pregel/write.d.ts +11 -6
- package/dist/pregel/write.js +61 -25
- package/dist/web.cjs +4 -1
- package/dist/web.d.ts +2 -1
- package/dist/web.js +2 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -249,7 +249,7 @@ Is there anything else you'd like to know about the weather in New York or any o
|
|
|
249
249
|
- [Conceptual Guides](https://langchain-ai.github.io/langgraphjs/concepts/): In-depth explanations of the key concepts and principles behind LangGraph, such as nodes, edges, state and more.
|
|
250
250
|
- [API Reference](https://langchain-ai.github.io/langgraphjs/reference/graphs/): Review important classes and methods, simple examples of how to use the graph and checkpointing APIs, higher-level prebuilt components and more.
|
|
251
251
|
|
|
252
|
-
## Running Example
|
|
252
|
+
## Running Example Jupyter Notebooks
|
|
253
253
|
|
|
254
254
|
Please note that the *.ipynb notebooks in the `examples/` folder require [tslab](https://github.com/yunabe/tslab?tab=readme-ov-file) to be installed. In order to run these notebooks in VSCode, you will also need the [Jupyter](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) VSCode Extension installed. After cloning this repository, you can run `yarn build` in the root. You should then be all set!
|
|
255
255
|
|
package/dist/channels/base.cjs
CHANGED
|
@@ -56,6 +56,7 @@ function createCheckpoint(checkpoint, channels, step) {
|
|
|
56
56
|
channel_values: values,
|
|
57
57
|
channel_versions: { ...checkpoint.channel_versions },
|
|
58
58
|
versions_seen: (0, base_js_1.deepCopy)(checkpoint.versions_seen),
|
|
59
|
+
pending_sends: checkpoint.pending_sends ?? [],
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
62
|
exports.createCheckpoint = createCheckpoint;
|
package/dist/channels/base.js
CHANGED
package/dist/checkpoint/base.cjs
CHANGED
|
@@ -32,6 +32,7 @@ function emptyCheckpoint() {
|
|
|
32
32
|
channel_values: {},
|
|
33
33
|
channel_versions: {},
|
|
34
34
|
versions_seen: {},
|
|
35
|
+
pending_sends: [],
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
38
|
exports.emptyCheckpoint = emptyCheckpoint;
|
|
@@ -43,6 +44,7 @@ function copyCheckpoint(checkpoint) {
|
|
|
43
44
|
channel_values: { ...checkpoint.channel_values },
|
|
44
45
|
channel_versions: { ...checkpoint.channel_versions },
|
|
45
46
|
versions_seen: deepCopy(checkpoint.versions_seen),
|
|
47
|
+
pending_sends: [...checkpoint.pending_sends],
|
|
46
48
|
};
|
|
47
49
|
}
|
|
48
50
|
exports.copyCheckpoint = copyCheckpoint;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RunnableConfig } from "@langchain/core/runnables";
|
|
2
2
|
import { SerializerProtocol } from "../serde/base.js";
|
|
3
|
+
import { SendInterface } from "../constants.js";
|
|
3
4
|
export interface CheckpointMetadata {
|
|
4
5
|
source: "input" | "loop" | "update";
|
|
5
6
|
/**
|
|
@@ -40,6 +41,11 @@ export interface Checkpoint<N extends string = string, C extends string = string
|
|
|
40
41
|
* @default {}
|
|
41
42
|
*/
|
|
42
43
|
versions_seen: Record<N, Record<C, number>>;
|
|
44
|
+
/**
|
|
45
|
+
* List of packets sent to nodes but not yet processed.
|
|
46
|
+
* Cleared by the next checkpoint.
|
|
47
|
+
*/
|
|
48
|
+
pending_sends: SendInterface[];
|
|
43
49
|
}
|
|
44
50
|
export interface ReadonlyCheckpoint extends Readonly<Checkpoint> {
|
|
45
51
|
readonly channel_values: Readonly<Record<string, unknown>>;
|
package/dist/checkpoint/base.js
CHANGED
|
@@ -26,6 +26,7 @@ export function emptyCheckpoint() {
|
|
|
26
26
|
channel_values: {},
|
|
27
27
|
channel_versions: {},
|
|
28
28
|
versions_seen: {},
|
|
29
|
+
pending_sends: [],
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
32
|
export function copyCheckpoint(checkpoint) {
|
|
@@ -36,6 +37,7 @@ export function copyCheckpoint(checkpoint) {
|
|
|
36
37
|
channel_values: { ...checkpoint.channel_values },
|
|
37
38
|
channel_versions: { ...checkpoint.channel_versions },
|
|
38
39
|
versions_seen: deepCopy(checkpoint.versions_seen),
|
|
40
|
+
pending_sends: [...checkpoint.pending_sends],
|
|
39
41
|
};
|
|
40
42
|
}
|
|
41
43
|
export class BaseCheckpointSaver {
|
package/dist/constants.cjs
CHANGED
|
@@ -1,8 +1,86 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TASKS = exports.TAG_HIDDEN = exports.INTERRUPT = exports.CONFIG_KEY_READ = exports.CONFIG_KEY_SEND = void 0;
|
|
3
|
+
exports._isSend = exports.Send = exports._isSendInterface = exports.TASKS = exports.TAG_HIDDEN = exports.INTERRUPT = exports.CONFIG_KEY_READ = exports.CONFIG_KEY_SEND = void 0;
|
|
4
4
|
exports.CONFIG_KEY_SEND = "__pregel_send";
|
|
5
5
|
exports.CONFIG_KEY_READ = "__pregel_read";
|
|
6
6
|
exports.INTERRUPT = "__interrupt__";
|
|
7
7
|
exports.TAG_HIDDEN = "langsmith:hidden";
|
|
8
8
|
exports.TASKS = "__pregel_tasks";
|
|
9
|
+
function _isSendInterface(x) {
|
|
10
|
+
const operation = x;
|
|
11
|
+
return typeof operation.node === "string" && operation.args !== undefined;
|
|
12
|
+
}
|
|
13
|
+
exports._isSendInterface = _isSendInterface;
|
|
14
|
+
/**
|
|
15
|
+
* A message or packet to send to a specific node in the graph.
|
|
16
|
+
*
|
|
17
|
+
* The `Send` class is used within a `StateGraph`'s conditional edges to
|
|
18
|
+
* dynamically invoke a node with a custom state at the next step.
|
|
19
|
+
*
|
|
20
|
+
* Importantly, the sent state can differ from the core graph's state,
|
|
21
|
+
* allowing for flexible and dynamic workflow management.
|
|
22
|
+
*
|
|
23
|
+
* One such example is a "map-reduce" workflow where your graph invokes
|
|
24
|
+
* the same node multiple times in parallel with different states,
|
|
25
|
+
* before aggregating the results back into the main graph's state.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* import { Annotation, StateGraph } from "@langchain/langgraph";
|
|
30
|
+
*
|
|
31
|
+
* const ChainState = Annotation.Root({
|
|
32
|
+
* subjects: Annotation<string[]>,
|
|
33
|
+
* jokes: Annotation<string[]>({
|
|
34
|
+
* reducer: (a, b) => a.concat(b),
|
|
35
|
+
* }),
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* const continueToJokes = async (state: typeof ChainState.State) => {
|
|
39
|
+
* return state.subjects.map((subject) => {
|
|
40
|
+
* return new Send("generate_joke", { subjects: [subject] });
|
|
41
|
+
* });
|
|
42
|
+
* };
|
|
43
|
+
*
|
|
44
|
+
* const graph = new StateGraph(ChainState)
|
|
45
|
+
* .addNode("generate_joke", (state) => ({
|
|
46
|
+
* jokes: [`Joke about ${state.subjects}`],
|
|
47
|
+
* }))
|
|
48
|
+
* .addConditionalEdges("__start__", continueToJokes)
|
|
49
|
+
* .addEdge("generate_joke", "__end__")
|
|
50
|
+
* .compile();
|
|
51
|
+
*
|
|
52
|
+
* const res = await graph.invoke({ subjects: ["cats", "dogs"] });
|
|
53
|
+
*
|
|
54
|
+
* // Invoking with two subjects results in a generated joke for each
|
|
55
|
+
* // { subjects: ["cats", "dogs"], jokes: [`Joke about cats`, `Joke about dogs`] }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
class Send {
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
60
|
+
constructor(node, args) {
|
|
61
|
+
Object.defineProperty(this, "node", {
|
|
62
|
+
enumerable: true,
|
|
63
|
+
configurable: true,
|
|
64
|
+
writable: true,
|
|
65
|
+
value: node
|
|
66
|
+
});
|
|
67
|
+
Object.defineProperty(this, "args", {
|
|
68
|
+
enumerable: true,
|
|
69
|
+
configurable: true,
|
|
70
|
+
writable: true,
|
|
71
|
+
value: args
|
|
72
|
+
});
|
|
73
|
+
Object.defineProperty(this, "lg_name", {
|
|
74
|
+
enumerable: true,
|
|
75
|
+
configurable: true,
|
|
76
|
+
writable: true,
|
|
77
|
+
value: "Send"
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.Send = Send;
|
|
82
|
+
function _isSend(x) {
|
|
83
|
+
const operation = x;
|
|
84
|
+
return operation.lg_name === "Send";
|
|
85
|
+
}
|
|
86
|
+
exports._isSend = _isSend;
|
package/dist/constants.d.ts
CHANGED
|
@@ -3,3 +3,59 @@ export declare const CONFIG_KEY_READ = "__pregel_read";
|
|
|
3
3
|
export declare const INTERRUPT = "__interrupt__";
|
|
4
4
|
export declare const TAG_HIDDEN = "langsmith:hidden";
|
|
5
5
|
export declare const TASKS = "__pregel_tasks";
|
|
6
|
+
export interface SendInterface {
|
|
7
|
+
node: string;
|
|
8
|
+
args: any;
|
|
9
|
+
}
|
|
10
|
+
export declare function _isSendInterface(x: unknown): x is SendInterface;
|
|
11
|
+
/**
|
|
12
|
+
* A message or packet to send to a specific node in the graph.
|
|
13
|
+
*
|
|
14
|
+
* The `Send` class is used within a `StateGraph`'s conditional edges to
|
|
15
|
+
* dynamically invoke a node with a custom state at the next step.
|
|
16
|
+
*
|
|
17
|
+
* Importantly, the sent state can differ from the core graph's state,
|
|
18
|
+
* allowing for flexible and dynamic workflow management.
|
|
19
|
+
*
|
|
20
|
+
* One such example is a "map-reduce" workflow where your graph invokes
|
|
21
|
+
* the same node multiple times in parallel with different states,
|
|
22
|
+
* before aggregating the results back into the main graph's state.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import { Annotation, StateGraph } from "@langchain/langgraph";
|
|
27
|
+
*
|
|
28
|
+
* const ChainState = Annotation.Root({
|
|
29
|
+
* subjects: Annotation<string[]>,
|
|
30
|
+
* jokes: Annotation<string[]>({
|
|
31
|
+
* reducer: (a, b) => a.concat(b),
|
|
32
|
+
* }),
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* const continueToJokes = async (state: typeof ChainState.State) => {
|
|
36
|
+
* return state.subjects.map((subject) => {
|
|
37
|
+
* return new Send("generate_joke", { subjects: [subject] });
|
|
38
|
+
* });
|
|
39
|
+
* };
|
|
40
|
+
*
|
|
41
|
+
* const graph = new StateGraph(ChainState)
|
|
42
|
+
* .addNode("generate_joke", (state) => ({
|
|
43
|
+
* jokes: [`Joke about ${state.subjects}`],
|
|
44
|
+
* }))
|
|
45
|
+
* .addConditionalEdges("__start__", continueToJokes)
|
|
46
|
+
* .addEdge("generate_joke", "__end__")
|
|
47
|
+
* .compile();
|
|
48
|
+
*
|
|
49
|
+
* const res = await graph.invoke({ subjects: ["cats", "dogs"] });
|
|
50
|
+
*
|
|
51
|
+
* // Invoking with two subjects results in a generated joke for each
|
|
52
|
+
* // { subjects: ["cats", "dogs"], jokes: [`Joke about cats`, `Joke about dogs`] }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare class Send implements SendInterface {
|
|
56
|
+
node: string;
|
|
57
|
+
args: any;
|
|
58
|
+
lg_name: string;
|
|
59
|
+
constructor(node: string, args: any);
|
|
60
|
+
}
|
|
61
|
+
export declare function _isSend(x: unknown): x is Send;
|
package/dist/constants.js
CHANGED
|
@@ -3,3 +3,78 @@ export const CONFIG_KEY_READ = "__pregel_read";
|
|
|
3
3
|
export const INTERRUPT = "__interrupt__";
|
|
4
4
|
export const TAG_HIDDEN = "langsmith:hidden";
|
|
5
5
|
export const TASKS = "__pregel_tasks";
|
|
6
|
+
export function _isSendInterface(x) {
|
|
7
|
+
const operation = x;
|
|
8
|
+
return typeof operation.node === "string" && operation.args !== undefined;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A message or packet to send to a specific node in the graph.
|
|
12
|
+
*
|
|
13
|
+
* The `Send` class is used within a `StateGraph`'s conditional edges to
|
|
14
|
+
* dynamically invoke a node with a custom state at the next step.
|
|
15
|
+
*
|
|
16
|
+
* Importantly, the sent state can differ from the core graph's state,
|
|
17
|
+
* allowing for flexible and dynamic workflow management.
|
|
18
|
+
*
|
|
19
|
+
* One such example is a "map-reduce" workflow where your graph invokes
|
|
20
|
+
* the same node multiple times in parallel with different states,
|
|
21
|
+
* before aggregating the results back into the main graph's state.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* import { Annotation, StateGraph } from "@langchain/langgraph";
|
|
26
|
+
*
|
|
27
|
+
* const ChainState = Annotation.Root({
|
|
28
|
+
* subjects: Annotation<string[]>,
|
|
29
|
+
* jokes: Annotation<string[]>({
|
|
30
|
+
* reducer: (a, b) => a.concat(b),
|
|
31
|
+
* }),
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* const continueToJokes = async (state: typeof ChainState.State) => {
|
|
35
|
+
* return state.subjects.map((subject) => {
|
|
36
|
+
* return new Send("generate_joke", { subjects: [subject] });
|
|
37
|
+
* });
|
|
38
|
+
* };
|
|
39
|
+
*
|
|
40
|
+
* const graph = new StateGraph(ChainState)
|
|
41
|
+
* .addNode("generate_joke", (state) => ({
|
|
42
|
+
* jokes: [`Joke about ${state.subjects}`],
|
|
43
|
+
* }))
|
|
44
|
+
* .addConditionalEdges("__start__", continueToJokes)
|
|
45
|
+
* .addEdge("generate_joke", "__end__")
|
|
46
|
+
* .compile();
|
|
47
|
+
*
|
|
48
|
+
* const res = await graph.invoke({ subjects: ["cats", "dogs"] });
|
|
49
|
+
*
|
|
50
|
+
* // Invoking with two subjects results in a generated joke for each
|
|
51
|
+
* // { subjects: ["cats", "dogs"], jokes: [`Joke about cats`, `Joke about dogs`] }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export class Send {
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
56
|
+
constructor(node, args) {
|
|
57
|
+
Object.defineProperty(this, "node", {
|
|
58
|
+
enumerable: true,
|
|
59
|
+
configurable: true,
|
|
60
|
+
writable: true,
|
|
61
|
+
value: node
|
|
62
|
+
});
|
|
63
|
+
Object.defineProperty(this, "args", {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
configurable: true,
|
|
66
|
+
writable: true,
|
|
67
|
+
value: args
|
|
68
|
+
});
|
|
69
|
+
Object.defineProperty(this, "lg_name", {
|
|
70
|
+
enumerable: true,
|
|
71
|
+
configurable: true,
|
|
72
|
+
writable: true,
|
|
73
|
+
value: "Send"
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export function _isSend(x) {
|
|
78
|
+
const operation = x;
|
|
79
|
+
return operation.lg_name === "Send";
|
|
80
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getChannel = exports.Annotation = exports.AnnotationRoot = void 0;
|
|
4
|
+
const binop_js_1 = require("../channels/binop.cjs");
|
|
5
|
+
const last_value_js_1 = require("../channels/last_value.cjs");
|
|
6
|
+
class AnnotationRoot {
|
|
7
|
+
constructor(s) {
|
|
8
|
+
Object.defineProperty(this, "lc_graph_name", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true,
|
|
12
|
+
value: "AnnotationRoot"
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(this, "spec", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: void 0
|
|
19
|
+
});
|
|
20
|
+
this.spec = s;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.AnnotationRoot = AnnotationRoot;
|
|
24
|
+
function Annotation(annotation) {
|
|
25
|
+
if (annotation) {
|
|
26
|
+
return getChannel(annotation);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
// @ts-expect-error - Annotation without reducer
|
|
30
|
+
return new last_value_js_1.LastValue();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.Annotation = Annotation;
|
|
34
|
+
Annotation.Root = (sd) => new AnnotationRoot(sd);
|
|
35
|
+
function getChannel(reducer) {
|
|
36
|
+
if (typeof reducer === "object" &&
|
|
37
|
+
reducer &&
|
|
38
|
+
"reducer" in reducer &&
|
|
39
|
+
reducer.reducer) {
|
|
40
|
+
return new binop_js_1.BinaryOperatorAggregate(reducer.reducer, reducer.default);
|
|
41
|
+
}
|
|
42
|
+
if (typeof reducer === "object" &&
|
|
43
|
+
reducer &&
|
|
44
|
+
"value" in reducer &&
|
|
45
|
+
reducer.value) {
|
|
46
|
+
return new binop_js_1.BinaryOperatorAggregate(reducer.value, reducer.default);
|
|
47
|
+
}
|
|
48
|
+
// @ts-expect-error - Annotation without reducer
|
|
49
|
+
return new last_value_js_1.LastValue();
|
|
50
|
+
}
|
|
51
|
+
exports.getChannel = getChannel;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { RunnableLike } from "@langchain/core/runnables";
|
|
2
|
+
import { BaseChannel } from "../channels/base.js";
|
|
3
|
+
import { BinaryOperator, BinaryOperatorAggregate } from "../channels/binop.js";
|
|
4
|
+
import { LastValue } from "../channels/last_value.js";
|
|
5
|
+
export type SingleReducer<ValueType, UpdateType = ValueType> = {
|
|
6
|
+
reducer: BinaryOperator<ValueType, UpdateType>;
|
|
7
|
+
default?: () => ValueType;
|
|
8
|
+
} | {
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Use `reducer` instead
|
|
11
|
+
*/
|
|
12
|
+
value: BinaryOperator<ValueType, UpdateType>;
|
|
13
|
+
default?: () => ValueType;
|
|
14
|
+
} | null;
|
|
15
|
+
export interface StateDefinition {
|
|
16
|
+
[key: string]: BaseChannel | (() => BaseChannel);
|
|
17
|
+
}
|
|
18
|
+
type ExtractValueType<C> = C extends BaseChannel ? C["ValueType"] : C extends () => BaseChannel ? ReturnType<C>["ValueType"] : never;
|
|
19
|
+
type ExtractUpdateType<C> = C extends BaseChannel ? C["UpdateType"] : C extends () => BaseChannel ? ReturnType<C>["UpdateType"] : never;
|
|
20
|
+
export type StateType<SD extends StateDefinition> = {
|
|
21
|
+
[key in keyof SD]: ExtractValueType<SD[key]>;
|
|
22
|
+
};
|
|
23
|
+
export type UpdateType<SD extends StateDefinition> = {
|
|
24
|
+
[key in keyof SD]?: ExtractUpdateType<SD[key]>;
|
|
25
|
+
};
|
|
26
|
+
export type NodeType<SD extends StateDefinition> = RunnableLike<StateType<SD>, UpdateType<SD>>;
|
|
27
|
+
export declare class AnnotationRoot<SD extends StateDefinition> {
|
|
28
|
+
lc_graph_name: string;
|
|
29
|
+
State: StateType<SD>;
|
|
30
|
+
Update: UpdateType<SD>;
|
|
31
|
+
Node: NodeType<SD>;
|
|
32
|
+
spec: SD;
|
|
33
|
+
constructor(s: SD);
|
|
34
|
+
}
|
|
35
|
+
export declare function Annotation<ValueType>(): LastValue<ValueType>;
|
|
36
|
+
export declare function Annotation<ValueType, UpdateType = ValueType>(annotation: SingleReducer<ValueType, UpdateType>): BinaryOperatorAggregate<ValueType, UpdateType>;
|
|
37
|
+
export declare namespace Annotation {
|
|
38
|
+
var Root: <S extends StateDefinition>(sd: S) => AnnotationRoot<S>;
|
|
39
|
+
}
|
|
40
|
+
export declare function getChannel<V, U = V>(reducer: SingleReducer<V, U>): BaseChannel<V, U>;
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { BinaryOperatorAggregate } from "../channels/binop.js";
|
|
2
|
+
import { LastValue } from "../channels/last_value.js";
|
|
3
|
+
export class AnnotationRoot {
|
|
4
|
+
constructor(s) {
|
|
5
|
+
Object.defineProperty(this, "lc_graph_name", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: "AnnotationRoot"
|
|
10
|
+
});
|
|
11
|
+
Object.defineProperty(this, "spec", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
writable: true,
|
|
15
|
+
value: void 0
|
|
16
|
+
});
|
|
17
|
+
this.spec = s;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function Annotation(annotation) {
|
|
21
|
+
if (annotation) {
|
|
22
|
+
return getChannel(annotation);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
// @ts-expect-error - Annotation without reducer
|
|
26
|
+
return new LastValue();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
Annotation.Root = (sd) => new AnnotationRoot(sd);
|
|
30
|
+
export function getChannel(reducer) {
|
|
31
|
+
if (typeof reducer === "object" &&
|
|
32
|
+
reducer &&
|
|
33
|
+
"reducer" in reducer &&
|
|
34
|
+
reducer.reducer) {
|
|
35
|
+
return new BinaryOperatorAggregate(reducer.reducer, reducer.default);
|
|
36
|
+
}
|
|
37
|
+
if (typeof reducer === "object" &&
|
|
38
|
+
reducer &&
|
|
39
|
+
"value" in reducer &&
|
|
40
|
+
reducer.value) {
|
|
41
|
+
return new BinaryOperatorAggregate(reducer.value, reducer.default);
|
|
42
|
+
}
|
|
43
|
+
// @ts-expect-error - Annotation without reducer
|
|
44
|
+
return new LastValue();
|
|
45
|
+
}
|
package/dist/graph/graph.cjs
CHANGED
|
@@ -11,6 +11,7 @@ const ephemeral_value_js_1 = require("../channels/ephemeral_value.cjs");
|
|
|
11
11
|
const write_js_1 = require("../pregel/write.cjs");
|
|
12
12
|
const constants_js_1 = require("../constants.cjs");
|
|
13
13
|
const utils_js_1 = require("../utils.cjs");
|
|
14
|
+
const errors_js_1 = require("../errors.cjs");
|
|
14
15
|
exports.START = "__start__";
|
|
15
16
|
exports.END = "__end__";
|
|
16
17
|
class Branch {
|
|
@@ -47,7 +48,8 @@ class Branch {
|
|
|
47
48
|
}
|
|
48
49
|
let destinations;
|
|
49
50
|
if (this.ends) {
|
|
50
|
-
destinations =
|
|
51
|
+
// destinations = [r if isinstance(r, Send) else self.ends[r] for r in result]
|
|
52
|
+
destinations = result.map((r) => ((0, constants_js_1._isSend)(r) ? r : this.ends[r]));
|
|
51
53
|
}
|
|
52
54
|
else {
|
|
53
55
|
destinations = result;
|
|
@@ -55,6 +57,9 @@ class Branch {
|
|
|
55
57
|
if (destinations.some((dest) => !dest)) {
|
|
56
58
|
throw new Error("Branch condition returned unknown or null destination");
|
|
57
59
|
}
|
|
60
|
+
if (destinations.filter(constants_js_1._isSend).some((packet) => packet.node === exports.END)) {
|
|
61
|
+
throw new errors_js_1.InvalidUpdateError("Cannot send a packet to the END node");
|
|
62
|
+
}
|
|
58
63
|
return writer(destinations);
|
|
59
64
|
}
|
|
60
65
|
}
|
|
@@ -117,7 +122,9 @@ class Graph {
|
|
|
117
122
|
if (key === exports.END) {
|
|
118
123
|
throw new Error(`Node \`${key}\` is reserved.`);
|
|
119
124
|
}
|
|
120
|
-
this.nodes[key] = (0, runnables_1._coerceToRunnable)(
|
|
125
|
+
this.nodes[key] = (0, runnables_1._coerceToRunnable)(
|
|
126
|
+
// Account for arbitrary state due to Send API
|
|
127
|
+
action);
|
|
121
128
|
return this;
|
|
122
129
|
}
|
|
123
130
|
addEdge(startKey, endKey) {
|
|
@@ -301,8 +308,16 @@ class CompiledGraph extends index_js_1.Pregel {
|
|
|
301
308
|
}
|
|
302
309
|
// attach branch writer
|
|
303
310
|
this.nodes[start].pipe(branch.compile((dests) => {
|
|
304
|
-
const
|
|
305
|
-
|
|
311
|
+
const writes = dests.map((dest) => {
|
|
312
|
+
if ((0, constants_js_1._isSend)(dest)) {
|
|
313
|
+
return dest;
|
|
314
|
+
}
|
|
315
|
+
return {
|
|
316
|
+
channel: dest === exports.END ? exports.END : `branch:${start}:${name}:${dest}`,
|
|
317
|
+
value: write_js_1.PASSTHROUGH,
|
|
318
|
+
};
|
|
319
|
+
});
|
|
320
|
+
return new write_js_1.ChannelWrite(writes, [constants_js_1.TAG_HIDDEN]);
|
|
306
321
|
}));
|
|
307
322
|
// attach branch readers
|
|
308
323
|
const ends = branch.ends
|
package/dist/graph/graph.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { Pregel, PregelInterface } from "../pregel/index.js";
|
|
|
5
5
|
import { BaseCheckpointSaver } from "../checkpoint/base.js";
|
|
6
6
|
import { BaseChannel } from "../channels/base.js";
|
|
7
7
|
import { All } from "../pregel/types.js";
|
|
8
|
+
import { Send } from "../constants.js";
|
|
8
9
|
import { RunnableCallable } from "../utils.js";
|
|
9
10
|
export declare const START = "__start__";
|
|
10
11
|
export declare const END = "__end__";
|
|
@@ -14,11 +15,11 @@ export interface BranchOptions<IO, N extends string> {
|
|
|
14
15
|
pathMap?: Record<string, N | typeof END> | N[];
|
|
15
16
|
}
|
|
16
17
|
export declare class Branch<IO, N extends string> {
|
|
17
|
-
condition: (input: IO, config?: RunnableConfig) => string | string[] | Promise<string
|
|
18
|
+
condition: (input: IO, config?: RunnableConfig) => string | Send | (string | Send)[] | Promise<string | Send | (string | Send)[]>;
|
|
18
19
|
ends?: Record<string, N | typeof END>;
|
|
19
20
|
constructor(options: Omit<BranchOptions<IO, N>, "source">);
|
|
20
|
-
compile(writer: (dests: string[]) => Runnable | undefined, reader?: (config: RunnableConfig) => IO): RunnableCallable<unknown, unknown>;
|
|
21
|
-
_route(input: IO, config: RunnableConfig, writer: (dests: string[]) => Runnable | undefined, reader?: (config: RunnableConfig) => IO): Promise<Runnable | undefined>;
|
|
21
|
+
compile(writer: (dests: (string | Send)[]) => Runnable | undefined, reader?: (config: RunnableConfig) => IO): RunnableCallable<unknown, unknown>;
|
|
22
|
+
_route(input: IO, config: RunnableConfig, writer: (dests: (string | Send)[]) => Runnable | undefined, reader?: (config: RunnableConfig) => IO): Promise<Runnable | undefined>;
|
|
22
23
|
}
|
|
23
24
|
export declare class Graph<N extends string = typeof END, RunInput = any, RunOutput = any> {
|
|
24
25
|
nodes: Record<N, Runnable<RunInput, RunOutput>>;
|
|
@@ -30,7 +31,7 @@ export declare class Graph<N extends string = typeof END, RunInput = any, RunOut
|
|
|
30
31
|
constructor();
|
|
31
32
|
private warnIfCompiled;
|
|
32
33
|
get allEdges(): Set<[string, string]>;
|
|
33
|
-
addNode<K extends string>(key: K, action: RunnableLike<
|
|
34
|
+
addNode<K extends string, NodeInput = RunInput>(key: K, action: RunnableLike<NodeInput, RunOutput>): Graph<N | K, RunInput, RunOutput>;
|
|
34
35
|
addEdge(startKey: N | typeof START, endKey: N | typeof END): this;
|
|
35
36
|
addConditionalEdges(source: BranchOptions<RunInput, N>): this;
|
|
36
37
|
addConditionalEdges(source: N, path: Branch<RunInput, N>["condition"], pathMap?: BranchOptions<RunInput, N>["pathMap"]): this;
|
package/dist/graph/graph.js
CHANGED
|
@@ -6,8 +6,9 @@ import { PregelNode } from "../pregel/read.js";
|
|
|
6
6
|
import { Channel, Pregel } from "../pregel/index.js";
|
|
7
7
|
import { EphemeralValue } from "../channels/ephemeral_value.js";
|
|
8
8
|
import { ChannelWrite, PASSTHROUGH } from "../pregel/write.js";
|
|
9
|
-
import { TAG_HIDDEN } from "../constants.js";
|
|
9
|
+
import { _isSend, TAG_HIDDEN } from "../constants.js";
|
|
10
10
|
import { RunnableCallable } from "../utils.js";
|
|
11
|
+
import { InvalidUpdateError } from "../errors.js";
|
|
11
12
|
export const START = "__start__";
|
|
12
13
|
export const END = "__end__";
|
|
13
14
|
export class Branch {
|
|
@@ -44,7 +45,8 @@ export class Branch {
|
|
|
44
45
|
}
|
|
45
46
|
let destinations;
|
|
46
47
|
if (this.ends) {
|
|
47
|
-
destinations =
|
|
48
|
+
// destinations = [r if isinstance(r, Send) else self.ends[r] for r in result]
|
|
49
|
+
destinations = result.map((r) => (_isSend(r) ? r : this.ends[r]));
|
|
48
50
|
}
|
|
49
51
|
else {
|
|
50
52
|
destinations = result;
|
|
@@ -52,6 +54,9 @@ export class Branch {
|
|
|
52
54
|
if (destinations.some((dest) => !dest)) {
|
|
53
55
|
throw new Error("Branch condition returned unknown or null destination");
|
|
54
56
|
}
|
|
57
|
+
if (destinations.filter(_isSend).some((packet) => packet.node === END)) {
|
|
58
|
+
throw new InvalidUpdateError("Cannot send a packet to the END node");
|
|
59
|
+
}
|
|
55
60
|
return writer(destinations);
|
|
56
61
|
}
|
|
57
62
|
}
|
|
@@ -113,7 +118,9 @@ export class Graph {
|
|
|
113
118
|
if (key === END) {
|
|
114
119
|
throw new Error(`Node \`${key}\` is reserved.`);
|
|
115
120
|
}
|
|
116
|
-
this.nodes[key] = _coerceToRunnable(
|
|
121
|
+
this.nodes[key] = _coerceToRunnable(
|
|
122
|
+
// Account for arbitrary state due to Send API
|
|
123
|
+
action);
|
|
117
124
|
return this;
|
|
118
125
|
}
|
|
119
126
|
addEdge(startKey, endKey) {
|
|
@@ -296,8 +303,16 @@ export class CompiledGraph extends Pregel {
|
|
|
296
303
|
}
|
|
297
304
|
// attach branch writer
|
|
298
305
|
this.nodes[start].pipe(branch.compile((dests) => {
|
|
299
|
-
const
|
|
300
|
-
|
|
306
|
+
const writes = dests.map((dest) => {
|
|
307
|
+
if (_isSend(dest)) {
|
|
308
|
+
return dest;
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
channel: dest === END ? END : `branch:${start}:${name}:${dest}`,
|
|
312
|
+
value: PASSTHROUGH,
|
|
313
|
+
};
|
|
314
|
+
});
|
|
315
|
+
return new ChannelWrite(writes, [TAG_HIDDEN]);
|
|
301
316
|
}));
|
|
302
317
|
// attach branch readers
|
|
303
318
|
const ends = branch.ends
|
package/dist/graph/index.cjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.messagesStateReducer = exports.MessageGraph = exports.StateGraph = exports.Graph = exports.START = exports.END = void 0;
|
|
3
|
+
exports.messagesStateReducer = exports.MessageGraph = exports.StateGraph = exports.Graph = exports.START = exports.END = exports.Annotation = void 0;
|
|
4
|
+
var annotation_js_1 = require("./annotation.cjs");
|
|
5
|
+
Object.defineProperty(exports, "Annotation", { enumerable: true, get: function () { return annotation_js_1.Annotation; } });
|
|
4
6
|
var graph_js_1 = require("./graph.cjs");
|
|
5
7
|
Object.defineProperty(exports, "END", { enumerable: true, get: function () { return graph_js_1.END; } });
|
|
6
8
|
Object.defineProperty(exports, "START", { enumerable: true, get: function () { return graph_js_1.START; } });
|
package/dist/graph/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { Annotation, type StateType, type UpdateType } from "./annotation.js";
|
|
1
2
|
export { END, START, Graph } from "./graph.js";
|
|
2
3
|
export { type StateGraphArgs, StateGraph, type CompiledStateGraph, } from "./state.js";
|
|
3
4
|
export { MessageGraph, messagesStateReducer } from "./message.js";
|
package/dist/graph/index.js
CHANGED
package/dist/graph/message.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseMessage, BaseMessageLike } from "@langchain/core/messages";
|
|
2
2
|
import { StateGraph } from "./state.js";
|
|
3
3
|
type Messages = Array<BaseMessage | BaseMessageLike> | BaseMessage | BaseMessageLike;
|
|
4
|
-
export declare function messagesStateReducer(left:
|
|
4
|
+
export declare function messagesStateReducer(left: BaseMessage[], right: Messages): BaseMessage[];
|
|
5
5
|
export declare class MessageGraph extends StateGraph<BaseMessage[], BaseMessage[], Messages> {
|
|
6
6
|
constructor();
|
|
7
7
|
}
|