@langchain/langgraph 0.0.12 → 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 +235 -95
  50. package/dist/graph/graph.d.ts +52 -23
  51. package/dist/graph/graph.js +234 -96
  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 +11 -7
  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
- }): Promise<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,21 +22,39 @@ class Branch {
15
22
  writable: true,
16
23
  value: void 0
17
24
  });
18
- this.condition = condition;
19
- this.ends = ends;
20
- }
21
- async runnable(
22
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
- input, options) {
24
- const result = await this.condition(input, options?.config);
25
- let destination;
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
+ }));
44
+ }
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;
26
51
  if (this.ends) {
27
- destination = this.ends[result];
52
+ destinations = result.map((r) => this.ends[r]);
28
53
  }
29
54
  else {
30
- destination = result;
55
+ destinations = result;
31
56
  }
32
- return Channel.writeTo(destination !== END ? `${destination}:inbox` : END);
57
+ return writer(destinations);
33
58
  }
34
59
  }
35
60
  export class Graph {
@@ -64,6 +89,12 @@ export class Graph {
64
89
  writable: true,
65
90
  value: false
66
91
  });
92
+ Object.defineProperty(this, "supportMultipleEdges", {
93
+ enumerable: true,
94
+ configurable: true,
95
+ writable: true,
96
+ value: false
97
+ });
67
98
  this.nodes = {};
68
99
  this.edges = new Set();
69
100
  this.branches = {};
@@ -73,129 +104,236 @@ export class Graph {
73
104
  console.warn(message);
74
105
  }
75
106
  }
107
+ get allEdges() {
108
+ return this.edges;
109
+ }
76
110
  addNode(key, action) {
77
111
  this.warnIfCompiled(`Adding a node to a graph that has already been compiled. This will not be reflected in the compiled graph.`);
78
- if (this.nodes[key]) {
112
+ if (key in this.nodes) {
79
113
  throw new Error(`Node \`${key}\` already present.`);
80
114
  }
81
115
  if (key === END) {
82
116
  throw new Error(`Node \`${key}\` is reserved.`);
83
117
  }
84
118
  this.nodes[key] = _coerceToRunnable(action);
119
+ return this;
85
120
  }
86
121
  addEdge(startKey, endKey) {
87
122
  this.warnIfCompiled(`Adding an edge to a graph that has already been compiled. This will not be reflected in the compiled graph.`);
88
123
  if (startKey === END) {
89
124
  throw new Error("END cannot be a start node");
90
125
  }
91
- if (!this.nodes[startKey]) {
92
- throw new Error(`Need to addNode \`${startKey}\` first`);
93
- }
94
- if (!this.nodes[endKey] && endKey !== END) {
95
- throw new Error(`Need to addNode \`${endKey}\` first`);
126
+ if (endKey === START) {
127
+ throw new Error("START cannot be an end node");
96
128
  }
97
- // TODO: support multiple message passing
98
- if (Array.from(this.edges).some(([start]) => start === startKey)) {
129
+ if (!this.supportMultipleEdges &&
130
+ Array.from(this.edges).some(([start]) => start === startKey)) {
99
131
  throw new Error(`Already found path for ${startKey}`);
100
132
  }
101
133
  this.edges.add([startKey, endKey]);
134
+ return this;
102
135
  }
103
- addConditionalEdges(startKey, condition, conditionalEdgeMapping) {
136
+ addConditionalEdges(source, path, pathMap) {
137
+ const options = typeof source === "object" ? source : { source, path: path, pathMap };
104
138
  this.warnIfCompiled("Adding an edge to a graph that has already been compiled. This will not be reflected in the compiled graph.");
105
- if (!this.nodes[startKey]) {
106
- throw new Error(`Need to addNode \`${startKey}\` first`);
107
- }
108
- if (conditionalEdgeMapping) {
109
- const mappingValues = Array.from(Object.values(conditionalEdgeMapping));
110
- const nodesValues = Object.keys(this.nodes);
111
- const endExcluded = mappingValues.filter((value) => value !== END);
112
- const difference = endExcluded.filter((value) => !nodesValues.some((nv) => nv === value));
113
- if (difference.length > 0) {
114
- throw new Error(`Missing nodes which are in conditional edge mapping.\nMapping contains possible destinations: ${mappingValues.join(", ")}.\nPossible nodes are ${nodesValues.join(", ")}.`);
115
- }
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}\``);
116
144
  }
117
- if (!this.branches[startKey]) {
118
- this.branches[startKey] = [];
145
+ // save it
146
+ if (!this.branches[options.source]) {
147
+ this.branches[options.source] = {};
119
148
  }
120
- this.branches[startKey].push(new Branch(condition, conditionalEdgeMapping));
149
+ this.branches[options.source][name] = new Branch(options);
150
+ return this;
121
151
  }
152
+ /**
153
+ * @deprecated use `addEdge(START, key)` instead
154
+ */
122
155
  setEntryPoint(key) {
123
156
  this.warnIfCompiled("Setting the entry point of a graph that has already been compiled. This will not be reflected in the compiled graph.");
124
- if (!this.nodes[key]) {
125
- throw new Error(`Need to addNode \`${key}\` first`);
126
- }
127
- this.entryPoint = key;
157
+ return this.addEdge(START, key);
128
158
  }
159
+ /**
160
+ * @deprecated use `addEdge(key, END)` instead
161
+ */
129
162
  setFinishPoint(key) {
130
163
  this.warnIfCompiled("Setting a finish point of a graph that has already been compiled. This will not be reflected in the compiled graph.");
131
- this.addEdge(key, END);
132
- }
133
- compile(checkpointer) {
134
- this.validate();
135
- const outgoingEdges = {};
136
- this.edges.forEach(([start, end]) => {
137
- if (!outgoingEdges[start]) {
138
- outgoingEdges[start] = [];
139
- }
140
- 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",
141
188
  });
142
- const nodes = {};
189
+ // attach nodes, edges and branches
143
190
  for (const [key, node] of Object.entries(this.nodes)) {
144
- nodes[key] = Channel.subscribeTo(`${key}:inbox`)
145
- .pipe(node)
146
- .pipe(Channel.writeTo(key));
147
- }
148
- for (const key of Object.keys(this.nodes)) {
149
- const outgoing = outgoingEdges[key];
150
- const edgesKey = `${key}:edges`;
151
- if (outgoing || this.branches[key]) {
152
- nodes[edgesKey] = Channel.subscribeTo(key, {
153
- tags: ["langsmith:hidden"],
154
- });
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);
155
199
  }
156
- if (outgoing) {
157
- 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
+ }
158
225
  }
159
- if (this.branches[key]) {
160
- this.branches[key].forEach((branch) => {
161
- const runnableLambda = new RunnableLambda({
162
- func: (input) => branch.runnable(input),
163
- });
164
- nodes[edgesKey] = nodes[edgesKey].pipe(runnableLambda);
165
- });
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`);
166
231
  }
167
232
  }
168
- const hidden = Object.keys(this.nodes).map((node) => `${node}:inbox`);
169
- if (!this.entryPoint) {
170
- throw new Error("Entry point not set");
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}\``);
236
+ }
171
237
  }
172
- return new Pregel({
173
- nodes,
174
- input: `${this.entryPoint}:inbox`,
175
- output: END,
176
- hidden,
177
- checkpointer,
178
- });
179
- }
180
- validate() {
181
- const allStarts = new Set([...this.edges].map(([src, _]) => src).concat(Object.keys(this.branches)));
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
+ }
259
+ }
260
+ // validate targets
182
261
  for (const node of Object.keys(this.nodes)) {
183
- if (!allStarts.has(node)) {
184
- 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}\``);
185
269
  }
186
270
  }
187
- const allEndsAreDefined = Object.values(this.branches).every((branchList) => branchList.every((branch) => branch.ends));
188
- if (allEndsAreDefined) {
189
- const allEnds = new Set([...this.edges]
190
- .map(([_, end]) => end)
191
- .concat(...Object.values(this.branches).flatMap((branchList) => branchList.flatMap((branch) => Object.values(branch.ends ?? {}))))
192
- .concat(this.entryPoint ? [this.entryPoint] : []));
193
- for (const node of Object.keys(this.nodes)) {
194
- if (!allEnds.has(node)) {
195
- 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`);
196
276
  }
197
277
  }
198
278
  }
199
279
  this.compiled = true;
200
280
  }
201
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
  }