@langchain/langgraph 0.0.11 → 0.0.13

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.
Files changed (134) hide show
  1. package/dist/channels/any_value.cjs +57 -0
  2. package/dist/channels/any_value.d.ts +16 -0
  3. package/dist/channels/any_value.js +53 -0
  4. package/dist/channels/base.cjs +19 -28
  5. package/dist/channels/base.d.ts +13 -19
  6. package/dist/channels/base.js +17 -24
  7. package/dist/channels/binop.cjs +4 -3
  8. package/dist/channels/binop.d.ts +1 -1
  9. package/dist/channels/binop.js +3 -2
  10. package/dist/channels/dynamic_barrier_value.cjs +88 -0
  11. package/dist/channels/dynamic_barrier_value.d.ts +26 -0
  12. package/dist/channels/dynamic_barrier_value.js +84 -0
  13. package/dist/channels/ephemeral_value.cjs +64 -0
  14. package/dist/channels/ephemeral_value.d.ts +14 -0
  15. package/dist/channels/ephemeral_value.js +60 -0
  16. package/dist/channels/index.cjs +1 -3
  17. package/dist/channels/index.d.ts +1 -1
  18. package/dist/channels/index.js +1 -1
  19. package/dist/channels/last_value.cjs +11 -5
  20. package/dist/channels/last_value.d.ts +5 -1
  21. package/dist/channels/last_value.js +9 -3
  22. package/dist/channels/named_barrier_value.cjs +71 -0
  23. package/dist/channels/named_barrier_value.d.ts +18 -0
  24. package/dist/channels/named_barrier_value.js +66 -0
  25. package/dist/channels/topic.cjs +5 -3
  26. package/dist/channels/topic.d.ts +3 -3
  27. package/dist/channels/topic.js +5 -3
  28. package/dist/checkpoint/base.cjs +30 -12
  29. package/dist/checkpoint/base.d.ts +39 -22
  30. package/dist/checkpoint/base.js +28 -11
  31. package/dist/checkpoint/id.cjs +40 -0
  32. package/dist/checkpoint/id.d.ts +2 -0
  33. package/dist/checkpoint/id.js +35 -0
  34. package/dist/checkpoint/index.cjs +2 -2
  35. package/dist/checkpoint/index.d.ts +2 -2
  36. package/dist/checkpoint/index.js +2 -2
  37. package/dist/checkpoint/memory.cjs +63 -49
  38. package/dist/checkpoint/memory.d.ts +7 -10
  39. package/dist/checkpoint/memory.js +62 -47
  40. package/dist/checkpoint/sqlite.cjs +170 -0
  41. package/dist/checkpoint/sqlite.d.ts +14 -0
  42. package/dist/checkpoint/sqlite.js +163 -0
  43. package/dist/constants.cjs +3 -1
  44. package/dist/constants.d.ts +2 -0
  45. package/dist/constants.js +2 -0
  46. package/dist/errors.cjs +31 -0
  47. package/dist/errors.d.ts +12 -0
  48. package/dist/errors.js +24 -0
  49. package/dist/graph/graph.cjs +234 -96
  50. package/dist/graph/graph.d.ts +52 -23
  51. package/dist/graph/graph.js +233 -97
  52. package/dist/graph/index.cjs +2 -2
  53. package/dist/graph/index.d.ts +2 -2
  54. package/dist/graph/index.js +2 -2
  55. package/dist/graph/message.cjs +4 -3
  56. package/dist/graph/message.d.ts +4 -1
  57. package/dist/graph/message.js +4 -3
  58. package/dist/graph/state.cjs +237 -102
  59. package/dist/graph/state.d.ts +41 -18
  60. package/dist/graph/state.js +238 -104
  61. package/dist/index.cjs +6 -2
  62. package/dist/index.d.ts +3 -2
  63. package/dist/index.js +2 -1
  64. package/dist/prebuilt/agent_executor.cjs +22 -36
  65. package/dist/prebuilt/agent_executor.d.ts +7 -10
  66. package/dist/prebuilt/agent_executor.js +23 -37
  67. package/dist/prebuilt/chat_agent_executor.cjs +13 -13
  68. package/dist/prebuilt/chat_agent_executor.d.ts +3 -1
  69. package/dist/prebuilt/chat_agent_executor.js +15 -15
  70. package/dist/prebuilt/index.cjs +4 -1
  71. package/dist/prebuilt/index.d.ts +1 -0
  72. package/dist/prebuilt/index.js +1 -0
  73. package/dist/prebuilt/tool_node.cjs +59 -0
  74. package/dist/prebuilt/tool_node.d.ts +17 -0
  75. package/dist/prebuilt/tool_node.js +54 -0
  76. package/dist/pregel/debug.cjs +6 -8
  77. package/dist/pregel/debug.d.ts +2 -2
  78. package/dist/pregel/debug.js +5 -7
  79. package/dist/pregel/index.cjs +406 -236
  80. package/dist/pregel/index.d.ts +77 -41
  81. package/dist/pregel/index.js +408 -241
  82. package/dist/pregel/io.cjs +117 -30
  83. package/dist/pregel/io.d.ts +11 -3
  84. package/dist/pregel/io.js +111 -28
  85. package/dist/pregel/read.cjs +126 -46
  86. package/dist/pregel/read.d.ts +27 -18
  87. package/dist/pregel/read.js +125 -45
  88. package/dist/pregel/types.cjs +2 -0
  89. package/dist/pregel/types.d.ts +32 -0
  90. package/dist/pregel/types.js +1 -0
  91. package/dist/pregel/validate.cjs +58 -51
  92. package/dist/pregel/validate.d.ts +14 -13
  93. package/dist/pregel/validate.js +56 -50
  94. package/dist/pregel/write.cjs +46 -30
  95. package/dist/pregel/write.d.ts +18 -8
  96. package/dist/pregel/write.js +45 -29
  97. package/dist/serde/base.cjs +2 -0
  98. package/dist/serde/base.d.ts +4 -0
  99. package/dist/serde/base.js +1 -0
  100. package/dist/setup/async_local_storage.cjs +2 -2
  101. package/dist/setup/async_local_storage.js +1 -1
  102. package/dist/tests/channels.test.d.ts +1 -0
  103. package/dist/tests/channels.test.js +151 -0
  104. package/dist/tests/chatbot.int.test.d.ts +1 -0
  105. package/dist/tests/chatbot.int.test.js +61 -0
  106. package/dist/tests/checkpoints.test.d.ts +1 -0
  107. package/dist/tests/checkpoints.test.js +190 -0
  108. package/dist/tests/graph.test.d.ts +1 -0
  109. package/dist/tests/graph.test.js +15 -0
  110. package/dist/tests/prebuilt.int.test.d.ts +1 -0
  111. package/dist/tests/prebuilt.int.test.js +101 -0
  112. package/dist/tests/prebuilt.test.d.ts +1 -0
  113. package/dist/tests/prebuilt.test.js +195 -0
  114. package/dist/tests/pregel.io.test.d.ts +1 -0
  115. package/dist/tests/pregel.io.test.js +332 -0
  116. package/dist/tests/pregel.read.test.d.ts +1 -0
  117. package/dist/tests/pregel.read.test.js +109 -0
  118. package/dist/tests/pregel.test.d.ts +1 -0
  119. package/dist/tests/pregel.test.js +1879 -0
  120. package/dist/tests/pregel.validate.test.d.ts +1 -0
  121. package/dist/tests/pregel.validate.test.js +198 -0
  122. package/dist/tests/pregel.write.test.d.ts +1 -0
  123. package/dist/tests/pregel.write.test.js +44 -0
  124. package/dist/tests/tracing.int.test.d.ts +1 -0
  125. package/dist/tests/tracing.int.test.js +449 -0
  126. package/dist/tests/utils.d.ts +22 -0
  127. package/dist/tests/utils.js +76 -0
  128. package/dist/utils.cjs +74 -0
  129. package/dist/utils.d.ts +18 -0
  130. package/dist/utils.js +70 -0
  131. package/package.json +12 -8
  132. package/dist/pregel/reserved.cjs +0 -6
  133. package/dist/pregel/reserved.d.ts +0 -3
  134. package/dist/pregel/reserved.js +0 -3
@@ -1,32 +1,61 @@
1
1
  import { Runnable, RunnableConfig, RunnableLike } from "@langchain/core/runnables";
2
- import { Pregel } from "../pregel/index.js";
2
+ import { PregelNode } from "../pregel/read.js";
3
+ import { Pregel, PregelInterface } from "../pregel/index.js";
3
4
  import { BaseCheckpointSaver } from "../checkpoint/base.js";
5
+ import { BaseChannel } from "../channels/base.js";
6
+ import { All } from "../pregel/types.js";
7
+ import { RunnableCallable } from "../utils.js";
8
+ export declare const START = "__start__";
4
9
  export declare const END = "__end__";
5
- type EndsMap = {
6
- [result: string]: string;
7
- };
8
- declare class Branch {
9
- condition: CallableFunction;
10
- ends?: EndsMap;
11
- constructor(condition: CallableFunction, ends?: EndsMap);
12
- runnable(input: any, options?: {
13
- config?: RunnableConfig;
14
- }): Runnable;
10
+ export interface BranchOptions<IO, N extends string> {
11
+ source: N;
12
+ path: Branch<IO, N>["condition"];
13
+ pathMap?: Record<string, N | typeof END> | N[];
14
+ then?: N | typeof END;
15
15
  }
16
- export declare class Graph<RunInput = any, RunOutput = any> {
17
- nodes: Record<string, Runnable<RunInput, RunOutput>>;
18
- edges: Set<[string, string]>;
19
- branches: Record<string, Branch[]>;
16
+ export declare class Branch<IO, N extends string> {
17
+ condition: (input: IO, config?: RunnableConfig) => string | string[] | Promise<string> | Promise<string[]>;
18
+ ends?: Record<string, N | typeof END>;
19
+ then?: BranchOptions<IO, N>["then"];
20
+ constructor(options: Omit<BranchOptions<IO, N>, "source">);
21
+ compile(writer: (dests: string[]) => Runnable | undefined, reader?: (config: RunnableConfig) => IO): RunnableCallable<unknown, unknown>;
22
+ _route(input: IO, config: RunnableConfig, writer: (dests: string[]) => Runnable | undefined, reader?: (config: RunnableConfig) => IO): Promise<Runnable | undefined>;
23
+ }
24
+ export declare class Graph<const N extends string = typeof END, RunInput = any, RunOutput = any> {
25
+ nodes: Record<N, Runnable<RunInput, RunOutput>>;
26
+ edges: Set<[N | typeof START, N | typeof END]>;
27
+ branches: Record<string, Record<string, Branch<RunInput, N>>>;
20
28
  entryPoint?: string;
21
29
  compiled: boolean;
30
+ supportMultipleEdges: boolean;
22
31
  constructor();
23
32
  private warnIfCompiled;
24
- addNode(key: string, action: RunnableLike<RunInput, RunOutput>): void;
25
- addEdge(startKey: string, endKey: string): void;
26
- addConditionalEdges(startKey: string, condition: CallableFunction, conditionalEdgeMapping?: Record<string, string>): void;
27
- setEntryPoint(key: string): void;
28
- setFinishPoint(key: string): void;
29
- compile(checkpointer?: BaseCheckpointSaver): Pregel;
30
- validate(): void;
33
+ get allEdges(): Set<[string, string]>;
34
+ addNode<K extends string>(key: K, action: RunnableLike<RunInput, RunOutput>): Graph<N | K, RunInput, RunOutput>;
35
+ addEdge(startKey: N | typeof START, endKey: N | typeof END): this;
36
+ addConditionalEdges(source: BranchOptions<RunInput, N>): this;
37
+ addConditionalEdges(source: N, path: Branch<RunInput, N>["condition"], pathMap?: BranchOptions<RunInput, N>["pathMap"]): this;
38
+ /**
39
+ * @deprecated use `addEdge(START, key)` instead
40
+ */
41
+ setEntryPoint(key: N): this;
42
+ /**
43
+ * @deprecated use `addEdge(key, END)` instead
44
+ */
45
+ setFinishPoint(key: N): this;
46
+ compile({ checkpointer, interruptBefore, interruptAfter, }?: {
47
+ checkpointer?: BaseCheckpointSaver;
48
+ interruptBefore?: N[] | All;
49
+ interruptAfter?: N[] | All;
50
+ }): CompiledGraph<N>;
51
+ validate(interrupt?: string[]): void;
52
+ }
53
+ export declare class CompiledGraph<N extends string, RunInput = any, RunOutput = any> extends Pregel<Record<N | typeof START, PregelNode<RunInput, RunOutput>>, Record<N | typeof START | typeof END | string, BaseChannel>> {
54
+ builder: Graph<N, RunInput, RunOutput>;
55
+ constructor({ builder, ...rest }: {
56
+ builder: Graph<N, RunInput, RunOutput>;
57
+ } & PregelInterface<Record<N | typeof START, PregelNode<RunInput, RunOutput>>, Record<N | typeof START | typeof END | string, BaseChannel>>);
58
+ attachNode(key: N, node: Runnable<RunInput, RunOutput>): void;
59
+ attachEdge(start: N | typeof START, end: N | typeof END): void;
60
+ attachBranch(start: N | typeof START, name: string, branch: Branch<RunInput, N>): void;
31
61
  }
32
- export {};
@@ -1,8 +1,15 @@
1
- import { RunnableLambda, _coerceToRunnable, } from "@langchain/core/runnables";
1
+ /* eslint-disable @typescript-eslint/no-use-before-define */
2
+ import { _coerceToRunnable, } from "@langchain/core/runnables";
3
+ import { PregelNode } from "../pregel/read.js";
2
4
  import { Channel, Pregel } from "../pregel/index.js";
5
+ import { EphemeralValue } from "../channels/ephemeral_value.js";
6
+ import { ChannelWrite, PASSTHROUGH } from "../pregel/write.js";
7
+ import { TAG_HIDDEN } from "../constants.js";
8
+ import { RunnableCallable } from "../utils.js";
9
+ export const START = "__start__";
3
10
  export const END = "__end__";
4
- class Branch {
5
- constructor(condition, ends) {
11
+ export class Branch {
12
+ constructor(options) {
6
13
  Object.defineProperty(this, "condition", {
7
14
  enumerable: true,
8
15
  configurable: true,
@@ -15,20 +22,39 @@ class Branch {
15
22
  writable: true,
16
23
  value: void 0
17
24
  });
18
- this.condition = condition;
19
- this.ends = ends;
25
+ Object.defineProperty(this, "then", {
26
+ enumerable: true,
27
+ configurable: true,
28
+ writable: true,
29
+ value: void 0
30
+ });
31
+ this.condition = options.path;
32
+ this.ends = Array.isArray(options.pathMap)
33
+ ? options.pathMap.reduce((acc, n) => {
34
+ acc[n] = n;
35
+ return acc;
36
+ }, {})
37
+ : options.pathMap;
38
+ this.then = options.then;
39
+ }
40
+ compile(writer, reader) {
41
+ return ChannelWrite.registerWriter(new RunnableCallable({
42
+ func: (input, config) => this._route(input, config, writer, reader),
43
+ }));
20
44
  }
21
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
- runnable(input, options) {
23
- const result = this.condition(input, options?.config);
24
- let destination;
45
+ async _route(input, config, writer, reader) {
46
+ let result = await this.condition(reader ? reader(config) : input, config);
47
+ if (!Array.isArray(result)) {
48
+ result = [result];
49
+ }
50
+ let destinations;
25
51
  if (this.ends) {
26
- destination = this.ends[result];
52
+ destinations = result.map((r) => this.ends[r]);
27
53
  }
28
54
  else {
29
- destination = result;
55
+ destinations = result;
30
56
  }
31
- return Channel.writeTo(destination !== END ? `${destination}:inbox` : END);
57
+ return writer(destinations);
32
58
  }
33
59
  }
34
60
  export class Graph {
@@ -63,6 +89,12 @@ export class Graph {
63
89
  writable: true,
64
90
  value: false
65
91
  });
92
+ Object.defineProperty(this, "supportMultipleEdges", {
93
+ enumerable: true,
94
+ configurable: true,
95
+ writable: true,
96
+ value: false
97
+ });
66
98
  this.nodes = {};
67
99
  this.edges = new Set();
68
100
  this.branches = {};
@@ -72,132 +104,236 @@ export class Graph {
72
104
  console.warn(message);
73
105
  }
74
106
  }
107
+ get allEdges() {
108
+ return this.edges;
109
+ }
75
110
  addNode(key, action) {
76
111
  this.warnIfCompiled(`Adding a node to a graph that has already been compiled. This will not be reflected in the compiled graph.`);
77
- if (this.nodes[key]) {
112
+ if (key in this.nodes) {
78
113
  throw new Error(`Node \`${key}\` already present.`);
79
114
  }
80
115
  if (key === END) {
81
116
  throw new Error(`Node \`${key}\` is reserved.`);
82
117
  }
83
118
  this.nodes[key] = _coerceToRunnable(action);
119
+ return this;
84
120
  }
85
121
  addEdge(startKey, endKey) {
86
122
  this.warnIfCompiled(`Adding an edge to a graph that has already been compiled. This will not be reflected in the compiled graph.`);
87
123
  if (startKey === END) {
88
124
  throw new Error("END cannot be a start node");
89
125
  }
90
- if (!this.nodes[startKey]) {
91
- throw new Error(`Need to addNode \`${startKey}\` first`);
92
- }
93
- if (!this.nodes[endKey] && endKey !== END) {
94
- throw new Error(`Need to addNode \`${endKey}\` first`);
126
+ if (endKey === START) {
127
+ throw new Error("START cannot be an end node");
95
128
  }
96
- // TODO: support multiple message passing
97
- if (Array.from(this.edges).some(([start]) => start === startKey)) {
129
+ if (!this.supportMultipleEdges &&
130
+ Array.from(this.edges).some(([start]) => start === startKey)) {
98
131
  throw new Error(`Already found path for ${startKey}`);
99
132
  }
100
133
  this.edges.add([startKey, endKey]);
134
+ return this;
101
135
  }
102
- addConditionalEdges(startKey, condition, conditionalEdgeMapping) {
136
+ addConditionalEdges(source, path, pathMap) {
137
+ const options = typeof source === "object" ? source : { source, path: path, pathMap };
103
138
  this.warnIfCompiled("Adding an edge to a graph that has already been compiled. This will not be reflected in the compiled graph.");
104
- if (!this.nodes[startKey]) {
105
- throw new Error(`Need to addNode \`${startKey}\` first`);
106
- }
107
- if (condition.constructor.name === "AsyncFunction") {
108
- throw new Error("Condition cannot be an async function");
109
- }
110
- if (conditionalEdgeMapping) {
111
- const mappingValues = Array.from(Object.values(conditionalEdgeMapping));
112
- const nodesValues = Object.keys(this.nodes);
113
- const endExcluded = mappingValues.filter((value) => value !== END);
114
- const difference = endExcluded.filter((value) => !nodesValues.some((nv) => nv === value));
115
- if (difference.length > 0) {
116
- throw new Error(`Missing nodes which are in conditional edge mapping.\nMapping contains possible destinations: ${mappingValues.join(", ")}.\nPossible nodes are ${nodesValues.join(", ")}.`);
117
- }
139
+ // find a name for condition
140
+ const name = options.path.name || "condition";
141
+ // validate condition
142
+ if (this.branches[options.source] && this.branches[options.source][name]) {
143
+ throw new Error(`Condition \`${name}\` already present for node \`${source}\``);
118
144
  }
119
- if (!this.branches[startKey]) {
120
- this.branches[startKey] = [];
145
+ // save it
146
+ if (!this.branches[options.source]) {
147
+ this.branches[options.source] = {};
121
148
  }
122
- this.branches[startKey].push(new Branch(condition, conditionalEdgeMapping));
149
+ this.branches[options.source][name] = new Branch(options);
150
+ return this;
123
151
  }
152
+ /**
153
+ * @deprecated use `addEdge(START, key)` instead
154
+ */
124
155
  setEntryPoint(key) {
125
156
  this.warnIfCompiled("Setting the entry point of a graph that has already been compiled. This will not be reflected in the compiled graph.");
126
- if (!this.nodes[key]) {
127
- throw new Error(`Need to addNode \`${key}\` first`);
128
- }
129
- this.entryPoint = key;
157
+ return this.addEdge(START, key);
130
158
  }
159
+ /**
160
+ * @deprecated use `addEdge(key, END)` instead
161
+ */
131
162
  setFinishPoint(key) {
132
163
  this.warnIfCompiled("Setting a finish point of a graph that has already been compiled. This will not be reflected in the compiled graph.");
133
- this.addEdge(key, END);
134
- }
135
- compile(checkpointer) {
136
- this.validate();
137
- const outgoingEdges = {};
138
- this.edges.forEach(([start, end]) => {
139
- if (!outgoingEdges[start]) {
140
- outgoingEdges[start] = [];
141
- }
142
- outgoingEdges[start].push(end !== END ? `${end}:inbox` : END);
164
+ return this.addEdge(key, END);
165
+ }
166
+ compile({ checkpointer, interruptBefore, interruptAfter, } = {}) {
167
+ // validate the graph
168
+ this.validate([
169
+ ...(Array.isArray(interruptBefore) ? interruptBefore : []),
170
+ ...(Array.isArray(interruptAfter) ? interruptAfter : []),
171
+ ]);
172
+ // create empty compiled graph
173
+ const compiled = new CompiledGraph({
174
+ builder: this,
175
+ checkpointer,
176
+ interruptAfter,
177
+ interruptBefore,
178
+ autoValidate: false,
179
+ nodes: {},
180
+ channels: {
181
+ [START]: new EphemeralValue(),
182
+ [END]: new EphemeralValue(),
183
+ },
184
+ inputs: START,
185
+ outputs: END,
186
+ streamChannels: [],
187
+ streamMode: "values",
143
188
  });
144
- const nodes = {};
189
+ // attach nodes, edges and branches
145
190
  for (const [key, node] of Object.entries(this.nodes)) {
146
- nodes[key] = Channel.subscribeTo(`${key}:inbox`)
147
- .pipe(node)
148
- .pipe(Channel.writeTo(key));
149
- }
150
- for (const key of Object.keys(this.nodes)) {
151
- const outgoing = outgoingEdges[key];
152
- const edgesKey = `${key}:edges`;
153
- if (outgoing || this.branches[key]) {
154
- nodes[edgesKey] = Channel.subscribeTo(key, {
155
- tags: ["langsmith:hidden"],
156
- });
191
+ compiled.attachNode(key, node);
192
+ }
193
+ for (const [start, end] of this.edges) {
194
+ compiled.attachEdge(start, end);
195
+ }
196
+ for (const [start, branches] of Object.entries(this.branches)) {
197
+ for (const [name, branch] of Object.entries(branches)) {
198
+ compiled.attachBranch(start, name, branch);
157
199
  }
158
- if (outgoing) {
159
- nodes[edgesKey] = nodes[edgesKey].pipe(Channel.writeTo(...outgoing));
200
+ }
201
+ return compiled.validate();
202
+ }
203
+ validate(interrupt) {
204
+ // assemble sources
205
+ const allSources = new Set([...this.allEdges].map(([src, _]) => src));
206
+ for (const [start, branches] of Object.entries(this.branches)) {
207
+ allSources.add(start);
208
+ for (const branch of Object.values(branches)) {
209
+ if (branch.then) {
210
+ if (branch.ends) {
211
+ for (const end of Object.values(branch.ends)) {
212
+ if (end !== END) {
213
+ allSources.add(end);
214
+ }
215
+ }
216
+ }
217
+ else {
218
+ for (const node of Object.keys(this.nodes)) {
219
+ if (node !== start) {
220
+ allSources.add(node);
221
+ }
222
+ }
223
+ }
224
+ }
225
+ }
226
+ }
227
+ // validate sources
228
+ for (const node of Object.keys(this.nodes)) {
229
+ if (!allSources.has(node)) {
230
+ throw new Error(`Node \`${node}\` is a dead-end`);
160
231
  }
161
- if (this.branches[key]) {
162
- this.branches[key].forEach((branch) => {
163
- const runnableLambda = new RunnableLambda({
164
- func: (input) => branch.runnable(input),
165
- });
166
- nodes[edgesKey] = nodes[edgesKey].pipe(runnableLambda);
167
- });
232
+ }
233
+ for (const source of allSources) {
234
+ if (source !== START && !(source in this.nodes)) {
235
+ throw new Error(`Found edge starting at unknown node \`${source}\``);
168
236
  }
169
237
  }
170
- const hidden = Object.keys(this.nodes).map((node) => `${node}:inbox`);
171
- if (!this.entryPoint) {
172
- throw new Error("Entry point not set");
238
+ // assemble targets
239
+ const allTargets = new Set([...this.allEdges].map(([_, target]) => target));
240
+ for (const [start, branches] of Object.entries(this.branches)) {
241
+ for (const branch of Object.values(branches)) {
242
+ if (branch.then) {
243
+ allTargets.add(branch.then);
244
+ }
245
+ if (branch.ends) {
246
+ for (const end of Object.values(branch.ends)) {
247
+ allTargets.add(end);
248
+ }
249
+ }
250
+ else {
251
+ allTargets.add(END);
252
+ for (const node of Object.keys(this.nodes)) {
253
+ if (node !== start && node !== branch.then) {
254
+ allTargets.add(node);
255
+ }
256
+ }
257
+ }
258
+ }
173
259
  }
174
- return new Pregel({
175
- nodes,
176
- input: `${this.entryPoint}:inbox`,
177
- output: END,
178
- hidden,
179
- checkpointer,
180
- });
181
- }
182
- validate() {
183
- const allStarts = new Set([...this.edges].map(([src, _]) => src).concat(Object.keys(this.branches)));
260
+ // validate targets
184
261
  for (const node of Object.keys(this.nodes)) {
185
- if (!allStarts.has(node)) {
186
- throw new Error(`Node \`${node}\` is a dead-end`);
262
+ if (!allTargets.has(node)) {
263
+ throw new Error(`Node \`${node}\` is not reachable`);
264
+ }
265
+ }
266
+ for (const target of allTargets) {
267
+ if (target !== END && !(target in this.nodes)) {
268
+ throw new Error(`Found edge ending at unknown node \`${target}\``);
187
269
  }
188
270
  }
189
- const allEndsAreDefined = Object.values(this.branches).every((branchList) => branchList.every((branch) => branch.ends));
190
- if (allEndsAreDefined) {
191
- const allEnds = new Set([...this.edges]
192
- .map(([_, end]) => end)
193
- .concat(...Object.values(this.branches).flatMap((branchList) => branchList.flatMap((branch) => Object.values(branch.ends ?? {}))))
194
- .concat(this.entryPoint ? [this.entryPoint] : []));
195
- for (const node of Object.keys(this.nodes)) {
196
- if (!allEnds.has(node)) {
197
- throw new Error(`Node \`${node}\` is not reachable`);
271
+ // validate interrupts
272
+ if (interrupt) {
273
+ for (const node of interrupt) {
274
+ if (!(node in this.nodes)) {
275
+ throw new Error(`Interrupt node \`${node}\` is not present`);
198
276
  }
199
277
  }
200
278
  }
201
279
  this.compiled = true;
202
280
  }
203
281
  }
282
+ export class CompiledGraph extends Pregel {
283
+ constructor({ builder, ...rest }) {
284
+ super(rest);
285
+ Object.defineProperty(this, "builder", {
286
+ enumerable: true,
287
+ configurable: true,
288
+ writable: true,
289
+ value: void 0
290
+ });
291
+ this.builder = builder;
292
+ }
293
+ attachNode(key, node) {
294
+ this.channels[key] = new EphemeralValue();
295
+ this.nodes[key] = new PregelNode({
296
+ channels: [],
297
+ triggers: [],
298
+ })
299
+ .pipe(node)
300
+ .pipe(new ChannelWrite([{ channel: key, value: PASSTHROUGH }], [TAG_HIDDEN]));
301
+ this.streamChannels.push(key);
302
+ }
303
+ attachEdge(start, end) {
304
+ if (end === END) {
305
+ if (start === START) {
306
+ throw new Error("Cannot have an edge from START to END");
307
+ }
308
+ this.nodes[start].writers.push(new ChannelWrite([{ channel: END, value: PASSTHROUGH }], [TAG_HIDDEN]));
309
+ }
310
+ else {
311
+ this.nodes[end].triggers.push(start);
312
+ this.nodes[end].channels.push(start);
313
+ }
314
+ }
315
+ attachBranch(start, name, branch) {
316
+ // add hidden start node
317
+ if (start === START && this.nodes[START]) {
318
+ this.nodes[START] = Channel.subscribeTo(START, { tags: [TAG_HIDDEN] });
319
+ }
320
+ // attach branch writer
321
+ this.nodes[start].pipe(branch.compile((dests) => {
322
+ const channels = dests.map((dest) => dest === END ? END : `branch:${start}:${name}:${dest}`);
323
+ return new ChannelWrite(channels.map((channel) => ({ channel, value: PASSTHROUGH })), [TAG_HIDDEN]);
324
+ }));
325
+ // attach branch readers
326
+ const ends = branch.ends
327
+ ? Object.values(branch.ends)
328
+ : Object.keys(this.nodes);
329
+ for (const end of ends) {
330
+ if (end !== END) {
331
+ const channelName = `branch:${start}:${name}:${end}`;
332
+ this.channels[channelName] =
333
+ new EphemeralValue();
334
+ this.nodes[end].triggers.push(channelName);
335
+ this.nodes[end].channels.push(channelName);
336
+ }
337
+ }
338
+ }
339
+ }
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MessageGraph = exports.StateGraph = exports.START = exports.Graph = exports.END = void 0;
3
+ exports.MessageGraph = exports.StateGraph = exports.Graph = exports.START = exports.END = void 0;
4
4
  var graph_js_1 = require("./graph.cjs");
5
5
  Object.defineProperty(exports, "END", { enumerable: true, get: function () { return graph_js_1.END; } });
6
+ Object.defineProperty(exports, "START", { enumerable: true, get: function () { return graph_js_1.START; } });
6
7
  Object.defineProperty(exports, "Graph", { enumerable: true, get: function () { return graph_js_1.Graph; } });
7
8
  var state_js_1 = require("./state.cjs");
8
- Object.defineProperty(exports, "START", { enumerable: true, get: function () { return state_js_1.START; } });
9
9
  Object.defineProperty(exports, "StateGraph", { enumerable: true, get: function () { return state_js_1.StateGraph; } });
10
10
  var message_js_1 = require("./message.cjs");
11
11
  Object.defineProperty(exports, "MessageGraph", { enumerable: true, get: function () { return message_js_1.MessageGraph; } });
@@ -1,3 +1,3 @@
1
- export { END, Graph } from "./graph.js";
2
- export { type StateGraphArgs, START, StateGraph } from "./state.js";
1
+ export { END, START, Graph } from "./graph.js";
2
+ export { type StateGraphArgs, StateGraph } from "./state.js";
3
3
  export { MessageGraph } from "./message.js";
@@ -1,3 +1,3 @@
1
- export { END, Graph } from "./graph.js";
2
- export { START, StateGraph } from "./state.js";
1
+ export { END, START, Graph } from "./graph.js";
2
+ export { StateGraph } from "./state.js";
3
3
  export { MessageGraph } from "./message.js";
@@ -11,9 +11,10 @@ class MessageGraph extends state_js_1.StateGraph {
11
11
  constructor() {
12
12
  super({
13
13
  channels: {
14
- value: (a, b) => addMessages(a, b),
15
- default: () => [],
16
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
+ __root__: {
15
+ reducer: addMessages,
16
+ default: () => [],
17
+ },
17
18
  },
18
19
  });
19
20
  }
@@ -1,7 +1,10 @@
1
1
  import { BaseMessage } from "@langchain/core/messages";
2
2
  import { StateGraph } from "./state.js";
3
3
  type Messages = Array<BaseMessage> | BaseMessage;
4
- export declare class MessageGraph<T extends Messages> extends StateGraph<T> {
4
+ export declare class MessageGraph extends StateGraph<BaseMessage[], Messages> {
5
5
  constructor();
6
6
  }
7
+ export interface MessagesState {
8
+ messages: BaseMessage[];
9
+ }
7
10
  export {};
@@ -8,9 +8,10 @@ export class MessageGraph extends StateGraph {
8
8
  constructor() {
9
9
  super({
10
10
  channels: {
11
- value: (a, b) => addMessages(a, b),
12
- default: () => [],
13
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
+ __root__: {
12
+ reducer: addMessages,
13
+ default: () => [],
14
+ },
14
15
  },
15
16
  });
16
17
  }