@langchain/langgraph 1.4.20 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/channels/base.cjs +113 -8
  2. package/dist/channels/base.cjs.map +1 -1
  3. package/dist/channels/base.d.cts +26 -4
  4. package/dist/channels/base.d.cts.map +1 -1
  5. package/dist/channels/base.d.ts +26 -4
  6. package/dist/channels/base.d.ts.map +1 -1
  7. package/dist/channels/base.js +110 -10
  8. package/dist/channels/base.js.map +1 -1
  9. package/dist/channels/index.cjs +2 -0
  10. package/dist/channels/index.d.cts +2 -2
  11. package/dist/channels/index.d.ts +2 -2
  12. package/dist/channels/index.js +2 -2
  13. package/dist/constants.cjs +16 -2
  14. package/dist/constants.cjs.map +1 -1
  15. package/dist/constants.d.cts.map +1 -1
  16. package/dist/constants.d.ts.map +1 -1
  17. package/dist/constants.js +15 -3
  18. package/dist/constants.js.map +1 -1
  19. package/dist/graph/index.cjs +1 -1
  20. package/dist/graph/index.js +1 -1
  21. package/dist/graph/messages_reducer.cjs +7 -0
  22. package/dist/graph/messages_reducer.cjs.map +1 -1
  23. package/dist/graph/messages_reducer.js +7 -1
  24. package/dist/graph/messages_reducer.js.map +1 -1
  25. package/dist/index.cjs +1 -1
  26. package/dist/index.js +1 -1
  27. package/dist/pregel/algo.cjs +46 -45
  28. package/dist/pregel/algo.cjs.map +1 -1
  29. package/dist/pregel/algo.d.cts.map +1 -1
  30. package/dist/pregel/algo.d.ts.map +1 -1
  31. package/dist/pregel/algo.js +47 -47
  32. package/dist/pregel/algo.js.map +1 -1
  33. package/dist/pregel/checkpoint.cjs +70 -0
  34. package/dist/pregel/checkpoint.cjs.map +1 -0
  35. package/dist/pregel/checkpoint.js +67 -0
  36. package/dist/pregel/checkpoint.js.map +1 -0
  37. package/dist/pregel/index.cjs +87 -34
  38. package/dist/pregel/index.cjs.map +1 -1
  39. package/dist/pregel/index.d.cts.map +1 -1
  40. package/dist/pregel/index.d.ts.map +1 -1
  41. package/dist/pregel/index.js +91 -38
  42. package/dist/pregel/index.js.map +1 -1
  43. package/dist/pregel/loop.cjs +325 -109
  44. package/dist/pregel/loop.cjs.map +1 -1
  45. package/dist/pregel/loop.js +330 -115
  46. package/dist/pregel/loop.js.map +1 -1
  47. package/dist/state/prebuilt/messages.cjs +1 -1
  48. package/dist/state/prebuilt/messages.js +1 -1
  49. package/dist/web.cjs +1 -1
  50. package/dist/web.js +1 -1
  51. package/package.json +5 -5
@@ -7,6 +7,7 @@ const require_utils = require("../utils.cjs");
7
7
  const require_write = require("./write.cjs");
8
8
  const require_read = require("./read.cjs");
9
9
  const require_callbacks = require("./callbacks.cjs");
10
+ const require_checkpoint = require("./checkpoint.cjs");
10
11
  const require_runtime = require("./runtime.cjs");
11
12
  const require_io = require("./io.cjs");
12
13
  const require_index = require("./utils/index.cjs");
@@ -639,7 +640,7 @@ var Pregel = class extends PartialRunnable {
639
640
  }
640
641
  const checkpointNamespace = startConfig.configurable?.checkpoint_ns ?? "";
641
642
  if (checkpointNamespace !== "" && startConfig.configurable?.["__pregel_read"] === void 0 && startConfig.configurable?.["__pregel_checkpointer"] === void 0) throw new Error(`Subgraph "${require_config.recastCheckpointNamespace(checkpointNamespace)}" not found`);
642
- const updateSuperStep = async (inputConfig, updates) => {
643
+ const updateSuperStep = async (inputConfig, updates, isFirstSuperstep) => {
643
644
  const config = this._ownCheckpointConfig(this.config ? (0, _langchain_core_runnables.mergeConfigs)(this.config, inputConfig) : inputConfig);
644
645
  const saved = await checkpointer.getTuple(config);
645
646
  const checkpoint = saved !== void 0 ? (0, _langchain_langgraph_checkpoint.copyCheckpoint)(saved.checkpoint) : (0, _langchain_langgraph_checkpoint.emptyCheckpoint)();
@@ -656,21 +657,46 @@ var Pregel = class extends PartialRunnable {
656
657
  }
657
658
  const deltaWritesVersioned = Object.values(this.channels).some(require_base.isDeltaChannel) && (saved === void 0 || require_base.isDeltaWritesVersioned(saved.metadata));
658
659
  const versionedMetadata = deltaWritesVersioned ? { [require_base.DELTA_WRITES_VERSIONED]: true } : {};
660
+ const getNextVersion = (current) => checkpointer.getNextVersion(current);
661
+ const writtenChannels = () => new Set(Object.keys(require_index.getNewChannelVersions(checkpointPreviousVersions, checkpoint.channel_versions)));
662
+ const forkPending = isFirstSuperstep ? require_base.deltaChannelsWithPendingWrites(this.channels, saved?.pendingWrites) : /* @__PURE__ */ new Set();
663
+ const editsOlderCheckpoint = async () => isFirstSuperstep && saved !== void 0 && await require_checkpoint.checkpointSuperseded(checkpointer, config, saved);
664
+ const specs = this.channels;
665
+ const sealDeltaWrites = (writes) => {
666
+ for (const [ch] of require_base.deltaChannelWrites(specs, writes)) forkPending.add(String(ch));
667
+ };
668
+ const sealOverwrites = (writes) => {
669
+ for (const [ch, value] of require_base.deltaChannelWrites(specs, writes)) if (require_constants._isOverwriteValue(value)) forkPending.add(String(ch));
670
+ };
671
+ const loadChannels = () => require_base.channelsFromCheckpoint(this.channels, checkpoint, {
672
+ saver: checkpointer,
673
+ config: saved?.config ?? checkpointConfig,
674
+ deltaWritesVersioned
675
+ });
659
676
  const { values, asNode } = updates[0];
660
677
  if (values == null && asNode === void 0) {
661
678
  if (updates.length > 1) throw new require_errors.InvalidUpdateError(`Cannot create empty checkpoint with multiple updates`);
662
- return require_index.patchCheckpointMap(await checkpointer.put(checkpointConfig, require_base.createCheckpoint(checkpoint, void 0, step), {
679
+ const counters = saved === void 0 ? {} : require_checkpoint.advanceDeltaCounters(this.channels, /* @__PURE__ */ new Set(), saved.metadata?.counters_since_delta_snapshot);
680
+ const channels = forkPending.size > 0 || Object.entries(counters).some(([name, count]) => require_base.reachedSnapshotBound(this.channels[name], count)) ? await loadChannels() : void 0;
681
+ const { channelsToSnapshot, metadata: countersMetadata } = channels === void 0 ? {
682
+ channelsToSnapshot: /* @__PURE__ */ new Set(),
683
+ metadata: require_checkpoint.deltaCountersMetadata(counters)
684
+ } : require_checkpoint.updateStateDeltaPlan(channels, /* @__PURE__ */ new Set(), saved, checkpoint.channel_versions, deltaWritesVersioned, forkPending);
685
+ const nextCheckpoint = require_base.createCheckpoint(checkpoint, channels, step, {
686
+ channelsToSnapshot,
687
+ storedVersions: checkpointPreviousVersions,
688
+ getNextVersion,
689
+ triggerToNodes: this.triggerToNodes
690
+ });
691
+ return require_index.patchCheckpointMap(await checkpointer.put(checkpointConfig, nextCheckpoint, {
663
692
  source: "update",
664
693
  step: step + 1,
665
694
  parents: saved?.metadata?.parents ?? {},
666
- ...versionedMetadata
667
- }, {}), saved ? saved.metadata : void 0);
695
+ ...versionedMetadata,
696
+ ...countersMetadata
697
+ }, require_index.getNewChannelVersions(checkpointPreviousVersions, nextCheckpoint.channel_versions)), saved ? saved.metadata : void 0);
668
698
  }
669
- const channels = await require_base.channelsFromCheckpoint(this.channels, checkpoint, {
670
- saver: checkpointer,
671
- config: saved?.config ?? checkpointConfig,
672
- deltaWritesVersioned
673
- });
699
+ const channels = await loadChannels();
674
700
  if (values === null && asNode === "__end__") {
675
701
  if (updates.length > 1) throw new require_errors.InvalidUpdateError(`Cannot apply multiple updates when clearing state`);
676
702
  if (saved) {
@@ -696,14 +722,22 @@ var Pregel = class extends PartialRunnable {
696
722
  }
697
723
  require_algo._applyWrites(checkpoint, channels, Object.values(nextTasks), checkpointer.getNextVersion.bind(checkpointer), this.triggerToNodes);
698
724
  }
699
- const { [require_base.DELTA_WRITES_VERSIONED]: _carried, ...endMetadata } = checkpointMetadata;
700
- return require_index.patchCheckpointMap(await checkpointer.put(checkpointConfig, require_base.createCheckpoint(checkpoint, channels, step), {
725
+ const { channelsToSnapshot, metadata: countersMetadata } = require_checkpoint.updateStateDeltaPlan(channels, writtenChannels(), saved, checkpoint.channel_versions, deltaWritesVersioned, forkPending);
726
+ const nextCheckpoint = require_base.createCheckpoint(checkpoint, channels, step, {
727
+ channelsToSnapshot,
728
+ storedVersions: checkpointPreviousVersions,
729
+ getNextVersion,
730
+ triggerToNodes: this.triggerToNodes
731
+ });
732
+ const { [require_base.DELTA_WRITES_VERSIONED]: _carried, counters_since_delta_snapshot: _counters, ...endMetadata } = checkpointMetadata;
733
+ return require_index.patchCheckpointMap(await checkpointer.put(checkpointConfig, nextCheckpoint, {
701
734
  ...endMetadata,
702
735
  source: "update",
703
736
  step: step + 1,
704
737
  parents: saved?.metadata?.parents ?? {},
705
- ...versionedMetadata
706
- }, require_index.getNewChannelVersions(checkpointPreviousVersions, checkpoint.channel_versions)), saved ? saved.metadata : void 0);
738
+ ...versionedMetadata,
739
+ ...countersMetadata
740
+ }, require_index.getNewChannelVersions(checkpointPreviousVersions, nextCheckpoint.channel_versions)), saved ? saved.metadata : void 0);
707
741
  }
708
742
  if (asNode === "__copy__") {
709
743
  if (updates.length > 1) throw new require_errors.InvalidUpdateError(`Cannot copy checkpoint with multiple updates`);
@@ -718,7 +752,8 @@ var Pregel = class extends PartialRunnable {
718
752
  source: "fork",
719
753
  step: step + 1,
720
754
  parents: saved.metadata?.parents ?? {},
721
- ...versionedMetadata
755
+ ...versionedMetadata,
756
+ ...require_checkpoint.deltaCountersMetadata(saved.metadata?.counters_since_delta_snapshot ?? {})
722
757
  }, {});
723
758
  if (isCopyWithUpdates(values)) {
724
759
  const nextTasks = require_algo._prepareNextTasks(nextCheckpoint, saved.pendingWrites, this.nodes, channels, nextConfig, false, { step: step + 2 });
@@ -739,7 +774,7 @@ var Pregel = class extends PartialRunnable {
739
774
  });
740
775
  return acc;
741
776
  }, {});
742
- return updateSuperStep(require_index.patchCheckpointMap(nextConfig, saved.metadata), Object.values(userGroupBy).flat());
777
+ return updateSuperStep(require_index.patchCheckpointMap(nextConfig, saved.metadata), Object.values(userGroupBy).flat(), false);
743
778
  }
744
779
  return require_index.patchCheckpointMap(nextConfig, saved.metadata);
745
780
  }
@@ -747,20 +782,30 @@ var Pregel = class extends PartialRunnable {
747
782
  if (updates.length > 1) throw new require_errors.InvalidUpdateError(`Cannot apply multiple updates when updating as input`);
748
783
  const inputWrites = await require_utils.gatherIterator(require_io.mapInput(this.inputChannels, values));
749
784
  if (inputWrites.length === 0) throw new require_errors.InvalidUpdateError(`Received no input writes for ${JSON.stringify(this.inputChannels, null, 2)}`);
785
+ require_loop.ensureDeltaMessageIds(specs, inputWrites);
786
+ if (await editsOlderCheckpoint()) sealDeltaWrites(inputWrites);
787
+ else if (saved !== void 0) await checkpointer.putWrites(checkpointConfig, inputWrites, (0, _langchain_langgraph_checkpoint.uuid5)(require_constants.INPUT, checkpoint.id));
750
788
  require_algo._applyWrites(checkpoint, channels, [{
751
789
  name: require_constants.INPUT,
752
790
  writes: inputWrites,
753
791
  triggers: []
754
792
  }], checkpointer.getNextVersion.bind(checkpointer), this.triggerToNodes);
793
+ sealOverwrites(inputWrites);
755
794
  const nextStep = saved?.metadata?.step != null ? saved.metadata.step + 1 : -1;
756
- const nextConfig = await checkpointer.put(checkpointConfig, require_base.createCheckpoint(checkpoint, channels, nextStep), {
795
+ const { channelsToSnapshot, metadata: countersMetadata } = require_checkpoint.updateStateDeltaPlan(channels, writtenChannels(), saved, checkpoint.channel_versions, deltaWritesVersioned, forkPending);
796
+ const nextCheckpoint = require_base.createCheckpoint(checkpoint, channels, nextStep, {
797
+ channelsToSnapshot,
798
+ storedVersions: checkpointPreviousVersions,
799
+ getNextVersion,
800
+ triggerToNodes: this.triggerToNodes
801
+ });
802
+ return require_index.patchCheckpointMap(await checkpointer.put(checkpointConfig, nextCheckpoint, {
757
803
  source: "input",
758
804
  step: nextStep,
759
805
  parents: saved?.metadata?.parents ?? {},
760
- ...versionedMetadata
761
- }, require_index.getNewChannelVersions(checkpointPreviousVersions, checkpoint.channel_versions));
762
- await checkpointer.putWrites(nextConfig, inputWrites, (0, _langchain_langgraph_checkpoint.uuid5)(require_constants.INPUT, checkpoint.id));
763
- return require_index.patchCheckpointMap(nextConfig, saved ? saved.metadata : void 0);
806
+ ...versionedMetadata,
807
+ ...countersMetadata
808
+ }, require_index.getNewChannelVersions(checkpointPreviousVersions, nextCheckpoint.channel_versions)), saved ? saved.metadata : void 0);
764
809
  }
765
810
  if (config.configurable?.checkpoint_id === void 0 && saved?.pendingWrites !== void 0 && saved.pendingWrites.length > 0) {
766
811
  const nextTasks = require_algo._prepareNextTasks(checkpoint, saved.pendingWrites, this.nodes, channels, saved.config, true, {
@@ -787,7 +832,8 @@ var Pregel = class extends PartialRunnable {
787
832
  });
788
833
  if (tasks.length > 0) require_algo._applyWrites(checkpoint, channels, tasks, checkpointer.getNextVersion.bind(checkpointer), this.triggerToNodes);
789
834
  }
790
- const nonNullVersion = Object.values(checkpoint.versions_seen).map((seenVersions) => {
835
+ const versionsSeen = require_base.versionsSeenWithoutBumps(checkpoint.versions_seen);
836
+ const nonNullVersion = Object.values(versionsSeen).map((seenVersions) => {
791
837
  return Object.values(seenVersions);
792
838
  }).flat().find((v) => !!v);
793
839
  const validUpdates = [];
@@ -797,7 +843,7 @@ var Pregel = class extends PartialRunnable {
797
843
  else if (asNode === void 0 && nonNullVersion === void 0) {
798
844
  if (typeof this.inputChannels === "string" && this.nodes[this.inputChannels] !== void 0) asNode = this.inputChannels;
799
845
  } else if (asNode === void 0) {
800
- const lastSeenByNode = Object.entries(checkpoint.versions_seen).map(([n, seen]) => {
846
+ const lastSeenByNode = Object.entries(versionsSeen).map(([n, seen]) => {
801
847
  return Object.values(seen).map((v) => {
802
848
  return [v, n];
803
849
  });
@@ -832,6 +878,7 @@ var Pregel = class extends PartialRunnable {
832
878
  proc: writers.length > 1 ? _langchain_core_runnables.RunnableSequence.from(writers, { omitSequenceTags: true }) : writers[0],
833
879
  writes: [],
834
880
  triggers: [require_constants.INTERRUPT],
881
+ path: [require_constants.INTERRUPT, i],
835
882
  id: taskId ?? (0, _langchain_langgraph_checkpoint.uuid5)(i === 0 ? "__interrupt__" : `__interrupt__:${i}`, checkpoint.id),
836
883
  writers: []
837
884
  });
@@ -846,22 +893,28 @@ var Pregel = class extends PartialRunnable {
846
893
  [require_constants.CONFIG_KEY_READ]: (select_, fresh_ = false) => require_algo._localRead(checkpoint, channels, task, select_, fresh_)
847
894
  }
848
895
  }));
849
- for (const task of tasks) {
896
+ for (const task of tasks) require_loop.ensureDeltaMessageIds(specs, task.writes);
897
+ if (await editsOlderCheckpoint()) for (const task of tasks) sealDeltaWrites(task.writes);
898
+ else for (const task of tasks) {
850
899
  const channelWrites = task.writes.filter((w) => w[0] !== require_constants.PUSH);
851
- if (saved !== void 0 && channelWrites.length > 0) await checkpointer.putWrites(checkpointConfig, channelWrites, task.id);
900
+ if (saved !== void 0 && channelWrites.length > 0) await checkpointer.putWrites(checkpointConfig, channelWrites, task.id, require_algo.taskPathStr(task.path));
852
901
  }
853
902
  require_algo._applyWrites(checkpoint, channels, tasks, checkpointer.getNextVersion.bind(checkpointer), this.triggerToNodes);
854
- const channelsToSnapshot = /* @__PURE__ */ new Set();
855
- if (saved === void 0) {
856
- for (const [k, ch] of Object.entries(channels)) if (require_base.isDeltaChannel(ch) && checkpoint.channel_versions[k] !== void 0) channelsToSnapshot.add(k);
857
- }
858
- const newVersions = require_index.getNewChannelVersions(checkpointPreviousVersions, checkpoint.channel_versions);
859
- const nextConfig = await checkpointer.put(checkpointConfig, require_base.createCheckpoint(checkpoint, channels, step + 1, { channelsToSnapshot }), {
903
+ for (const task of tasks) sealOverwrites(task.writes);
904
+ const { channelsToSnapshot, metadata: countersMetadata } = require_checkpoint.updateStateDeltaPlan(channels, writtenChannels(), saved, checkpoint.channel_versions, deltaWritesVersioned, forkPending);
905
+ const nextCheckpoint = require_base.createCheckpoint(checkpoint, channels, step + 1, {
906
+ channelsToSnapshot,
907
+ storedVersions: checkpointPreviousVersions,
908
+ getNextVersion,
909
+ triggerToNodes: this.triggerToNodes
910
+ });
911
+ const nextConfig = await checkpointer.put(checkpointConfig, nextCheckpoint, {
860
912
  source: "update",
861
913
  step: step + 1,
862
914
  parents: saved?.metadata?.parents ?? {},
863
- ...versionedMetadata
864
- }, newVersions);
915
+ ...versionedMetadata,
916
+ ...countersMetadata
917
+ }, require_index.getNewChannelVersions(checkpointPreviousVersions, nextCheckpoint.channel_versions));
865
918
  for (const task of tasks) {
866
919
  const pushWrites = task.writes.filter((w) => w[0] === require_constants.PUSH);
867
920
  if (pushWrites.length > 0) await checkpointer.putWrites(nextConfig, pushWrites, task.id);
@@ -869,7 +922,7 @@ var Pregel = class extends PartialRunnable {
869
922
  return require_index.patchCheckpointMap(nextConfig, saved ? saved.metadata : void 0);
870
923
  };
871
924
  let currentConfig = startConfig;
872
- for (const { updates } of supersteps) currentConfig = await updateSuperStep(currentConfig, updates);
925
+ for (const [i, { updates }] of supersteps.entries()) currentConfig = await updateSuperStep(currentConfig, updates, i === 0);
873
926
  return currentConfig;
874
927
  }
875
928
  /**
@@ -1258,7 +1311,7 @@ var Pregel = class extends PartialRunnable {
1258
1311
  try {
1259
1312
  while (await loop.tick({ inputKeys: this.inputChannels })) {
1260
1313
  if (emitLifecycleEvents) await emitLifecycleEvents(loop.lifecycleEvents);
1261
- for (const { task } of await loop._matchCachedWrites()) loop._outputWrites(task.id, task.writes, true);
1314
+ for (const { task } of await loop._matchCachedWrites()) loop.putWrites(task.id, task.writes, true);
1262
1315
  if (debug) require_debug.printStepCheckpoint(loop.checkpointMetadata.step, loop.channels, this.streamChannelsList);
1263
1316
  if (debug) require_debug.printStepTasks(loop.step, Object.values(loop.tasks));
1264
1317
  await runner.tick({