@langchain/langgraph 0.3.5 → 0.3.7
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.
- package/CHANGELOG.md +10 -0
- package/dist/channels/base.cjs +2 -2
- package/dist/channels/base.d.ts +3 -1
- package/dist/channels/base.js +2 -2
- package/dist/channels/base.js.map +1 -1
- package/dist/constants.cjs +3 -1
- package/dist/constants.d.ts +3 -0
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -1
- package/dist/errors.cjs +1 -6
- package/dist/errors.js +1 -6
- package/dist/errors.js.map +1 -1
- package/dist/graph/state.d.ts +1 -1
- package/dist/hash.cjs +333 -0
- package/dist/hash.d.ts +2 -0
- package/dist/hash.js +329 -0
- package/dist/hash.js.map +1 -0
- package/dist/interrupt.cjs +11 -1
- package/dist/interrupt.js +13 -3
- package/dist/interrupt.js.map +1 -1
- package/dist/prebuilt/react_agent_executor.cjs +78 -12
- package/dist/prebuilt/react_agent_executor.d.ts +4 -3
- package/dist/prebuilt/react_agent_executor.js +77 -12
- package/dist/prebuilt/react_agent_executor.js.map +1 -1
- package/dist/pregel/algo.cjs +29 -14
- package/dist/pregel/algo.js +30 -15
- package/dist/pregel/algo.js.map +1 -1
- package/dist/pregel/debug.cjs +18 -42
- package/dist/pregel/debug.d.ts +18 -33
- package/dist/pregel/debug.js +18 -42
- package/dist/pregel/debug.js.map +1 -1
- package/dist/pregel/index.cjs +77 -23
- package/dist/pregel/index.d.ts +7 -2
- package/dist/pregel/index.js +78 -24
- package/dist/pregel/index.js.map +1 -1
- package/dist/pregel/loop.cjs +157 -43
- package/dist/pregel/loop.d.ts +7 -1
- package/dist/pregel/loop.js +158 -44
- package/dist/pregel/loop.js.map +1 -1
- package/dist/pregel/messages.cjs +3 -0
- package/dist/pregel/messages.d.ts +1 -1
- package/dist/pregel/messages.js +3 -0
- package/dist/pregel/messages.js.map +1 -1
- package/dist/pregel/messages.test.cjs +18 -0
- package/dist/pregel/messages.test.js +18 -0
- package/dist/pregel/messages.test.js.map +1 -1
- package/dist/pregel/remote.cjs +2 -0
- package/dist/pregel/remote.d.ts +1 -0
- package/dist/pregel/remote.js +2 -0
- package/dist/pregel/remote.js.map +1 -1
- package/dist/pregel/retry.cjs +4 -0
- package/dist/pregel/retry.js +4 -0
- package/dist/pregel/retry.js.map +1 -1
- package/dist/pregel/types.d.ts +49 -4
- package/dist/pregel/types.js.map +1 -1
- package/dist/pregel/utils/config.cjs +2 -1
- package/dist/pregel/utils/config.js +2 -1
- package/dist/pregel/utils/config.js.map +1 -1
- package/dist/pregel/validate.cjs +1 -1
- package/dist/pregel/validate.js +1 -1
- package/dist/pregel/validate.js.map +1 -1
- package/dist/pregel/validate.test.cjs +1 -1
- package/dist/pregel/validate.test.js +1 -1
- package/dist/pregel/validate.test.js.map +1 -1
- package/dist/utils.js.map +1 -1
- package/package.json +6 -5
package/dist/pregel/loop.cjs
CHANGED
|
@@ -11,6 +11,7 @@ const errors_js_1 = require("../errors.cjs");
|
|
|
11
11
|
const index_js_1 = require("./utils/index.cjs");
|
|
12
12
|
const debug_js_1 = require("./debug.cjs");
|
|
13
13
|
const stream_js_1 = require("./stream.cjs");
|
|
14
|
+
const hash_js_1 = require("../hash.cjs");
|
|
14
15
|
const INPUT_DONE = Symbol.for("INPUT_DONE");
|
|
15
16
|
const INPUT_RESUMING = Symbol.for("INPUT_RESUMING");
|
|
16
17
|
const DEFAULT_LOOP_LIMIT = 25;
|
|
@@ -129,6 +130,12 @@ class PregelLoop {
|
|
|
129
130
|
writable: true,
|
|
130
131
|
value: void 0
|
|
131
132
|
});
|
|
133
|
+
Object.defineProperty(this, "checkpointIdSaved", {
|
|
134
|
+
enumerable: true,
|
|
135
|
+
configurable: true,
|
|
136
|
+
writable: true,
|
|
137
|
+
value: void 0
|
|
138
|
+
});
|
|
132
139
|
Object.defineProperty(this, "checkpointConfig", {
|
|
133
140
|
enumerable: true,
|
|
134
141
|
configurable: true,
|
|
@@ -171,6 +178,12 @@ class PregelLoop {
|
|
|
171
178
|
writable: true,
|
|
172
179
|
value: void 0
|
|
173
180
|
});
|
|
181
|
+
Object.defineProperty(this, "checkpointDuring", {
|
|
182
|
+
enumerable: true,
|
|
183
|
+
configurable: true,
|
|
184
|
+
writable: true,
|
|
185
|
+
value: void 0
|
|
186
|
+
});
|
|
174
187
|
Object.defineProperty(this, "outputKeys", {
|
|
175
188
|
enumerable: true,
|
|
176
189
|
configurable: true,
|
|
@@ -201,6 +214,12 @@ class PregelLoop {
|
|
|
201
214
|
writable: true,
|
|
202
215
|
value: void 0
|
|
203
216
|
});
|
|
217
|
+
Object.defineProperty(this, "prevCheckpoint", {
|
|
218
|
+
enumerable: true,
|
|
219
|
+
configurable: true,
|
|
220
|
+
writable: true,
|
|
221
|
+
value: void 0
|
|
222
|
+
});
|
|
204
223
|
Object.defineProperty(this, "status", {
|
|
205
224
|
enumerable: true,
|
|
206
225
|
configurable: true,
|
|
@@ -320,6 +339,7 @@ class PregelLoop {
|
|
|
320
339
|
this.prevCheckpointConfig = params.prevCheckpointConfig;
|
|
321
340
|
this.interruptAfter = params.interruptAfter;
|
|
322
341
|
this.interruptBefore = params.interruptBefore;
|
|
342
|
+
this.checkpointDuring = params.checkpointDuring;
|
|
323
343
|
this.debug = params.debug;
|
|
324
344
|
this.triggerToNodes = params.triggerToNodes;
|
|
325
345
|
}
|
|
@@ -422,6 +442,7 @@ class PregelLoop {
|
|
|
422
442
|
cache: params.cache,
|
|
423
443
|
interruptAfter: params.interruptAfter,
|
|
424
444
|
interruptBefore: params.interruptBefore,
|
|
445
|
+
checkpointDuring: params.checkpointDuring,
|
|
425
446
|
debug: params.debug,
|
|
426
447
|
triggerToNodes: params.triggerToNodes,
|
|
427
448
|
});
|
|
@@ -446,22 +467,17 @@ class PregelLoop {
|
|
|
446
467
|
*/
|
|
447
468
|
putWrites(taskId, writes) {
|
|
448
469
|
let writesCopy = writes;
|
|
449
|
-
if (writesCopy.length === 0)
|
|
470
|
+
if (writesCopy.length === 0)
|
|
450
471
|
return;
|
|
451
|
-
}
|
|
452
472
|
// deduplicate writes to special channels, last write wins
|
|
453
473
|
if (writesCopy.every(([key]) => key in langgraph_checkpoint_1.WRITES_IDX_MAP)) {
|
|
454
474
|
writesCopy = Array.from(new Map(writesCopy.map((w) => [w[0], w])).values());
|
|
455
475
|
}
|
|
476
|
+
// remove existing writes for this task
|
|
477
|
+
this.checkpointPendingWrites = this.checkpointPendingWrites.filter((w) => w[0] !== taskId);
|
|
456
478
|
// save writes
|
|
457
479
|
for (const [c, v] of writesCopy) {
|
|
458
|
-
|
|
459
|
-
if (c in langgraph_checkpoint_1.WRITES_IDX_MAP && idx !== -1) {
|
|
460
|
-
this.checkpointPendingWrites[idx] = [taskId, c, v];
|
|
461
|
-
}
|
|
462
|
-
else {
|
|
463
|
-
this.checkpointPendingWrites.push([taskId, c, v]);
|
|
464
|
-
}
|
|
480
|
+
this.checkpointPendingWrites.push([taskId, c, v]);
|
|
465
481
|
}
|
|
466
482
|
const putWritePromise = this.checkpointer?.putWrites({
|
|
467
483
|
...this.checkpointConfig,
|
|
@@ -504,13 +520,27 @@ class PregelLoop {
|
|
|
504
520
|
(task.config.tags ?? []).includes(constants_js_1.TAG_HIDDEN)) {
|
|
505
521
|
return;
|
|
506
522
|
}
|
|
507
|
-
if (writes.length > 0
|
|
508
|
-
writes[0][0]
|
|
509
|
-
|
|
510
|
-
|
|
523
|
+
if (writes.length > 0) {
|
|
524
|
+
if (writes[0][0] === constants_js_1.INTERRUPT) {
|
|
525
|
+
// in `algo.ts` we append a bool to the task path to indicate
|
|
526
|
+
// whether or not a call was present. If so, we don't emit the
|
|
527
|
+
// the interrupt as it'll be emitted by the parent.
|
|
528
|
+
if (task.path?.[0] === constants_js_1.PUSH && task.path?.at(-1) === true)
|
|
529
|
+
return;
|
|
530
|
+
const interruptWrites = writes
|
|
531
|
+
.filter((w) => w[0] === constants_js_1.INTERRUPT)
|
|
532
|
+
.flatMap((w) => w[1]);
|
|
533
|
+
this._emit([
|
|
534
|
+
["updates", { [constants_js_1.INTERRUPT]: interruptWrites }],
|
|
535
|
+
["values", { [constants_js_1.INTERRUPT]: interruptWrites }],
|
|
536
|
+
]);
|
|
537
|
+
}
|
|
538
|
+
else if (writes[0][0] !== constants_js_1.ERROR) {
|
|
539
|
+
this._emit((0, utils_js_1.gatherIteratorSync)((0, utils_js_1.prefixGenerator)((0, io_js_1.mapOutputUpdates)(this.outputKeys, [[task, writes]], cached), "updates")));
|
|
540
|
+
}
|
|
511
541
|
}
|
|
512
542
|
if (!cached) {
|
|
513
|
-
this._emit((0, utils_js_1.gatherIteratorSync)((0, utils_js_1.prefixGenerator)((0, debug_js_1.mapDebugTaskResults)(
|
|
543
|
+
this._emit((0, utils_js_1.gatherIteratorSync)((0, utils_js_1.prefixGenerator)((0, debug_js_1.mapDebugTaskResults)([[task, writes]], this.streamKeys), "tasks")));
|
|
514
544
|
}
|
|
515
545
|
}
|
|
516
546
|
}
|
|
@@ -607,8 +637,7 @@ class PregelLoop {
|
|
|
607
637
|
this.tasks = nextTasks;
|
|
608
638
|
// Produce debug output
|
|
609
639
|
if (this.checkpointer) {
|
|
610
|
-
this._emit(await (0, utils_js_1.gatherIterator)((0, utils_js_1.prefixGenerator)((0, debug_js_1.mapDebugCheckpoint)(this.
|
|
611
|
-
this.checkpointConfig, this.channels, this.streamKeys, this.checkpointMetadata, Object.values(this.tasks), this.checkpointPendingWrites, this.prevCheckpointConfig, this.outputKeys), "debug")));
|
|
640
|
+
this._emit(await (0, utils_js_1.gatherIterator)((0, utils_js_1.prefixGenerator)((0, debug_js_1.mapDebugCheckpoint)(this.checkpointConfig, this.channels, this.streamKeys, this.checkpointMetadata, Object.values(this.tasks), this.checkpointPendingWrites, this.prevCheckpointConfig, this.outputKeys), "checkpoints")));
|
|
612
641
|
}
|
|
613
642
|
if (Object.values(this.tasks).length === 0) {
|
|
614
643
|
this.status = "done";
|
|
@@ -641,11 +670,22 @@ class PregelLoop {
|
|
|
641
670
|
throw new errors_js_1.GraphInterrupt();
|
|
642
671
|
}
|
|
643
672
|
// Produce debug output
|
|
644
|
-
const debugOutput = await (0, utils_js_1.gatherIterator)((0, utils_js_1.prefixGenerator)((0, debug_js_1.mapDebugTasks)(
|
|
673
|
+
const debugOutput = await (0, utils_js_1.gatherIterator)((0, utils_js_1.prefixGenerator)((0, debug_js_1.mapDebugTasks)(Object.values(this.tasks)), "tasks"));
|
|
645
674
|
this._emit(debugOutput);
|
|
646
675
|
return true;
|
|
647
676
|
}
|
|
648
677
|
async finishAndHandleError(error) {
|
|
678
|
+
// persist current checkpoint and writes
|
|
679
|
+
if (!this.checkpointDuring &&
|
|
680
|
+
// if it's a top graph
|
|
681
|
+
(!this.isNested ||
|
|
682
|
+
// or a nested graph with error or interrupt
|
|
683
|
+
typeof error !== "undefined" ||
|
|
684
|
+
// or a nested graph with checkpointer: true
|
|
685
|
+
this.checkpointNamespace.every((part) => !part.includes(constants_js_1.CHECKPOINT_NAMESPACE_END)))) {
|
|
686
|
+
this._putCheckpoint(this.checkpointMetadata);
|
|
687
|
+
this._flushPendingWrites();
|
|
688
|
+
}
|
|
649
689
|
const suppress = this._suppressInterrupt(error);
|
|
650
690
|
if (suppress || error === undefined) {
|
|
651
691
|
this.output = (0, io_js_1.readChannels)(this.channels, this.outputKeys);
|
|
@@ -662,11 +702,12 @@ class PregelLoop {
|
|
|
662
702
|
this._emit((0, utils_js_1.gatherIteratorSync)((0, utils_js_1.prefixGenerator)((0, io_js_1.mapOutputValues)(this.outputKeys, Object.values(this.tasks).flatMap((t) => t.writes), this.channels), "values")));
|
|
663
703
|
}
|
|
664
704
|
// Emit INTERRUPT event
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
705
|
+
if ((0, errors_js_1.isGraphInterrupt)(error) && !error.interrupts.length) {
|
|
706
|
+
this._emit([
|
|
707
|
+
["updates", { [constants_js_1.INTERRUPT]: [] }],
|
|
708
|
+
["values", { [constants_js_1.INTERRUPT]: [] }],
|
|
709
|
+
]);
|
|
710
|
+
}
|
|
670
711
|
}
|
|
671
712
|
return suppress;
|
|
672
713
|
}
|
|
@@ -690,7 +731,7 @@ class PregelLoop {
|
|
|
690
731
|
this.toInterrupt.push(pushed);
|
|
691
732
|
return;
|
|
692
733
|
}
|
|
693
|
-
this._emit((0, utils_js_1.gatherIteratorSync)((0, utils_js_1.prefixGenerator)((0, debug_js_1.mapDebugTasks)(
|
|
734
|
+
this._emit((0, utils_js_1.gatherIteratorSync)((0, utils_js_1.prefixGenerator)((0, debug_js_1.mapDebugTasks)([pushed]), "tasks")));
|
|
694
735
|
if (this.debug)
|
|
695
736
|
(0, debug_js_1.printStepTasks)(this.step, [pushed]);
|
|
696
737
|
this.tasks[pushed.id] = pushed;
|
|
@@ -717,17 +758,22 @@ class PregelLoop {
|
|
|
717
758
|
if (scratchpad && scratchpad.nullResume !== undefined) {
|
|
718
759
|
this.putWrites(constants_js_1.NULL_TASK_ID, [[constants_js_1.RESUME, scratchpad.nullResume]]);
|
|
719
760
|
}
|
|
761
|
+
// map command to writes
|
|
720
762
|
if ((0, constants_js_1.isCommand)(this.input)) {
|
|
721
763
|
const hasResume = this.input.resume != null;
|
|
764
|
+
if (this.input.resume != null &&
|
|
765
|
+
typeof this.input.resume === "object" &&
|
|
766
|
+
Object.keys(this.input.resume).every(hash_js_1.isXXH3)) {
|
|
767
|
+
this.config.configurable ??= {};
|
|
768
|
+
this.config.configurable[constants_js_1.CONFIG_KEY_RESUME_MAP] = this.input.resume;
|
|
769
|
+
}
|
|
722
770
|
if (hasResume && this.checkpointer == null) {
|
|
723
771
|
throw new Error("Cannot use Command(resume=...) without checkpointer");
|
|
724
772
|
}
|
|
725
773
|
const writes = {};
|
|
726
774
|
// group writes by task id
|
|
727
775
|
for (const [tid, key, value] of (0, io_js_1.mapCommand)(this.input, this.checkpointPendingWrites)) {
|
|
728
|
-
|
|
729
|
-
writes[tid] = [];
|
|
730
|
-
}
|
|
776
|
+
writes[tid] ??= [];
|
|
731
777
|
writes[tid].push([key, value]);
|
|
732
778
|
}
|
|
733
779
|
if (Object.keys(writes).length === 0) {
|
|
@@ -810,33 +856,50 @@ class PregelLoop {
|
|
|
810
856
|
}
|
|
811
857
|
}
|
|
812
858
|
_emit(values) {
|
|
813
|
-
for (const
|
|
814
|
-
if (this.stream.modes.has(
|
|
815
|
-
this.stream.push([this.checkpointNamespace,
|
|
859
|
+
for (const [mode, payload] of values) {
|
|
860
|
+
if (this.stream.modes.has(mode)) {
|
|
861
|
+
this.stream.push([this.checkpointNamespace, mode, payload]);
|
|
862
|
+
}
|
|
863
|
+
// debug mode is a "checkpoints" or "tasks" wrapped in an object
|
|
864
|
+
// TODO: consider deprecating this in 1.x
|
|
865
|
+
if ((mode === "checkpoints" || mode === "tasks") &&
|
|
866
|
+
this.stream.modes.has("debug")) {
|
|
867
|
+
const step = mode === "checkpoints" ? this.step - 1 : this.step;
|
|
868
|
+
const timestamp = new Date().toISOString();
|
|
869
|
+
const type = (() => {
|
|
870
|
+
if (mode === "checkpoints") {
|
|
871
|
+
return "checkpoint";
|
|
872
|
+
}
|
|
873
|
+
else if (typeof payload === "object" &&
|
|
874
|
+
payload != null &&
|
|
875
|
+
"result" in payload) {
|
|
876
|
+
return "task_result";
|
|
877
|
+
}
|
|
878
|
+
else {
|
|
879
|
+
return "task";
|
|
880
|
+
}
|
|
881
|
+
})();
|
|
882
|
+
this.stream.push([
|
|
883
|
+
this.checkpointNamespace,
|
|
884
|
+
"debug",
|
|
885
|
+
{ step, type, timestamp, payload },
|
|
886
|
+
]);
|
|
816
887
|
}
|
|
817
888
|
}
|
|
818
889
|
}
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
const
|
|
822
|
-
|
|
823
|
-
step: this.step,
|
|
824
|
-
parents: this.config.configurable?.[constants_js_1.CONFIG_KEY_CHECKPOINT_MAP] ?? {},
|
|
825
|
-
};
|
|
826
|
-
// Bail if no checkpointer
|
|
827
|
-
if (this.checkpointer !== undefined) {
|
|
890
|
+
_putCheckpoint(inputMetadata) {
|
|
891
|
+
const exiting = this.checkpointMetadata === inputMetadata;
|
|
892
|
+
const doCheckpoint = this.checkpointer != null && (this.checkpointDuring || exiting);
|
|
893
|
+
const storeCheckpoint = (checkpoint) => {
|
|
828
894
|
// store the previous checkpoint config for debug events
|
|
829
895
|
this.prevCheckpointConfig = this.checkpointConfig?.configurable
|
|
830
896
|
?.checkpoint_id
|
|
831
897
|
? this.checkpointConfig
|
|
832
898
|
: undefined;
|
|
833
|
-
// create new checkpoint
|
|
834
|
-
this.checkpointMetadata = metadata;
|
|
835
899
|
// child graphs keep at most one checkpoint per parent checkpoint
|
|
836
900
|
// this is achieved by writing child checkpoints as progress is made
|
|
837
901
|
// (so that error recovery / resuming from interrupt don't lose work)
|
|
838
902
|
// but doing so always with an id equal to that of the parent checkpoint
|
|
839
|
-
this.checkpoint = (0, base_js_1.createCheckpoint)(this.checkpoint, this.channels, this.step);
|
|
840
903
|
this.checkpointConfig = {
|
|
841
904
|
...this.checkpointConfig,
|
|
842
905
|
configurable: {
|
|
@@ -852,7 +915,7 @@ class PregelLoop {
|
|
|
852
915
|
// ensuring checkpointers receive checkpoints in order
|
|
853
916
|
void this._checkpointerPutAfterPrevious({
|
|
854
917
|
config: { ...this.checkpointConfig },
|
|
855
|
-
checkpoint: (0, langgraph_checkpoint_1.copyCheckpoint)(
|
|
918
|
+
checkpoint: (0, langgraph_checkpoint_1.copyCheckpoint)(checkpoint),
|
|
856
919
|
metadata: { ...this.checkpointMetadata },
|
|
857
920
|
newVersions,
|
|
858
921
|
});
|
|
@@ -863,8 +926,59 @@ class PregelLoop {
|
|
|
863
926
|
checkpoint_id: this.checkpoint.id,
|
|
864
927
|
},
|
|
865
928
|
};
|
|
929
|
+
};
|
|
930
|
+
// We need to retroactively store the previous checkpoint
|
|
931
|
+
// if it turns out that pending sends are scheduled.
|
|
932
|
+
// TODO: remove when `pending_sends` is removed from checkpoints
|
|
933
|
+
if (!exiting &&
|
|
934
|
+
!this.checkpointDuring &&
|
|
935
|
+
this.checkpointer != null &&
|
|
936
|
+
this.prevCheckpoint != null &&
|
|
937
|
+
this.checkpoint.pending_sends.length > 0) {
|
|
938
|
+
storeCheckpoint(this.prevCheckpoint);
|
|
939
|
+
}
|
|
940
|
+
if (!exiting) {
|
|
941
|
+
this.checkpointMetadata = {
|
|
942
|
+
...inputMetadata,
|
|
943
|
+
step: this.step,
|
|
944
|
+
parents: this.config.configurable?.[constants_js_1.CONFIG_KEY_CHECKPOINT_MAP] ?? {},
|
|
945
|
+
};
|
|
946
|
+
}
|
|
947
|
+
// Store previous checkpoint in case pending_sends are scheduled
|
|
948
|
+
// for next checkpoint.
|
|
949
|
+
if (!this.checkpointDuring) {
|
|
950
|
+
this.prevCheckpoint = this.checkpoint;
|
|
951
|
+
}
|
|
952
|
+
// create new checkpoint
|
|
953
|
+
this.checkpoint = (0, base_js_1.createCheckpoint)(this.checkpoint, doCheckpoint ? this.channels : undefined, this.step, exiting ? { id: this.checkpoint.id } : undefined);
|
|
954
|
+
// Bail if no checkpointer
|
|
955
|
+
if (doCheckpoint)
|
|
956
|
+
storeCheckpoint(this.checkpoint);
|
|
957
|
+
if (!exiting) {
|
|
958
|
+
// increment step
|
|
959
|
+
this.step += 1;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
_flushPendingWrites() {
|
|
963
|
+
if (this.checkpointer == null)
|
|
964
|
+
return;
|
|
965
|
+
if (this.checkpointPendingWrites.length === 0)
|
|
966
|
+
return;
|
|
967
|
+
// patch config
|
|
968
|
+
const config = (0, index_js_1.patchConfigurable)(this.checkpointConfig, {
|
|
969
|
+
[constants_js_1.CONFIG_KEY_CHECKPOINT_NS]: this.config.configurable?.checkpoint_ns ?? "",
|
|
970
|
+
[constants_js_1.CONFIG_KEY_CHECKPOINT_ID]: this.checkpoint.id,
|
|
971
|
+
});
|
|
972
|
+
// group writes by task id
|
|
973
|
+
const byTask = {};
|
|
974
|
+
for (const [tid, key, value] of this.checkpointPendingWrites) {
|
|
975
|
+
byTask[tid] ??= [];
|
|
976
|
+
byTask[tid].push([key, value]);
|
|
977
|
+
}
|
|
978
|
+
// submit writes to checkpointer
|
|
979
|
+
for (const [tid, ws] of Object.entries(byTask)) {
|
|
980
|
+
this.checkpointerPromises.push(this.checkpointer.putWrites(config, ws, tid));
|
|
866
981
|
}
|
|
867
|
-
this.step += 1;
|
|
868
982
|
}
|
|
869
983
|
_matchWrites(tasks) {
|
|
870
984
|
for (const [tid, k, v] of this.checkpointPendingWrites) {
|
package/dist/pregel/loop.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export type PregelLoopInitializeParams = {
|
|
|
22
22
|
cache?: BaseCache<PendingWrite<string>[]>;
|
|
23
23
|
interruptAfter: string[] | All;
|
|
24
24
|
interruptBefore: string[] | All;
|
|
25
|
+
checkpointDuring: boolean;
|
|
25
26
|
manager?: CallbackManagerForChainRun;
|
|
26
27
|
debug: boolean;
|
|
27
28
|
triggerToNodes: Record<string, string[]>;
|
|
@@ -52,6 +53,7 @@ type PregelLoopParams = {
|
|
|
52
53
|
prevCheckpointConfig: RunnableConfig | undefined;
|
|
53
54
|
interruptAfter: string[] | All;
|
|
54
55
|
interruptBefore: string[] | All;
|
|
56
|
+
checkpointDuring: boolean;
|
|
55
57
|
debug: boolean;
|
|
56
58
|
triggerToNodes: Record<string, string[]>;
|
|
57
59
|
};
|
|
@@ -81,6 +83,7 @@ export declare class PregelLoop {
|
|
|
81
83
|
channels: Record<string, BaseChannel>;
|
|
82
84
|
managed: ManagedValueMapping;
|
|
83
85
|
protected checkpoint: Checkpoint;
|
|
86
|
+
protected checkpointIdSaved: string | undefined;
|
|
84
87
|
protected checkpointConfig: RunnableConfig;
|
|
85
88
|
checkpointMetadata: CheckpointMetadata;
|
|
86
89
|
protected checkpointNamespace: string[];
|
|
@@ -88,11 +91,13 @@ export declare class PregelLoop {
|
|
|
88
91
|
protected checkpointPreviousVersions: Record<string, string | number>;
|
|
89
92
|
step: number;
|
|
90
93
|
protected stop: number;
|
|
94
|
+
protected checkpointDuring: boolean;
|
|
91
95
|
protected outputKeys: string | string[];
|
|
92
96
|
protected streamKeys: string | string[];
|
|
93
97
|
protected nodes: Record<string, PregelNode>;
|
|
94
98
|
protected skipDoneTasks: boolean;
|
|
95
99
|
protected prevCheckpointConfig: RunnableConfig | undefined;
|
|
100
|
+
protected prevCheckpoint: Checkpoint | undefined;
|
|
96
101
|
status: "pending" | "done" | "interrupt_before" | "interrupt_after" | "out_of_steps";
|
|
97
102
|
tasks: Record<string, PregelExecutableTask<any, any>>;
|
|
98
103
|
stream: IterableReadableWritableStream;
|
|
@@ -141,7 +146,8 @@ export declare class PregelLoop {
|
|
|
141
146
|
protected _suppressInterrupt(e?: Error): boolean;
|
|
142
147
|
protected _first(inputKeys: string | string[]): Promise<void>;
|
|
143
148
|
protected _emit(values: [StreamMode, unknown][]): void;
|
|
144
|
-
protected _putCheckpoint(inputMetadata: Omit<CheckpointMetadata, "step" | "parents">):
|
|
149
|
+
protected _putCheckpoint(inputMetadata: Omit<CheckpointMetadata, "step" | "parents">): void;
|
|
150
|
+
protected _flushPendingWrites(): void;
|
|
145
151
|
protected _matchWrites(tasks: Record<string, PregelExecutableTask<string, string>>): void;
|
|
146
152
|
}
|
|
147
153
|
export {};
|