@langchain/langgraph 0.2.40 → 0.2.42

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 (86) hide show
  1. package/README.md +237 -154
  2. package/dist/channels/any_value.cjs +10 -10
  3. package/dist/channels/any_value.d.ts +1 -1
  4. package/dist/channels/any_value.js +10 -10
  5. package/dist/channels/ephemeral_value.cjs +10 -9
  6. package/dist/channels/ephemeral_value.d.ts +1 -1
  7. package/dist/channels/ephemeral_value.js +10 -9
  8. package/dist/channels/last_value.cjs +8 -7
  9. package/dist/channels/last_value.d.ts +1 -1
  10. package/dist/channels/last_value.js +8 -7
  11. package/dist/constants.cjs +33 -6
  12. package/dist/constants.d.ts +17 -2
  13. package/dist/constants.js +32 -5
  14. package/dist/errors.d.ts +3 -3
  15. package/dist/func/index.cjs +272 -0
  16. package/dist/func/index.d.ts +310 -0
  17. package/dist/func/index.js +267 -0
  18. package/dist/func/types.cjs +15 -0
  19. package/dist/func/types.d.ts +59 -0
  20. package/dist/func/types.js +11 -0
  21. package/dist/graph/graph.cjs +31 -35
  22. package/dist/graph/graph.d.ts +1 -5
  23. package/dist/graph/graph.js +1 -5
  24. package/dist/graph/index.cjs +1 -3
  25. package/dist/graph/index.d.ts +1 -1
  26. package/dist/graph/index.js +1 -1
  27. package/dist/graph/message.d.ts +1 -1
  28. package/dist/graph/state.cjs +17 -17
  29. package/dist/graph/state.d.ts +2 -1
  30. package/dist/graph/state.js +2 -2
  31. package/dist/index.cjs +8 -0
  32. package/dist/index.d.ts +3 -0
  33. package/dist/index.js +3 -0
  34. package/dist/interrupt.cjs +21 -34
  35. package/dist/interrupt.d.ts +1 -1
  36. package/dist/interrupt.js +22 -35
  37. package/dist/prebuilt/agent_executor.cjs +3 -3
  38. package/dist/prebuilt/agent_executor.d.ts +1 -1
  39. package/dist/prebuilt/agent_executor.js +1 -1
  40. package/dist/prebuilt/chat_agent_executor.cjs +3 -3
  41. package/dist/prebuilt/chat_agent_executor.d.ts +1 -1
  42. package/dist/prebuilt/chat_agent_executor.js +1 -1
  43. package/dist/prebuilt/react_agent_executor.cjs +79 -12
  44. package/dist/prebuilt/react_agent_executor.d.ts +35 -4
  45. package/dist/prebuilt/react_agent_executor.js +79 -13
  46. package/dist/prebuilt/tool_node.cjs +1 -2
  47. package/dist/prebuilt/tool_node.d.ts +1 -1
  48. package/dist/prebuilt/tool_node.js +1 -2
  49. package/dist/pregel/algo.cjs +121 -12
  50. package/dist/pregel/algo.d.ts +8 -6
  51. package/dist/pregel/algo.js +122 -13
  52. package/dist/pregel/call.cjs +77 -0
  53. package/dist/pregel/call.d.ts +15 -0
  54. package/dist/pregel/call.js +71 -0
  55. package/dist/pregel/index.cjs +59 -96
  56. package/dist/pregel/index.d.ts +1 -10
  57. package/dist/pregel/index.js +61 -98
  58. package/dist/pregel/io.cjs +6 -1
  59. package/dist/pregel/io.js +7 -2
  60. package/dist/pregel/loop.cjs +109 -75
  61. package/dist/pregel/loop.d.ts +17 -23
  62. package/dist/pregel/loop.js +110 -75
  63. package/dist/pregel/messages.d.ts +1 -1
  64. package/dist/pregel/retry.cjs +22 -50
  65. package/dist/pregel/retry.d.ts +6 -6
  66. package/dist/pregel/retry.js +22 -50
  67. package/dist/pregel/runner.cjs +275 -0
  68. package/dist/pregel/runner.d.ts +64 -0
  69. package/dist/pregel/runner.js +271 -0
  70. package/dist/pregel/stream.cjs +71 -0
  71. package/dist/pregel/stream.d.ts +17 -0
  72. package/dist/pregel/stream.js +67 -0
  73. package/dist/pregel/types.cjs +54 -0
  74. package/dist/pregel/types.d.ts +78 -6
  75. package/dist/pregel/types.js +51 -1
  76. package/dist/pregel/utils/config.cjs +26 -1
  77. package/dist/pregel/utils/config.d.ts +14 -0
  78. package/dist/pregel/utils/config.js +22 -0
  79. package/dist/pregel/write.d.ts +1 -1
  80. package/dist/utils.cjs +15 -1
  81. package/dist/utils.d.ts +3 -1
  82. package/dist/utils.js +12 -0
  83. package/dist/web.cjs +7 -5
  84. package/dist/web.d.ts +4 -4
  85. package/dist/web.js +3 -3
  86. package/package.json +8 -8
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CompiledGraph = exports.Graph = exports.Branch = exports.END = exports.START = void 0;
3
+ exports.CompiledGraph = exports.Graph = exports.Branch = void 0;
4
4
  /* eslint-disable @typescript-eslint/no-use-before-define */
5
5
  const runnables_1 = require("@langchain/core/runnables");
6
6
  const graph_1 = require("@langchain/core/runnables/graph");
@@ -14,10 +14,6 @@ const constants_js_1 = require("../constants.cjs");
14
14
  const utils_js_1 = require("../utils.cjs");
15
15
  const errors_js_1 = require("../errors.cjs");
16
16
  const subgraph_js_1 = require("../pregel/utils/subgraph.cjs");
17
- /** Special reserved node name denoting the start of a graph. */
18
- exports.START = "__start__";
19
- /** Special reserved node name denoting the end of a graph. */
20
- exports.END = "__end__";
21
17
  class Branch {
22
18
  constructor(options) {
23
19
  Object.defineProperty(this, "condition", {
@@ -83,7 +79,7 @@ class Branch {
83
79
  if (destinations.some((dest) => !dest)) {
84
80
  throw new Error("Branch condition returned unknown or null destination");
85
81
  }
86
- if (destinations.filter(constants_js_1._isSend).some((packet) => packet.node === exports.END)) {
82
+ if (destinations.filter(constants_js_1._isSend).some((packet) => packet.node === constants_js_1.END)) {
87
83
  throw new errors_js_1.InvalidUpdateError("Cannot send a packet to the END node");
88
84
  }
89
85
  const writeResult = await writer(destinations, config);
@@ -149,7 +145,7 @@ class Graph {
149
145
  if (key in this.nodes) {
150
146
  throw new Error(`Node \`${key}\` already present.`);
151
147
  }
152
- if (key === exports.END) {
148
+ if (key === constants_js_1.END) {
153
149
  throw new Error(`Node \`${key}\` is reserved.`);
154
150
  }
155
151
  const runnable = (0, runnables_1._coerceToRunnable)(
@@ -165,10 +161,10 @@ class Graph {
165
161
  }
166
162
  addEdge(startKey, endKey) {
167
163
  this.warnIfCompiled(`Adding an edge to a graph that has already been compiled. This will not be reflected in the compiled graph.`);
168
- if (startKey === exports.END) {
164
+ if (startKey === constants_js_1.END) {
169
165
  throw new Error("END cannot be a start node");
170
166
  }
171
- if (endKey === exports.START) {
167
+ if (endKey === constants_js_1.START) {
172
168
  throw new Error("START cannot be an end node");
173
169
  }
174
170
  if (Array.from(this.edges).some(([start]) => start === startKey) &&
@@ -215,14 +211,14 @@ class Graph {
215
211
  */
216
212
  setEntryPoint(key) {
217
213
  this.warnIfCompiled("Setting the entry point of a graph that has already been compiled. This will not be reflected in the compiled graph.");
218
- return this.addEdge(exports.START, key);
214
+ return this.addEdge(constants_js_1.START, key);
219
215
  }
220
216
  /**
221
217
  * @deprecated use `addEdge(key, END)` instead
222
218
  */
223
219
  setFinishPoint(key) {
224
220
  this.warnIfCompiled("Setting a finish point of a graph that has already been compiled. This will not be reflected in the compiled graph.");
225
- return this.addEdge(key, exports.END);
221
+ return this.addEdge(key, constants_js_1.END);
226
222
  }
227
223
  compile({ checkpointer, interruptBefore, interruptAfter, } = {}) {
228
224
  // validate the graph
@@ -239,11 +235,11 @@ class Graph {
239
235
  autoValidate: false,
240
236
  nodes: {},
241
237
  channels: {
242
- [exports.START]: new ephemeral_value_js_1.EphemeralValue(),
243
- [exports.END]: new ephemeral_value_js_1.EphemeralValue(),
238
+ [constants_js_1.START]: new ephemeral_value_js_1.EphemeralValue(),
239
+ [constants_js_1.END]: new ephemeral_value_js_1.EphemeralValue(),
244
240
  },
245
- inputChannels: exports.START,
246
- outputChannels: exports.END,
241
+ inputChannels: constants_js_1.START,
242
+ outputChannels: constants_js_1.END,
247
243
  streamChannels: [],
248
244
  streamMode: "values",
249
245
  });
@@ -268,7 +264,7 @@ class Graph {
268
264
  allSources.add(start);
269
265
  }
270
266
  for (const source of allSources) {
271
- if (source !== exports.START && !(source in this.nodes)) {
267
+ if (source !== constants_js_1.START && !(source in this.nodes)) {
272
268
  throw new Error(`Found edge starting at unknown node \`${source}\``);
273
269
  }
274
270
  }
@@ -282,7 +278,7 @@ class Graph {
282
278
  }
283
279
  }
284
280
  else {
285
- allTargets.add(exports.END);
281
+ allTargets.add(constants_js_1.END);
286
282
  for (const node of Object.keys(this.nodes)) {
287
283
  if (node !== start) {
288
284
  allTargets.add(node);
@@ -311,7 +307,7 @@ class Graph {
311
307
  }
312
308
  }
313
309
  for (const target of allTargets) {
314
- if (target !== exports.END && !(target in this.nodes)) {
310
+ if (target !== constants_js_1.END && !(target in this.nodes)) {
315
311
  throw new Error(`Found edge ending at unknown node \`${target}\``);
316
312
  }
317
313
  }
@@ -352,11 +348,11 @@ class CompiledGraph extends index_js_1.Pregel {
352
348
  this.streamChannels.push(key);
353
349
  }
354
350
  attachEdge(start, end) {
355
- if (end === exports.END) {
356
- if (start === exports.START) {
351
+ if (end === constants_js_1.END) {
352
+ if (start === constants_js_1.START) {
357
353
  throw new Error("Cannot have an edge from START to END");
358
354
  }
359
- this.nodes[start].writers.push(new write_js_1.ChannelWrite([{ channel: exports.END, value: write_js_1.PASSTHROUGH }], [constants_js_1.TAG_HIDDEN]));
355
+ this.nodes[start].writers.push(new write_js_1.ChannelWrite([{ channel: constants_js_1.END, value: write_js_1.PASSTHROUGH }], [constants_js_1.TAG_HIDDEN]));
360
356
  }
361
357
  else {
362
358
  this.nodes[end].triggers.push(start);
@@ -365,8 +361,8 @@ class CompiledGraph extends index_js_1.Pregel {
365
361
  }
366
362
  attachBranch(start, name, branch) {
367
363
  // add hidden start node
368
- if (start === exports.START && this.nodes[exports.START]) {
369
- this.nodes[exports.START] = index_js_1.Channel.subscribeTo(exports.START, { tags: [constants_js_1.TAG_HIDDEN] });
364
+ if (start === constants_js_1.START && this.nodes[constants_js_1.START]) {
365
+ this.nodes[constants_js_1.START] = index_js_1.Channel.subscribeTo(constants_js_1.START, { tags: [constants_js_1.TAG_HIDDEN] });
370
366
  }
371
367
  // attach branch writer
372
368
  this.nodes[start].pipe(branch.run((dests) => {
@@ -375,7 +371,7 @@ class CompiledGraph extends index_js_1.Pregel {
375
371
  return dest;
376
372
  }
377
373
  return {
378
- channel: dest === exports.END ? exports.END : `branch:${start}:${name}:${dest}`,
374
+ channel: dest === constants_js_1.END ? constants_js_1.END : `branch:${start}:${name}:${dest}`,
379
375
  value: write_js_1.PASSTHROUGH,
380
376
  };
381
377
  });
@@ -386,7 +382,7 @@ class CompiledGraph extends index_js_1.Pregel {
386
382
  ? Object.values(branch.ends)
387
383
  : Object.keys(this.nodes);
388
384
  for (const end of ends) {
389
- if (end !== exports.END) {
385
+ if (end !== constants_js_1.END) {
390
386
  const channelName = `branch:${start}:${name}:${end}`;
391
387
  this.channels[channelName] =
392
388
  new ephemeral_value_js_1.EphemeralValue();
@@ -402,9 +398,9 @@ class CompiledGraph extends index_js_1.Pregel {
402
398
  const xray = config?.xray;
403
399
  const graph = new graph_1.Graph();
404
400
  const startNodes = {
405
- [exports.START]: graph.addNode({
401
+ [constants_js_1.START]: graph.addNode({
406
402
  schema: zod_1.z.any(),
407
- }, exports.START),
403
+ }, constants_js_1.START),
408
404
  };
409
405
  const endNodes = {};
410
406
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -415,8 +411,8 @@ class CompiledGraph extends index_js_1.Pregel {
415
411
  (x) => isCompiledGraph(x[1])));
416
412
  }
417
413
  function addEdge(start, end, label, conditional = false) {
418
- if (end === exports.END && endNodes[exports.END] === undefined) {
419
- endNodes[exports.END] = graph.addNode({ schema: zod_1.z.any() }, exports.END);
414
+ if (end === constants_js_1.END && endNodes[constants_js_1.END] === undefined) {
415
+ endNodes[constants_js_1.END] = graph.addNode({ schema: zod_1.z.any() }, constants_js_1.END);
420
416
  }
421
417
  return graph.addEdge(startNodes[start], endNodes[end], label !== end ? label : undefined, conditional);
422
418
  }
@@ -526,7 +522,7 @@ class CompiledGraph extends index_js_1.Pregel {
526
522
  ...Object.fromEntries(Object.keys(this.builder.nodes)
527
523
  .filter((k) => k !== start)
528
524
  .map((k) => [_escapeMermaidKeywords(k), _escapeMermaidKeywords(k)])),
529
- [exports.END]: exports.END,
525
+ [constants_js_1.END]: constants_js_1.END,
530
526
  };
531
527
  for (const branch of Object.values(branches)) {
532
528
  let ends;
@@ -559,9 +555,9 @@ class CompiledGraph extends index_js_1.Pregel {
559
555
  const xray = config?.xray;
560
556
  const graph = new graph_1.Graph();
561
557
  const startNodes = {
562
- [exports.START]: graph.addNode({
558
+ [constants_js_1.START]: graph.addNode({
563
559
  schema: zod_1.z.any(),
564
- }, exports.START),
560
+ }, constants_js_1.START),
565
561
  };
566
562
  const endNodes = {};
567
563
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -572,8 +568,8 @@ class CompiledGraph extends index_js_1.Pregel {
572
568
  (x) => isCompiledGraph(x[1])));
573
569
  }
574
570
  function addEdge(start, end, label, conditional = false) {
575
- if (end === exports.END && endNodes[exports.END] === undefined) {
576
- endNodes[exports.END] = graph.addNode({ schema: zod_1.z.any() }, exports.END);
571
+ if (end === constants_js_1.END && endNodes[constants_js_1.END] === undefined) {
572
+ endNodes[constants_js_1.END] = graph.addNode({ schema: zod_1.z.any() }, constants_js_1.END);
577
573
  }
578
574
  return graph.addEdge(startNodes[start], endNodes[end], label !== end ? label : undefined, conditional);
579
575
  }
@@ -683,7 +679,7 @@ class CompiledGraph extends index_js_1.Pregel {
683
679
  ...Object.fromEntries(Object.keys(this.builder.nodes)
684
680
  .filter((k) => k !== start)
685
681
  .map((k) => [_escapeMermaidKeywords(k), _escapeMermaidKeywords(k)])),
686
- [exports.END]: exports.END,
682
+ [constants_js_1.END]: constants_js_1.END,
687
683
  };
688
684
  for (const branch of Object.values(branches)) {
689
685
  let ends;
@@ -5,14 +5,10 @@ import { PregelNode } from "../pregel/read.js";
5
5
  import { Pregel } from "../pregel/index.js";
6
6
  import type { PregelParams } from "../pregel/types.js";
7
7
  import { BaseChannel } from "../channels/base.js";
8
- import { Send } from "../constants.js";
8
+ import { END, Send, START } from "../constants.js";
9
9
  import { RunnableCallable } from "../utils.js";
10
10
  import { StateDefinition, StateType } from "./annotation.js";
11
11
  import type { LangGraphRunnableConfig } from "../pregel/runnable_types.js";
12
- /** Special reserved node name denoting the start of a graph. */
13
- export declare const START = "__start__";
14
- /** Special reserved node name denoting the end of a graph. */
15
- export declare const END = "__end__";
16
12
  export interface BranchOptions<IO, N extends string, CallOptions extends LangGraphRunnableConfig = LangGraphRunnableConfig> {
17
13
  source: N;
18
14
  path: RunnableLike<IO, BranchPathReturnValue, CallOptions>;
@@ -7,14 +7,10 @@ import { PregelNode } from "../pregel/read.js";
7
7
  import { Channel, Pregel } from "../pregel/index.js";
8
8
  import { EphemeralValue } from "../channels/ephemeral_value.js";
9
9
  import { ChannelWrite, PASSTHROUGH } from "../pregel/write.js";
10
- import { _isSend, CHECKPOINT_NAMESPACE_END, CHECKPOINT_NAMESPACE_SEPARATOR, TAG_HIDDEN, } from "../constants.js";
10
+ import { _isSend, CHECKPOINT_NAMESPACE_END, CHECKPOINT_NAMESPACE_SEPARATOR, END, START, TAG_HIDDEN, } from "../constants.js";
11
11
  import { gatherIterator, gatherIteratorSync, RunnableCallable, } from "../utils.js";
12
12
  import { InvalidUpdateError, NodeInterrupt, UnreachableNodeError, } from "../errors.js";
13
13
  import { isPregelLike } from "../pregel/utils/subgraph.js";
14
- /** Special reserved node name denoting the start of a graph. */
15
- export const START = "__start__";
16
- /** Special reserved node name denoting the end of a graph. */
17
- export const END = "__end__";
18
14
  export class Branch {
19
15
  constructor(options) {
20
16
  Object.defineProperty(this, "condition", {
@@ -1,12 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.messagesStateReducer = exports.MessageGraph = exports.CompiledStateGraph = exports.StateGraph = exports.Graph = exports.START = exports.END = exports.AnnotationRoot = exports.Annotation = void 0;
3
+ exports.messagesStateReducer = exports.MessageGraph = exports.CompiledStateGraph = exports.StateGraph = exports.Graph = exports.AnnotationRoot = exports.Annotation = void 0;
4
4
  var annotation_js_1 = require("./annotation.cjs");
5
5
  Object.defineProperty(exports, "Annotation", { enumerable: true, get: function () { return annotation_js_1.Annotation; } });
6
6
  Object.defineProperty(exports, "AnnotationRoot", { enumerable: true, get: function () { return annotation_js_1.AnnotationRoot; } });
7
7
  var graph_js_1 = require("./graph.cjs");
8
- Object.defineProperty(exports, "END", { enumerable: true, get: function () { return graph_js_1.END; } });
9
- Object.defineProperty(exports, "START", { enumerable: true, get: function () { return graph_js_1.START; } });
10
8
  Object.defineProperty(exports, "Graph", { enumerable: true, get: function () { return graph_js_1.Graph; } });
11
9
  var state_js_1 = require("./state.cjs");
12
10
  Object.defineProperty(exports, "StateGraph", { enumerable: true, get: function () { return state_js_1.StateGraph; } });
@@ -1,4 +1,4 @@
1
1
  export { Annotation, type StateType, type UpdateType, type NodeType, AnnotationRoot, type StateDefinition, type SingleReducer, } from "./annotation.js";
2
- export { END, START, Graph, type CompiledGraph } from "./graph.js";
2
+ export { Graph, type CompiledGraph } from "./graph.js";
3
3
  export { type StateGraphArgs, StateGraph, CompiledStateGraph, } from "./state.js";
4
4
  export { MessageGraph, messagesStateReducer, type Messages, } from "./message.js";
@@ -1,4 +1,4 @@
1
1
  export { Annotation, AnnotationRoot, } from "./annotation.js";
2
- export { END, START, Graph } from "./graph.js";
2
+ export { Graph } from "./graph.js";
3
3
  export { StateGraph, CompiledStateGraph, } from "./state.js";
4
4
  export { MessageGraph, messagesStateReducer, } from "./message.js";
@@ -6,7 +6,7 @@ export type Messages = Array<BaseMessage | BaseMessageLike> | BaseMessage | Base
6
6
  * Can handle standard messages and special modifiers like {@link RemoveMessage}
7
7
  * instances.
8
8
  */
9
- export declare function messagesStateReducer(left: BaseMessage[], right: Messages): BaseMessage[];
9
+ export declare function messagesStateReducer(left: Messages, right: Messages): BaseMessage[];
10
10
  /** @ignore */
11
11
  export declare class MessageGraph extends StateGraph<BaseMessage[], BaseMessage[], Messages> {
12
12
  constructor();
@@ -211,7 +211,7 @@ class StateGraph extends graph_js_1.Graph {
211
211
  if (key in this.nodes) {
212
212
  throw new Error(`Node \`${key}\` already present.`);
213
213
  }
214
- if (key === graph_js_1.END || key === graph_js_1.START) {
214
+ if (key === constants_js_1.END || key === constants_js_1.START) {
215
215
  throw new Error(`Node \`${key}\` is reserved.`);
216
216
  }
217
217
  if (options?.input !== undefined) {
@@ -254,14 +254,14 @@ class StateGraph extends graph_js_1.Graph {
254
254
  "not be reflected in the compiled graph.");
255
255
  }
256
256
  for (const start of startKey) {
257
- if (start === graph_js_1.END) {
257
+ if (start === constants_js_1.END) {
258
258
  throw new Error("END cannot be a start node");
259
259
  }
260
260
  if (!Object.keys(this.nodes).some((node) => node === start)) {
261
261
  throw new Error(`Need to add a node named "${start}" first`);
262
262
  }
263
263
  }
264
- if (endKey === graph_js_1.END) {
264
+ if (endKey === constants_js_1.END) {
265
265
  throw new Error("END cannot be an end node");
266
266
  }
267
267
  if (!Object.keys(this.nodes).some((node) => node === endKey)) {
@@ -291,20 +291,20 @@ class StateGraph extends graph_js_1.Graph {
291
291
  nodes: {},
292
292
  channels: {
293
293
  ...this.channels,
294
- [graph_js_1.START]: new ephemeral_value_js_1.EphemeralValue(),
294
+ [constants_js_1.START]: new ephemeral_value_js_1.EphemeralValue(),
295
295
  },
296
- inputChannels: graph_js_1.START,
296
+ inputChannels: constants_js_1.START,
297
297
  outputChannels,
298
298
  streamChannels,
299
299
  streamMode: "updates",
300
300
  store,
301
301
  });
302
302
  // attach nodes, edges and branches
303
- compiled.attachNode(graph_js_1.START);
303
+ compiled.attachNode(constants_js_1.START);
304
304
  for (const [key, node] of Object.entries(this.nodes)) {
305
305
  compiled.attachNode(key, node);
306
306
  }
307
- compiled.attachBranch(graph_js_1.START, constants_js_1.SELF, _getControlBranch(), {
307
+ compiled.attachBranch(constants_js_1.START, constants_js_1.SELF, _getControlBranch(), {
308
308
  withReader: false,
309
309
  });
310
310
  for (const [key] of Object.entries(this.nodes)) {
@@ -348,7 +348,7 @@ function _getChannels(schema) {
348
348
  class CompiledStateGraph extends graph_js_1.CompiledGraph {
349
349
  attachNode(key, node) {
350
350
  let outputKeys;
351
- if (key === graph_js_1.START) {
351
+ if (key === constants_js_1.START) {
352
352
  // Get input schema keys excluding managed values
353
353
  outputKeys = Object.entries(this.builder._schemaDefinitions.get(this.builder._inputDefinition))
354
354
  .filter(([_, v]) => !(0, base_js_2.isConfiguredManagedValue)(v))
@@ -443,11 +443,11 @@ class CompiledStateGraph extends graph_js_1.CompiledGraph {
443
443
  },
444
444
  ];
445
445
  // add node and output channel
446
- if (key === graph_js_1.START) {
446
+ if (key === constants_js_1.START) {
447
447
  this.nodes[key] = new read_js_1.PregelNode({
448
448
  tags: [constants_js_1.TAG_HIDDEN],
449
- triggers: [graph_js_1.START],
450
- channels: [graph_js_1.START],
449
+ triggers: [constants_js_1.START],
450
+ channels: [constants_js_1.START],
451
451
  writers: [new write_js_1.ChannelWrite(stateWriteEntries, [constants_js_1.TAG_HIDDEN])],
452
452
  });
453
453
  }
@@ -479,7 +479,7 @@ class CompiledStateGraph extends graph_js_1.CompiledGraph {
479
479
  }
480
480
  }
481
481
  attachEdge(start, end) {
482
- if (end === graph_js_1.END) {
482
+ if (end === constants_js_1.END) {
483
483
  return;
484
484
  }
485
485
  if (Array.isArray(start)) {
@@ -494,15 +494,15 @@ class CompiledStateGraph extends graph_js_1.CompiledGraph {
494
494
  this.nodes[s].writers.push(new write_js_1.ChannelWrite([{ channel: channelName, value: s }], [constants_js_1.TAG_HIDDEN]));
495
495
  }
496
496
  }
497
- else if (start === graph_js_1.START) {
498
- const channelName = `${graph_js_1.START}:${end}`;
497
+ else if (start === constants_js_1.START) {
498
+ const channelName = `${constants_js_1.START}:${end}`;
499
499
  // register channel
500
500
  this.channels[channelName] =
501
501
  new ephemeral_value_js_1.EphemeralValue();
502
502
  // subscribe to channel
503
503
  this.nodes[end].triggers.push(channelName);
504
504
  // publish to channel
505
- this.nodes[graph_js_1.START].writers.push(new write_js_1.ChannelWrite([{ channel: channelName, value: graph_js_1.START }], [constants_js_1.TAG_HIDDEN]));
505
+ this.nodes[constants_js_1.START].writers.push(new write_js_1.ChannelWrite([{ channel: channelName, value: constants_js_1.START }], [constants_js_1.TAG_HIDDEN]));
506
506
  }
507
507
  else {
508
508
  this.nodes[end].triggers.push(start);
@@ -510,7 +510,7 @@ class CompiledStateGraph extends graph_js_1.CompiledGraph {
510
510
  }
511
511
  attachBranch(start, name, branch, options = { withReader: true }) {
512
512
  const branchWriter = async (packets, config) => {
513
- const filteredPackets = packets.filter((p) => p !== graph_js_1.END);
513
+ const filteredPackets = packets.filter((p) => p !== constants_js_1.END);
514
514
  if (!filteredPackets.length) {
515
515
  return;
516
516
  }
@@ -536,7 +536,7 @@ class CompiledStateGraph extends graph_js_1.CompiledGraph {
536
536
  ? Object.values(branch.ends)
537
537
  : Object.keys(this.builder.nodes);
538
538
  for (const end of ends) {
539
- if (end === graph_js_1.END) {
539
+ if (end === constants_js_1.END) {
540
540
  continue;
541
541
  }
542
542
  const channelName = `branch:${start}:${name}:${end}`;
@@ -1,7 +1,8 @@
1
1
  import { RunnableLike } from "@langchain/core/runnables";
2
2
  import { All, BaseCheckpointSaver, BaseStore } from "@langchain/langgraph-checkpoint";
3
3
  import { BaseChannel } from "../channels/base.js";
4
- import { END, CompiledGraph, Graph, START, Branch, AddNodeOptions, NodeSpec } from "./graph.js";
4
+ import { CompiledGraph, Graph, Branch, AddNodeOptions, NodeSpec } from "./graph.js";
5
+ import { END, START } from "../constants.js";
5
6
  import { AnnotationRoot, SingleReducer, StateDefinition, StateType, UpdateType } from "./annotation.js";
6
7
  import type { RetryPolicy } from "../pregel/utils/index.js";
7
8
  import { ManagedValueSpec } from "../managed/base.js";
@@ -1,13 +1,13 @@
1
1
  /* eslint-disable @typescript-eslint/no-use-before-define */
2
2
  import { _coerceToRunnable, Runnable, } from "@langchain/core/runnables";
3
3
  import { isBaseChannel } from "../channels/base.js";
4
- import { END, CompiledGraph, Graph, START, Branch, } from "./graph.js";
4
+ import { CompiledGraph, Graph, Branch, } from "./graph.js";
5
5
  import { ChannelWrite, PASSTHROUGH, } from "../pregel/write.js";
6
6
  import { ChannelRead, PregelNode } from "../pregel/read.js";
7
7
  import { NamedBarrierValue } from "../channels/named_barrier_value.js";
8
8
  import { EphemeralValue } from "../channels/ephemeral_value.js";
9
9
  import { RunnableCallable } from "../utils.js";
10
- import { isCommand, _isSend, CHECKPOINT_NAMESPACE_END, CHECKPOINT_NAMESPACE_SEPARATOR, Command, SELF, TAG_HIDDEN, } from "../constants.js";
10
+ import { isCommand, _isSend, CHECKPOINT_NAMESPACE_END, CHECKPOINT_NAMESPACE_SEPARATOR, Command, END, SELF, START, TAG_HIDDEN, } from "../constants.js";
11
11
  import { InvalidUpdateError, ParentCommand } from "../errors.js";
12
12
  import { getChannel, } from "./annotation.js";
13
13
  import { isConfiguredManagedValue } from "../managed/base.js";
package/dist/index.cjs CHANGED
@@ -15,7 +15,15 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
16
  };
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.getPreviousState = exports.getWriter = exports.getStore = exports.interrupt = void 0;
18
19
  const async_local_storage_js_1 = require("./setup/async_local_storage.cjs");
19
20
  // Initialize global async local storage instance for tracing
20
21
  (0, async_local_storage_js_1.initializeAsyncLocalStorageSingleton)();
21
22
  __exportStar(require("./web.cjs"), exports);
23
+ var interrupt_js_1 = require("./interrupt.cjs");
24
+ Object.defineProperty(exports, "interrupt", { enumerable: true, get: function () { return interrupt_js_1.interrupt; } });
25
+ var config_js_1 = require("./pregel/utils/config.cjs");
26
+ Object.defineProperty(exports, "getStore", { enumerable: true, get: function () { return config_js_1.getStore; } });
27
+ Object.defineProperty(exports, "getWriter", { enumerable: true, get: function () { return config_js_1.getWriter; } });
28
+ var index_js_1 = require("./func/index.cjs");
29
+ Object.defineProperty(exports, "getPreviousState", { enumerable: true, get: function () { return index_js_1.getPreviousState; } });
package/dist/index.d.ts CHANGED
@@ -1 +1,4 @@
1
1
  export * from "./web.js";
2
+ export { interrupt } from "./interrupt.js";
3
+ export { getStore, getWriter } from "./pregel/utils/config.js";
4
+ export { getPreviousState } from "./func/index.js";
package/dist/index.js CHANGED
@@ -3,3 +3,6 @@ import { initializeAsyncLocalStorageSingleton } from "./setup/async_local_storag
3
3
  // Initialize global async local storage instance for tracing
4
4
  initializeAsyncLocalStorageSingleton();
5
5
  export * from "./web.js";
6
+ export { interrupt } from "./interrupt.js";
7
+ export { getStore, getWriter } from "./pregel/utils/config.js";
8
+ export { getPreviousState } from "./func/index.js";
@@ -43,50 +43,37 @@ const constants_js_1 = require("./constants.cjs");
43
43
  * @throws {Error} If called outside the context of a graph
44
44
  * @throws {GraphInterrupt} When no resume value is available
45
45
  */
46
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
47
  function interrupt(value) {
47
48
  const config = singletons_1.AsyncLocalStorageProviderSingleton.getRunnableConfig();
48
49
  if (!config) {
49
50
  throw new Error("Called interrupt() outside the context of a graph.");
50
51
  }
51
- // Track interrupt index
52
- const scratchpad = config.configurable?.[constants_js_1.CONFIG_KEY_SCRATCHPAD];
53
- if (scratchpad.interruptCounter === undefined) {
54
- scratchpad.interruptCounter = 0;
55
- }
56
- else {
57
- scratchpad.interruptCounter += 1;
52
+ const conf = config.configurable;
53
+ if (!conf) {
54
+ throw new Error("No configurable found in config");
58
55
  }
56
+ // Track interrupt index
57
+ const scratchpad = conf[constants_js_1.CONFIG_KEY_SCRATCHPAD];
58
+ scratchpad.interruptCounter += 1;
59
59
  const idx = scratchpad.interruptCounter;
60
60
  // Find previous resume values
61
- const taskId = config.configurable?.[constants_js_1.CONFIG_KEY_TASK_ID];
62
- const writes = config.configurable?.[constants_js_1.CONFIG_KEY_WRITES] ?? [];
63
- if (!scratchpad.resume) {
64
- const newResume = (writes.find((w) => w[0] === taskId && w[1] === constants_js_1.RESUME)?.[2] || []);
65
- scratchpad.resume = Array.isArray(newResume) ? newResume : [newResume];
66
- }
67
- if (scratchpad.resume) {
68
- if (idx < scratchpad.resume.length) {
69
- return scratchpad.resume[idx];
70
- }
61
+ if (scratchpad.resume.length > 0 && idx < scratchpad.resume.length) {
62
+ return scratchpad.resume[idx];
71
63
  }
72
64
  // Find current resume value
73
- if (!scratchpad.usedNullResume) {
74
- scratchpad.usedNullResume = true;
75
- const sortedWrites = [...writes].sort((a, b) => b[0].localeCompare(a[0]) // Sort in reverse order
76
- );
77
- for (const [tid, c, v] of sortedWrites) {
78
- if (tid === constants_js_1.NULL_TASK_ID && c === constants_js_1.RESUME) {
79
- if (scratchpad.resume.length !== idx) {
80
- throw new Error(`Resume length mismatch: ${scratchpad.resume.length} !== ${idx}`);
81
- }
82
- scratchpad.resume.push(v);
83
- const send = config.configurable?.[constants_js_1.CONFIG_KEY_SEND];
84
- if (send) {
85
- send([[constants_js_1.RESUME, scratchpad.resume]]);
86
- }
87
- return v;
88
- }
65
+ if (scratchpad.nullResume !== undefined) {
66
+ if (scratchpad.resume.length !== idx) {
67
+ throw new Error(`Resume length mismatch: ${scratchpad.resume.length} !== ${idx}`);
68
+ }
69
+ const v = scratchpad.nullResume;
70
+ delete scratchpad.nullResume;
71
+ scratchpad.resume.push(v);
72
+ const send = conf[constants_js_1.CONFIG_KEY_SEND];
73
+ if (send) {
74
+ send([[constants_js_1.RESUME, scratchpad.resume]]);
89
75
  }
76
+ return v;
90
77
  }
91
78
  // No resume value found
92
79
  throw new errors_js_1.GraphInterrupt([
@@ -94,7 +81,7 @@ function interrupt(value) {
94
81
  value,
95
82
  when: "during",
96
83
  resumable: true,
97
- ns: config.configurable?.[constants_js_1.CONFIG_KEY_CHECKPOINT_NS]?.split(constants_js_1.CHECKPOINT_NAMESPACE_SEPARATOR),
84
+ ns: conf[constants_js_1.CONFIG_KEY_CHECKPOINT_NS]?.split(constants_js_1.CHECKPOINT_NAMESPACE_SEPARATOR),
98
85
  },
99
86
  ]);
100
87
  }
@@ -37,4 +37,4 @@
37
37
  * @throws {Error} If called outside the context of a graph
38
38
  * @throws {GraphInterrupt} When no resume value is available
39
39
  */
40
- export declare function interrupt<I = unknown, R = unknown>(value: I): R;
40
+ export declare function interrupt<I = unknown, R = any>(value: I): R;
package/dist/interrupt.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { AsyncLocalStorageProviderSingleton } from "@langchain/core/singletons";
2
2
  import { GraphInterrupt } from "./errors.js";
3
- import { CONFIG_KEY_CHECKPOINT_NS, CONFIG_KEY_SCRATCHPAD, CONFIG_KEY_TASK_ID, CONFIG_KEY_WRITES, CONFIG_KEY_SEND, CHECKPOINT_NAMESPACE_SEPARATOR, NULL_TASK_ID, RESUME, } from "./constants.js";
3
+ import { CONFIG_KEY_CHECKPOINT_NS, CONFIG_KEY_SCRATCHPAD, CONFIG_KEY_SEND, CHECKPOINT_NAMESPACE_SEPARATOR, RESUME, } from "./constants.js";
4
4
  /**
5
5
  * Interrupts the execution of a graph node.
6
6
  * This function can be used to pause execution of a node, and return the value of the `resume`
@@ -40,50 +40,37 @@ import { CONFIG_KEY_CHECKPOINT_NS, CONFIG_KEY_SCRATCHPAD, CONFIG_KEY_TASK_ID, CO
40
40
  * @throws {Error} If called outside the context of a graph
41
41
  * @throws {GraphInterrupt} When no resume value is available
42
42
  */
43
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
44
  export function interrupt(value) {
44
45
  const config = AsyncLocalStorageProviderSingleton.getRunnableConfig();
45
46
  if (!config) {
46
47
  throw new Error("Called interrupt() outside the context of a graph.");
47
48
  }
48
- // Track interrupt index
49
- const scratchpad = config.configurable?.[CONFIG_KEY_SCRATCHPAD];
50
- if (scratchpad.interruptCounter === undefined) {
51
- scratchpad.interruptCounter = 0;
52
- }
53
- else {
54
- scratchpad.interruptCounter += 1;
49
+ const conf = config.configurable;
50
+ if (!conf) {
51
+ throw new Error("No configurable found in config");
55
52
  }
53
+ // Track interrupt index
54
+ const scratchpad = conf[CONFIG_KEY_SCRATCHPAD];
55
+ scratchpad.interruptCounter += 1;
56
56
  const idx = scratchpad.interruptCounter;
57
57
  // Find previous resume values
58
- const taskId = config.configurable?.[CONFIG_KEY_TASK_ID];
59
- const writes = config.configurable?.[CONFIG_KEY_WRITES] ?? [];
60
- if (!scratchpad.resume) {
61
- const newResume = (writes.find((w) => w[0] === taskId && w[1] === RESUME)?.[2] || []);
62
- scratchpad.resume = Array.isArray(newResume) ? newResume : [newResume];
63
- }
64
- if (scratchpad.resume) {
65
- if (idx < scratchpad.resume.length) {
66
- return scratchpad.resume[idx];
67
- }
58
+ if (scratchpad.resume.length > 0 && idx < scratchpad.resume.length) {
59
+ return scratchpad.resume[idx];
68
60
  }
69
61
  // Find current resume value
70
- if (!scratchpad.usedNullResume) {
71
- scratchpad.usedNullResume = true;
72
- const sortedWrites = [...writes].sort((a, b) => b[0].localeCompare(a[0]) // Sort in reverse order
73
- );
74
- for (const [tid, c, v] of sortedWrites) {
75
- if (tid === NULL_TASK_ID && c === RESUME) {
76
- if (scratchpad.resume.length !== idx) {
77
- throw new Error(`Resume length mismatch: ${scratchpad.resume.length} !== ${idx}`);
78
- }
79
- scratchpad.resume.push(v);
80
- const send = config.configurable?.[CONFIG_KEY_SEND];
81
- if (send) {
82
- send([[RESUME, scratchpad.resume]]);
83
- }
84
- return v;
85
- }
62
+ if (scratchpad.nullResume !== undefined) {
63
+ if (scratchpad.resume.length !== idx) {
64
+ throw new Error(`Resume length mismatch: ${scratchpad.resume.length} !== ${idx}`);
65
+ }
66
+ const v = scratchpad.nullResume;
67
+ delete scratchpad.nullResume;
68
+ scratchpad.resume.push(v);
69
+ const send = conf[CONFIG_KEY_SEND];
70
+ if (send) {
71
+ send([[RESUME, scratchpad.resume]]);
86
72
  }
73
+ return v;
87
74
  }
88
75
  // No resume value found
89
76
  throw new GraphInterrupt([
@@ -91,7 +78,7 @@ export function interrupt(value) {
91
78
  value,
92
79
  when: "during",
93
80
  resumable: true,
94
- ns: config.configurable?.[CONFIG_KEY_CHECKPOINT_NS]?.split(CHECKPOINT_NAMESPACE_SEPARATOR),
81
+ ns: conf[CONFIG_KEY_CHECKPOINT_NS]?.split(CHECKPOINT_NAMESPACE_SEPARATOR),
95
82
  },
96
83
  ]);
97
84
  }