@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,11 +1,15 @@
1
- import { RunnableLambda, } from "@langchain/core/runnables";
2
1
  import { BinaryOperatorAggregate } from "../channels/binop.js";
3
- import { END, Graph } from "./graph.js";
2
+ import { END, CompiledGraph, Graph, START } from "./graph.js";
4
3
  import { LastValue } from "../channels/last_value.js";
5
- import { ChannelWrite } from "../pregel/write.js";
6
- import { Pregel, Channel } from "../pregel/index.js";
7
- import { ChannelRead } from "../pregel/read.js";
8
- export const START = "__start__";
4
+ import { ChannelWrite, PASSTHROUGH, SKIP_WRITE, } from "../pregel/write.js";
5
+ import { ChannelRead, PregelNode } from "../pregel/read.js";
6
+ import { NamedBarrierValue } from "../channels/named_barrier_value.js";
7
+ import { EphemeralValue } from "../channels/ephemeral_value.js";
8
+ import { RunnableCallable } from "../utils.js";
9
+ import { TAG_HIDDEN } from "../constants.js";
10
+ import { InvalidUpdateError } from "../errors.js";
11
+ import { DynamicBarrierValue } from "../channels/dynamic_barrier_value.js";
12
+ const ROOT = "__root__";
9
13
  export class StateGraph extends Graph {
10
14
  constructor(fields) {
11
15
  super();
@@ -15,128 +19,258 @@ export class StateGraph extends Graph {
15
19
  writable: true,
16
20
  value: void 0
17
21
  });
22
+ // TODO: this doesn't dedupe edges as in py, so worth fixing at some point
23
+ Object.defineProperty(this, "waitingEdges", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: new Set()
28
+ });
18
29
  this.channels = _getChannels(fields.channels);
30
+ for (const c of Object.values(this.channels)) {
31
+ if (c.lc_graph_name === "BinaryOperatorAggregate") {
32
+ this.supportMultipleEdges = true;
33
+ break;
34
+ }
35
+ }
36
+ }
37
+ get allEdges() {
38
+ return new Set([
39
+ ...this.edges,
40
+ ...Array.from(this.waitingEdges).flatMap(([starts, end]) => starts.map((start) => [start, end])),
41
+ ]);
19
42
  }
20
43
  addNode(key, action) {
21
- if (Object.keys(this.nodes).some((key) => key in this.channels)) {
44
+ if (key in this.channels) {
22
45
  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.`);
23
46
  }
24
- super.addNode(key, action);
47
+ return super.addNode(key, action);
25
48
  }
26
- compile(checkpointer) {
27
- this.validate();
28
- if (Object.keys(this.nodes).some((key) => key in this.channels)) {
29
- throw new Error("Cannot use channel names as node names");
49
+ addEdge(startKey, endKey) {
50
+ if (typeof startKey === "string") {
51
+ return super.addEdge(startKey, endKey);
30
52
  }
53
+ if (this.compiled) {
54
+ console.warn("Adding an edge to a graph that has already been compiled. This will " +
55
+ "not be reflected in the compiled graph.");
56
+ }
57
+ for (const start of startKey) {
58
+ if (start === END) {
59
+ throw new Error("END cannot be a start node");
60
+ }
61
+ if (!Object.keys(this.nodes).some((node) => node === start)) {
62
+ throw new Error(`Need to add_node ${start} first`);
63
+ }
64
+ }
65
+ if (endKey === END) {
66
+ throw new Error("END cannot be an end node");
67
+ }
68
+ if (!Object.keys(this.nodes).some((node) => node === endKey)) {
69
+ throw new Error(`Need to add_node ${endKey} first`);
70
+ }
71
+ this.waitingEdges.add([startKey, endKey]);
72
+ return this;
73
+ }
74
+ compile({ checkpointer, interruptBefore, interruptAfter, } = {}) {
75
+ // validate the graph
76
+ this.validate([
77
+ ...(Array.isArray(interruptBefore) ? interruptBefore : []),
78
+ ...(Array.isArray(interruptAfter) ? interruptAfter : []),
79
+ ]);
80
+ // prepare output channels
31
81
  const stateKeys = Object.keys(this.channels);
32
- const stateKeysRead = stateKeys.length === 1 && stateKeys[0] === "__root__"
82
+ const outputs = stateKeys.length === 1 && stateKeys[0] === ROOT
33
83
  ? stateKeys[0]
34
84
  : stateKeys;
35
- const updateState = Array.isArray(stateKeysRead)
36
- ? (nodeName,
37
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
- input, options) => _updateStateObject(stateKeys, nodeName, input, options)
39
- : _updateStateRoot;
40
- const outgoingEdges = {};
85
+ // create empty compiled graph
86
+ const compiled = new CompiledStateGraph({
87
+ builder: this,
88
+ checkpointer,
89
+ interruptAfter,
90
+ interruptBefore,
91
+ autoValidate: false,
92
+ nodes: {},
93
+ channels: {
94
+ ...this.channels,
95
+ [START]: new EphemeralValue(),
96
+ },
97
+ inputs: START,
98
+ outputs,
99
+ streamChannels: outputs,
100
+ streamMode: "updates",
101
+ });
102
+ // attach nodes, edges and branches
103
+ compiled.attachNode(START);
104
+ for (const [key, node] of Object.entries(this.nodes)) {
105
+ compiled.attachNode(key, node);
106
+ }
41
107
  for (const [start, end] of this.edges) {
42
- if (!outgoingEdges[start]) {
43
- outgoingEdges[start] = [];
44
- }
45
- outgoingEdges[start].push(end !== END ? `${end}:inbox` : END);
108
+ compiled.attachEdge(start, end);
46
109
  }
47
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
- const nodes = {};
49
- for (const [key, node] of Object.entries(this.nodes)) {
50
- nodes[key] = Channel.subscribeTo(`${key}:inbox`)
51
- .pipe(node)
52
- .pipe((
53
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
- input, options) => updateState(key, input, options))
55
- .pipe(Channel.writeTo(key));
56
- }
57
- for (const key of Object.keys(this.nodes)) {
58
- const outgoing = outgoingEdges[key];
59
- const edgesKey = `${key}:edges`;
60
- if (outgoing || this.branches[key]) {
61
- nodes[edgesKey] = Channel.subscribeTo(key, {
62
- tags: ["langsmith:hidden"],
63
- }).pipe(new ChannelRead(stateKeysRead));
64
- }
65
- if (outgoing) {
66
- nodes[edgesKey] = nodes[edgesKey].pipe(Channel.writeTo(...outgoing));
67
- }
68
- if (this.branches[key]) {
69
- for (const branch of this.branches[key]) {
70
- nodes[edgesKey] = nodes[edgesKey].pipe(new RunnableLambda({
71
- func: (i, c) => branch.runnable(i, c),
72
- }));
73
- }
110
+ for (const [starts, end] of this.waitingEdges) {
111
+ compiled.attachEdge(starts, end);
112
+ }
113
+ for (const [start, branches] of Object.entries(this.branches)) {
114
+ for (const [name, branch] of Object.entries(branches)) {
115
+ compiled.attachBranch(start, name, branch);
74
116
  }
75
117
  }
76
- nodes[START] = Channel.subscribeTo(`${START}:inbox`, {
77
- tags: ["langsmith:hidden"],
78
- })
79
- .pipe((
80
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
81
- input, options) => updateState(START, input, options))
82
- .pipe(Channel.writeTo(START));
83
- nodes[`${START}:edges`] = Channel.subscribeTo(START, {
84
- tags: ["langsmith:hidden"],
85
- })
86
- .pipe(new ChannelRead(stateKeysRead))
87
- .pipe(Channel.writeTo(`${this.entryPoint}:inbox`));
88
- return new Pregel({
89
- nodes,
90
- channels: this.channels,
91
- input: `${START}:inbox`,
92
- output: END,
93
- hidden: Object.keys(this.nodes)
94
- .map((node) => `${node}:inbox`)
95
- .concat(START, stateKeys),
96
- checkpointer,
97
- });
118
+ return compiled.validate();
98
119
  }
99
120
  }
100
- function _updateStateObject(stateKeys, nodeName,
101
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
102
- input, options
103
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
104
- ) {
105
- if (!options?.config) {
106
- throw new Error("Config not found when updating state.");
107
- }
108
- if (Object.keys(input).some((key) => !stateKeys.some((sk) => sk === key))) {
109
- throw new Error(`Invalid state update from node ${nodeName}, expected object with one or more of ${stateKeys.join(", ")}, got ${Object.keys(input).join(",")}`);
121
+ function _getChannels(schema) {
122
+ const channels = {};
123
+ for (const [name, val] of Object.entries(schema)) {
124
+ if (name === ROOT) {
125
+ channels[name] = getChannel(val);
126
+ }
127
+ else {
128
+ const key = name;
129
+ channels[name] = getChannel(val);
130
+ }
110
131
  }
111
- ChannelWrite.doWrite(options.config, input);
112
- return input;
132
+ return channels;
113
133
  }
114
- function _updateStateRoot(_nodeName, input, options) {
115
- if (!options?.config) {
116
- throw new Error("Config not found when updating state.");
134
+ function getChannel(reducer) {
135
+ if (reducer && "reducer" in reducer && reducer.reducer) {
136
+ return new BinaryOperatorAggregate(reducer.reducer, reducer.default);
137
+ }
138
+ if (reducer && "value" in reducer && reducer.value) {
139
+ return new BinaryOperatorAggregate(reducer.value, reducer.default);
117
140
  }
118
- ChannelWrite.doWrite(options.config, {
119
- __root__: input,
120
- });
121
- return input;
141
+ return new LastValue();
122
142
  }
123
- function _getChannels(schema) {
124
- if ("value" in schema && "default" in schema) {
125
- if (!schema.value) {
126
- throw new Error("Value is required for channels");
143
+ export class CompiledStateGraph extends CompiledGraph {
144
+ attachNode(key, node) {
145
+ const stateKeys = Object.keys(this.builder.channels);
146
+ function getStateKey(key, input) {
147
+ if (!input) {
148
+ return SKIP_WRITE;
149
+ }
150
+ else if (typeof input !== "object" || Array.isArray(input)) {
151
+ throw new InvalidUpdateError(`Expected dict, got ${typeof input}`);
152
+ }
153
+ else {
154
+ return key in input ? input[key] : SKIP_WRITE;
155
+ }
156
+ }
157
+ // state updaters
158
+ const stateWriteEntries = stateKeys.map((key) => key === ROOT
159
+ ? { channel: key, value: PASSTHROUGH, skipNone: true }
160
+ : {
161
+ channel: key,
162
+ value: PASSTHROUGH,
163
+ mapper: new RunnableCallable({
164
+ func: getStateKey.bind(null, key),
165
+ trace: false,
166
+ recurse: false,
167
+ }),
168
+ });
169
+ // add node and output channel
170
+ if (key === START) {
171
+ this.nodes[key] = new PregelNode({
172
+ tags: [TAG_HIDDEN],
173
+ triggers: [START],
174
+ channels: [START],
175
+ writers: [new ChannelWrite(stateWriteEntries, [TAG_HIDDEN])],
176
+ });
177
+ }
178
+ else {
179
+ this.channels[key] = new EphemeralValue();
180
+ this.nodes[key] = new PregelNode({
181
+ triggers: [],
182
+ // read state keys
183
+ channels: stateKeys.length === 1 && stateKeys[0] === ROOT
184
+ ? stateKeys
185
+ : stateKeys.reduce((acc, k) => {
186
+ acc[k] = k;
187
+ return acc;
188
+ }, {}),
189
+ // publish to this channel and state keys
190
+ writers: [
191
+ new ChannelWrite(stateWriteEntries.concat({ channel: key, value: key }), [TAG_HIDDEN]),
192
+ ],
193
+ bound: node,
194
+ });
127
195
  }
128
- return {
129
- __root__: new BinaryOperatorAggregate(schema.value, schema.default),
130
- };
131
196
  }
132
- const channels = {};
133
- for (const [name, values] of Object.entries(schema)) {
134
- if (values.value) {
135
- channels[name] = new BinaryOperatorAggregate(values.value, values.default);
197
+ attachEdge(start, end) {
198
+ if (end === END) {
199
+ return;
200
+ }
201
+ if (Array.isArray(start)) {
202
+ const channelName = `join:${start.join("+")}:${end}`;
203
+ // register channel
204
+ this.channels[channelName] =
205
+ new NamedBarrierValue(new Set(start));
206
+ // subscribe to channel
207
+ this.nodes[end].triggers.push(channelName);
208
+ // publish to channel
209
+ for (const s of start) {
210
+ this.nodes[s].writers.push(new ChannelWrite([{ channel: channelName, value: s }], [TAG_HIDDEN]));
211
+ }
212
+ }
213
+ else if (start === START) {
214
+ const channelName = `start:${end}`;
215
+ // register channel
216
+ this.channels[channelName] =
217
+ new EphemeralValue();
218
+ // subscribe to channel
219
+ this.nodes[end].triggers.push(channelName);
220
+ // publish to channel
221
+ this.nodes[START].writers.push(new ChannelWrite([{ channel: channelName, value: START }], [TAG_HIDDEN]));
136
222
  }
137
223
  else {
138
- channels[name] = new LastValue();
224
+ this.nodes[end].triggers.push(start);
225
+ }
226
+ }
227
+ attachBranch(start, name, branch) {
228
+ // attach branch publisher
229
+ this.nodes[start].writers.push(branch.compile(
230
+ // writer
231
+ (dests) => {
232
+ const filteredDests = dests.filter((dest) => dest !== END);
233
+ if (!filteredDests.length) {
234
+ return;
235
+ }
236
+ const writes = filteredDests.map((dest) => ({
237
+ channel: `branch:${start}:${name}:${dest}`,
238
+ value: start,
239
+ }));
240
+ if (branch.then && branch.then !== END) {
241
+ writes.push({
242
+ channel: `branch:${start}:${name}:then`,
243
+ value: { __names: filteredDests },
244
+ });
245
+ }
246
+ return new ChannelWrite(writes, [TAG_HIDDEN]);
247
+ },
248
+ // reader
249
+ (config) => ChannelRead.doRead(config, this.outputs, true)));
250
+ // attach branch subscribers
251
+ const ends = branch.ends
252
+ ? Object.values(branch.ends)
253
+ : Object.keys(this.builder.nodes).filter((n) => n !== branch.then);
254
+ for (const end of ends) {
255
+ if (end === END) {
256
+ continue;
257
+ }
258
+ const channelName = `branch:${start}:${name}:${end}`;
259
+ this.channels[channelName] =
260
+ new EphemeralValue();
261
+ this.nodes[end].triggers.push(channelName);
262
+ }
263
+ if (branch.then && branch.then !== END) {
264
+ const channelName = `branch:${start}:${name}:then`;
265
+ this.channels[channelName] =
266
+ new DynamicBarrierValue();
267
+ this.nodes[branch.then].triggers.push(channelName);
268
+ for (const end of ends) {
269
+ if (end === END) {
270
+ continue;
271
+ }
272
+ this.nodes[end].writers.push(new ChannelWrite([{ channel: channelName, value: end }], [TAG_HIDDEN]));
273
+ }
139
274
  }
140
275
  }
141
- return channels;
142
276
  }
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BaseCheckpointSaver = exports.emptyCheckpoint = exports.MemorySaverAssertImmutable = exports.MemorySaver = exports.MessageGraph = exports.StateGraph = exports.START = exports.Graph = exports.END = void 0;
3
+ exports.EmptyChannelError = exports.InvalidUpdateError = exports.GraphValueError = exports.GraphRecursionError = exports.BaseCheckpointSaver = exports.emptyCheckpoint = exports.MemorySaver = exports.MessageGraph = exports.StateGraph = exports.START = exports.Graph = exports.END = void 0;
4
4
  var index_js_1 = require("./graph/index.cjs");
5
5
  Object.defineProperty(exports, "END", { enumerable: true, get: function () { return index_js_1.END; } });
6
6
  Object.defineProperty(exports, "Graph", { enumerable: true, get: function () { return index_js_1.Graph; } });
@@ -9,7 +9,11 @@ Object.defineProperty(exports, "StateGraph", { enumerable: true, get: function (
9
9
  Object.defineProperty(exports, "MessageGraph", { enumerable: true, get: function () { return index_js_1.MessageGraph; } });
10
10
  var index_js_2 = require("./checkpoint/index.cjs");
11
11
  Object.defineProperty(exports, "MemorySaver", { enumerable: true, get: function () { return index_js_2.MemorySaver; } });
12
- Object.defineProperty(exports, "MemorySaverAssertImmutable", { enumerable: true, get: function () { return index_js_2.MemorySaverAssertImmutable; } });
13
12
  var index_js_3 = require("./checkpoint/index.cjs");
14
13
  Object.defineProperty(exports, "emptyCheckpoint", { enumerable: true, get: function () { return index_js_3.emptyCheckpoint; } });
15
14
  Object.defineProperty(exports, "BaseCheckpointSaver", { enumerable: true, get: function () { return index_js_3.BaseCheckpointSaver; } });
15
+ var errors_js_1 = require("./errors.cjs");
16
+ Object.defineProperty(exports, "GraphRecursionError", { enumerable: true, get: function () { return errors_js_1.GraphRecursionError; } });
17
+ Object.defineProperty(exports, "GraphValueError", { enumerable: true, get: function () { return errors_js_1.GraphValueError; } });
18
+ Object.defineProperty(exports, "InvalidUpdateError", { enumerable: true, get: function () { return errors_js_1.InvalidUpdateError; } });
19
+ Object.defineProperty(exports, "EmptyChannelError", { enumerable: true, get: function () { return errors_js_1.EmptyChannelError; } });
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { END, Graph, type StateGraphArgs, START, StateGraph, MessageGraph, } from "./graph/index.js";
2
- export { MemorySaver, MemorySaverAssertImmutable } from "./checkpoint/index.js";
3
- export { type ConfigurableFieldSpec, type Checkpoint, type CheckpointAt, emptyCheckpoint, BaseCheckpointSaver, } from "./checkpoint/index.js";
2
+ export { MemorySaver } from "./checkpoint/index.js";
3
+ export { type Checkpoint, emptyCheckpoint, BaseCheckpointSaver, } from "./checkpoint/index.js";
4
+ export { GraphRecursionError, GraphValueError, InvalidUpdateError, EmptyChannelError, } from "./errors.js";
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { END, Graph, START, StateGraph, MessageGraph, } from "./graph/index.js";
2
- export { MemorySaver, MemorySaverAssertImmutable } from "./checkpoint/index.js";
2
+ export { MemorySaver } from "./checkpoint/index.js";
3
3
  export { emptyCheckpoint, BaseCheckpointSaver, } from "./checkpoint/index.js";
4
+ export { GraphRecursionError, GraphValueError, InvalidUpdateError, EmptyChannelError, } from "./errors.js";
@@ -4,27 +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("../index.cjs");
7
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
- function _getAgentState(inputSchema) {
9
- if (!inputSchema) {
10
- return {
11
- input: {
12
- value: null,
13
- },
14
- agentOutcome: {
15
- value: null,
16
- },
17
- steps: {
18
- value: (x, y) => x.concat(y),
19
- default: () => [],
20
- },
21
- };
22
- }
23
- else {
24
- return inputSchema;
25
- }
26
- }
27
- function createAgentExecutor({ agentRunnable, tools, inputSchema, }) {
7
+ function createAgentExecutor({ agentRunnable, tools, }) {
28
8
  let toolExecutor;
29
9
  if (!Array.isArray(tools)) {
30
10
  toolExecutor = tools;
@@ -34,7 +14,6 @@ function createAgentExecutor({ agentRunnable, tools, inputSchema, }) {
34
14
  tools,
35
15
  });
36
16
  }
37
- const state = _getAgentState(inputSchema);
38
17
  // Define logic that will be used to determine which conditional edge to go down
39
18
  const shouldContinue = (data) => {
40
19
  if (data.agentOutcome && "returnValues" in data.agentOutcome) {
@@ -60,16 +39,23 @@ function createAgentExecutor({ agentRunnable, tools, inputSchema, }) {
60
39
  };
61
40
  // Define a new graph
62
41
  const workflow = new state_js_1.StateGraph({
63
- channels: state,
64
- });
65
- // Define the two nodes we will cycle between
66
- workflow.addNode("agent", runAgent);
67
- workflow.addNode("action", executeTools);
68
- // Set the entrypoint as `agent`
69
- // This means that this node is the first one called
70
- workflow.setEntryPoint("agent");
71
- // We now add a conditional edge
72
- workflow.addConditionalEdges(
42
+ channels: {
43
+ input: null,
44
+ agentOutcome: null,
45
+ steps: {
46
+ reducer: (x, y) => x.concat(y),
47
+ default: () => [],
48
+ },
49
+ },
50
+ })
51
+ // Define the two nodes we will cycle between
52
+ .addNode("agent", runAgent)
53
+ .addNode("action", executeTools)
54
+ // Set the entrypoint as `agent`
55
+ // This means that this node is the first one called
56
+ .addEdge(index_js_1.START, "agent")
57
+ // We now add a conditional edge
58
+ .addConditionalEdges(
73
59
  // First, we define the start node. We use `agent`.
74
60
  // This means these are the edges taken after the `agent` node is called.
75
61
  "agent",
@@ -86,10 +72,10 @@ function createAgentExecutor({ agentRunnable, tools, inputSchema, }) {
86
72
  continue: "action",
87
73
  // Otherwise we finish.
88
74
  end: index_js_1.END,
89
- });
90
- // We now add a normal edge from `tools` to `agent`.
91
- // This means that after `tools` is called, `agent` node is called next.
92
- workflow.addEdge("action", "agent");
75
+ })
76
+ // We now add a normal edge from `tools` to `agent`.
77
+ // This means that after `tools` is called, `agent` node is called next.
78
+ .addEdge("action", "agent");
93
79
  return workflow.compile();
94
80
  }
95
81
  exports.createAgentExecutor = createAgentExecutor;
@@ -3,21 +3,18 @@ import { BaseMessage } from "@langchain/core/messages";
3
3
  import { Runnable } from "@langchain/core/runnables";
4
4
  import { Tool } from "@langchain/core/tools";
5
5
  import { ToolExecutor } from "./tool_executor.js";
6
- import { StateGraphArgs } from "../graph/state.js";
7
- import { Pregel } from "../pregel/index.js";
8
- type Step = [AgentAction | AgentFinish, string];
9
- interface AgentStateBase {
6
+ interface Step {
7
+ action: AgentAction | AgentFinish;
8
+ observation: unknown;
9
+ }
10
+ export interface AgentExecutorState {
10
11
  agentOutcome?: AgentAction | AgentFinish;
11
12
  steps: Array<Step>;
12
- }
13
- export interface AgentExecutorState extends AgentStateBase {
14
13
  input: string;
15
14
  chatHistory?: BaseMessage[];
16
15
  }
17
- type AgentChannels<T extends AgentExecutorState> = StateGraphArgs<AgentExecutorState | T>["channels"];
18
- export declare function createAgentExecutor<T extends AgentExecutorState>({ agentRunnable, tools, inputSchema, }: {
16
+ export declare function createAgentExecutor({ agentRunnable, tools, }: {
19
17
  agentRunnable: Runnable;
20
18
  tools: Array<Tool> | ToolExecutor;
21
- inputSchema?: AgentChannels<T>;
22
- }): Pregel;
19
+ }): import("../graph/state.js").CompiledStateGraph<AgentExecutorState, Partial<AgentExecutorState>, "__start__" | "agent" | "action">;
23
20
  export {};
@@ -1,27 +1,7 @@
1
1
  import { ToolExecutor } from "./tool_executor.js";
2
2
  import { StateGraph } from "../graph/state.js";
3
- import { END } from "../index.js";
4
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
- function _getAgentState(inputSchema) {
6
- if (!inputSchema) {
7
- return {
8
- input: {
9
- value: null,
10
- },
11
- agentOutcome: {
12
- value: null,
13
- },
14
- steps: {
15
- value: (x, y) => x.concat(y),
16
- default: () => [],
17
- },
18
- };
19
- }
20
- else {
21
- return inputSchema;
22
- }
23
- }
24
- export function createAgentExecutor({ agentRunnable, tools, inputSchema, }) {
3
+ import { END, START } from "../index.js";
4
+ export function createAgentExecutor({ agentRunnable, tools, }) {
25
5
  let toolExecutor;
26
6
  if (!Array.isArray(tools)) {
27
7
  toolExecutor = tools;
@@ -31,7 +11,6 @@ export function createAgentExecutor({ agentRunnable, tools, inputSchema, }) {
31
11
  tools,
32
12
  });
33
13
  }
34
- const state = _getAgentState(inputSchema);
35
14
  // Define logic that will be used to determine which conditional edge to go down
36
15
  const shouldContinue = (data) => {
37
16
  if (data.agentOutcome && "returnValues" in data.agentOutcome) {
@@ -57,16 +36,23 @@ export function createAgentExecutor({ agentRunnable, tools, inputSchema, }) {
57
36
  };
58
37
  // Define a new graph
59
38
  const workflow = new StateGraph({
60
- channels: state,
61
- });
62
- // Define the two nodes we will cycle between
63
- workflow.addNode("agent", runAgent);
64
- workflow.addNode("action", executeTools);
65
- // Set the entrypoint as `agent`
66
- // This means that this node is the first one called
67
- workflow.setEntryPoint("agent");
68
- // We now add a conditional edge
69
- workflow.addConditionalEdges(
39
+ channels: {
40
+ input: null,
41
+ agentOutcome: null,
42
+ steps: {
43
+ reducer: (x, y) => x.concat(y),
44
+ default: () => [],
45
+ },
46
+ },
47
+ })
48
+ // Define the two nodes we will cycle between
49
+ .addNode("agent", runAgent)
50
+ .addNode("action", executeTools)
51
+ // Set the entrypoint as `agent`
52
+ // This means that this node is the first one called
53
+ .addEdge(START, "agent")
54
+ // We now add a conditional edge
55
+ .addConditionalEdges(
70
56
  // First, we define the start node. We use `agent`.
71
57
  // This means these are the edges taken after the `agent` node is called.
72
58
  "agent",
@@ -83,9 +69,9 @@ export function createAgentExecutor({ agentRunnable, tools, inputSchema, }) {
83
69
  continue: "action",
84
70
  // Otherwise we finish.
85
71
  end: END,
86
- });
87
- // We now add a normal edge from `tools` to `agent`.
88
- // This means that after `tools` is called, `agent` node is called next.
89
- workflow.addEdge("action", "agent");
72
+ })
73
+ // We now add a normal edge from `tools` to `agent`.
74
+ // This means that after `tools` is called, `agent` node is called next.
75
+ .addEdge("action", "agent");
90
76
  return workflow.compile();
91
77
  }
@@ -93,15 +93,15 @@ function createFunctionCallingExecutor({ model, tools, }) {
93
93
  // Define a new graph
94
94
  const workflow = new state_js_1.StateGraph({
95
95
  channels: schema,
96
- });
97
- // Define the two nodes we will cycle between
98
- workflow.addNode("agent", new runnables_1.RunnableLambda({ func: callModel }));
99
- workflow.addNode("action", new runnables_1.RunnableLambda({ func: callTool }));
100
- // Set the entrypoint as `agent`
101
- // This means that this node is the first one called
102
- workflow.setEntryPoint("agent");
103
- // We now add a conditional edge
104
- workflow.addConditionalEdges(
96
+ })
97
+ // Define the two nodes we will cycle between
98
+ .addNode("agent", new runnables_1.RunnableLambda({ func: callModel }))
99
+ .addNode("action", new runnables_1.RunnableLambda({ func: callTool }))
100
+ // Set the entrypoint as `agent`
101
+ // This means that this node is the first one called
102
+ .addEdge(index_js_1.START, "agent")
103
+ // We now add a conditional edge
104
+ .addConditionalEdges(
105
105
  // First, we define the start node. We use `agent`.
106
106
  // This means these are the edges taken after the `agent` node is called.
107
107
  "agent",
@@ -118,10 +118,10 @@ function createFunctionCallingExecutor({ model, tools, }) {
118
118
  continue: "action",
119
119
  // Otherwise we finish.
120
120
  end: index_js_1.END,
121
- });
122
- // We now add a normal edge from `tools` to `agent`.
123
- // This means that after `tools` is called, `agent` node is called next.
124
- workflow.addEdge("action", "agent");
121
+ })
122
+ // We now add a normal edge from `tools` to `agent`.
123
+ // This means that after `tools` is called, `agent` node is called next.
124
+ .addEdge("action", "agent");
125
125
  // Finally, we compile it!
126
126
  // This compiles it into a LangChain Runnable,
127
127
  // meaning you can use it as you would any other runnable