@langchain/langgraph 0.2.19 → 0.2.20

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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._isSend = exports.Send = exports._isSendInterface = exports.CHECKPOINT_NAMESPACE_END = exports.CHECKPOINT_NAMESPACE_SEPARATOR = exports.RESERVED = exports.TASK_NAMESPACE = exports.PULL = exports.PUSH = exports.TASKS = exports.TAG_HIDDEN = exports.RECURSION_LIMIT_DEFAULT = exports.RUNTIME_PLACEHOLDER = exports.INTERRUPT = exports.CONFIG_KEY_CHECKPOINT_MAP = exports.CONFIG_KEY_STREAM = exports.CONFIG_KEY_TASK_ID = exports.CONFIG_KEY_RESUMING = exports.CONFIG_KEY_CHECKPOINTER = exports.CONFIG_KEY_READ = exports.CONFIG_KEY_SEND = exports.ERROR = exports.INPUT = void 0;
3
+ exports._isSend = exports.Send = exports._isSendInterface = exports.CHECKPOINT_NAMESPACE_END = exports.CHECKPOINT_NAMESPACE_SEPARATOR = exports.RESERVED = exports.TASK_NAMESPACE = exports.PULL = exports.PUSH = exports.TASKS = exports.TAG_NOSTREAM = exports.TAG_HIDDEN = exports.RECURSION_LIMIT_DEFAULT = exports.RUNTIME_PLACEHOLDER = exports.INTERRUPT = exports.CONFIG_KEY_CHECKPOINT_MAP = exports.CONFIG_KEY_STREAM = exports.CONFIG_KEY_TASK_ID = exports.CONFIG_KEY_RESUMING = exports.CONFIG_KEY_CHECKPOINTER = exports.CONFIG_KEY_READ = exports.CONFIG_KEY_SEND = exports.ERROR = exports.INPUT = void 0;
4
4
  exports.INPUT = "__input__";
5
5
  exports.ERROR = "__error__";
6
6
  exports.CONFIG_KEY_SEND = "__pregel_send";
@@ -15,6 +15,7 @@ exports.INTERRUPT = "__interrupt__";
15
15
  exports.RUNTIME_PLACEHOLDER = "__pregel_runtime_placeholder__";
16
16
  exports.RECURSION_LIMIT_DEFAULT = 25;
17
17
  exports.TAG_HIDDEN = "langsmith:hidden";
18
+ exports.TAG_NOSTREAM = "langsmith:nostream";
18
19
  exports.TASKS = "__pregel_tasks";
19
20
  exports.PUSH = "__pregel_push";
20
21
  exports.PULL = "__pregel_pull";
@@ -11,6 +11,7 @@ export declare const INTERRUPT = "__interrupt__";
11
11
  export declare const RUNTIME_PLACEHOLDER = "__pregel_runtime_placeholder__";
12
12
  export declare const RECURSION_LIMIT_DEFAULT = 25;
13
13
  export declare const TAG_HIDDEN = "langsmith:hidden";
14
+ export declare const TAG_NOSTREAM = "langsmith:nostream";
14
15
  export declare const TASKS = "__pregel_tasks";
15
16
  export declare const PUSH = "__pregel_push";
16
17
  export declare const PULL = "__pregel_pull";
package/dist/constants.js CHANGED
@@ -12,6 +12,7 @@ export const INTERRUPT = "__interrupt__";
12
12
  export const RUNTIME_PLACEHOLDER = "__pregel_runtime_placeholder__";
13
13
  export const RECURSION_LIMIT_DEFAULT = 25;
14
14
  export const TAG_HIDDEN = "langsmith:hidden";
15
+ export const TAG_NOSTREAM = "langsmith:nostream";
15
16
  export const TASKS = "__pregel_tasks";
16
17
  export const PUSH = "__pregel_push";
17
18
  export const PULL = "__pregel_pull";
@@ -377,7 +377,7 @@ function _prepareSingleTask(taskPath, checkpoint, processes, channels, managed,
377
377
  config: (0, runnables_1.patchConfig)((0, runnables_1.mergeConfigs)(config, {
378
378
  metadata,
379
379
  tags: proc.tags,
380
- store: extra.store ?? config?.store,
380
+ store: extra.store ?? config.store,
381
381
  }), {
382
382
  runName: name,
383
383
  callbacks: manager?.getChild(`graph:step:${step}`),
@@ -368,7 +368,7 @@ export function _prepareSingleTask(taskPath, checkpoint, processes, channels, ma
368
368
  config: patchConfig(mergeConfigs(config, {
369
369
  metadata,
370
370
  tags: proc.tags,
371
- store: extra.store ?? config?.store,
371
+ store: extra.store ?? config.store,
372
372
  }), {
373
373
  runName: name,
374
374
  callbacks: manager?.getChild(`graph:step:${step}`),
@@ -1,13 +1,9 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.Pregel = exports.Channel = void 0;
7
4
  /* eslint-disable no-param-reassign */
8
5
  const runnables_1 = require("@langchain/core/runnables");
9
6
  const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
10
- const double_ended_queue_1 = __importDefault(require("double-ended-queue"));
11
7
  const base_js_1 = require("../channels/base.cjs");
12
8
  const read_js_1 = require("./read.cjs");
13
9
  const validate_js_1 = require("./validate.cjs");
@@ -24,6 +20,7 @@ const retry_js_1 = require("./retry.cjs");
24
20
  const base_js_2 = require("../managed/base.cjs");
25
21
  const utils_js_1 = require("../utils.cjs");
26
22
  const config_js_1 = require("./utils/config.cjs");
23
+ const messages_js_1 = require("./messages.cjs");
27
24
  function isString(value) {
28
25
  return typeof value === "string";
29
26
  }
@@ -579,6 +576,7 @@ class Pregel extends runnables_1.Runnable {
579
576
  }
580
577
  _defaults(config) {
581
578
  const { debug, streamMode, inputKeys, outputKeys, interruptAfter, interruptBefore, ...rest } = config;
579
+ let streamModeSingle = true;
582
580
  const defaultDebug = debug !== undefined ? debug : this.debug;
583
581
  let defaultOutputKeys = outputKeys;
584
582
  if (defaultOutputKeys === undefined) {
@@ -599,9 +597,11 @@ class Pregel extends runnables_1.Runnable {
599
597
  let defaultStreamMode;
600
598
  if (streamMode !== undefined) {
601
599
  defaultStreamMode = Array.isArray(streamMode) ? streamMode : [streamMode];
600
+ streamModeSingle = typeof streamMode === "string";
602
601
  }
603
602
  else {
604
603
  defaultStreamMode = this.streamMode;
604
+ streamModeSingle = true;
605
605
  }
606
606
  // if being called as a node in another graph, always use values mode
607
607
  if (config.configurable?.[constants_js_1.CONFIG_KEY_TASK_ID] !== undefined) {
@@ -629,6 +629,7 @@ class Pregel extends runnables_1.Runnable {
629
629
  defaultInterruptAfter,
630
630
  defaultCheckpointer,
631
631
  defaultStore,
632
+ streamModeSingle,
632
633
  ];
633
634
  }
634
635
  /**
@@ -705,135 +706,180 @@ class Pregel extends runnables_1.Runnable {
705
706
  inputConfig.configurable === undefined) {
706
707
  throw new Error(`Checkpointer requires one or more of the following "configurable" keys: "thread_id", "checkpoint_ns", "checkpoint_id"`);
707
708
  }
708
- const callbackManager = await (0, runnables_1.getCallbackManagerForConfig)(inputConfig);
709
- const runManager = await callbackManager?.handleChainStart(this.toJSON(), (0, index_js_1._coerceToDict)(input, "input"), inputConfig.runId, undefined, undefined, undefined, inputConfig?.runName ?? this.getName());
710
- delete inputConfig.runId;
709
+ const { runId, ...restConfig } = inputConfig;
711
710
  // assign defaults
712
- const [debug, streamMode, , outputKeys, config, interruptBefore, interruptAfter, checkpointer, store,] = this._defaults(inputConfig);
711
+ const [debug, streamMode, , outputKeys, config, interruptBefore, interruptAfter, checkpointer, store, streamModeSingle,] = this._defaults(restConfig);
712
+ const stream = new loop_js_1.IterableReadableWritableStream({
713
+ modes: new Set(streamMode),
714
+ });
715
+ // set up messages stream mode
716
+ if (streamMode.includes("messages")) {
717
+ const messageStreamer = new messages_js_1.StreamMessagesHandler((chunk) => stream.push(chunk));
718
+ const { callbacks } = config;
719
+ if (callbacks === undefined) {
720
+ config.callbacks = [messageStreamer];
721
+ }
722
+ else if (Array.isArray(callbacks)) {
723
+ config.callbacks = callbacks.concat(messageStreamer);
724
+ }
725
+ else {
726
+ const copiedCallbacks = callbacks.copy();
727
+ copiedCallbacks.addHandler(messageStreamer, true);
728
+ config.callbacks = copiedCallbacks;
729
+ }
730
+ }
731
+ // setup custom stream mode
732
+ if (streamMode.includes("custom")) {
733
+ config.writer = (chunk) => stream.push([[], "custom", chunk]);
734
+ }
735
+ const callbackManager = await (0, runnables_1.getCallbackManagerForConfig)(config);
736
+ const runManager = await callbackManager?.handleChainStart(this.toJSON(), (0, index_js_1._coerceToDict)(input, "input"), runId, undefined, undefined, undefined, config?.runName ?? this.getName());
713
737
  const { channelSpecs, managed } = await this.prepareSpecs(config);
714
738
  let loop;
715
- const stream = new double_ended_queue_1.default();
716
- function* emitCurrentLoopOutputs() {
717
- while (loop !== undefined && stream.length > 0) {
718
- const nextItem = stream.shift();
719
- if (nextItem === undefined) {
720
- throw new Error("Data structure error.");
739
+ let loopError;
740
+ const runLoop = async () => {
741
+ try {
742
+ loop = await loop_js_1.PregelLoop.initialize({
743
+ input,
744
+ config,
745
+ checkpointer,
746
+ nodes: this.nodes,
747
+ channelSpecs,
748
+ managed,
749
+ outputKeys,
750
+ streamKeys: this.streamChannelsAsIs,
751
+ store,
752
+ stream,
753
+ });
754
+ if (options?.subgraphs) {
755
+ loop.config.configurable = {
756
+ ...loop.config.configurable,
757
+ [constants_js_1.CONFIG_KEY_STREAM]: loop.stream,
758
+ };
721
759
  }
722
- const [namespace, mode, payload] = nextItem;
723
- if (streamMode.includes(mode)) {
724
- if (streamSubgraphs && streamMode.length > 1) {
725
- yield [namespace, mode, payload];
726
- }
727
- else if (streamMode.length > 1) {
728
- yield [mode, payload];
729
- }
730
- else if (streamSubgraphs) {
731
- yield [namespace, payload];
760
+ while (await loop.tick({
761
+ inputKeys: this.inputChannels,
762
+ interruptAfter,
763
+ interruptBefore,
764
+ manager: runManager,
765
+ })) {
766
+ if (debug) {
767
+ (0, debug_js_1.printStepCheckpoint)(loop.checkpointMetadata.step, loop.channels, this.streamChannelsList);
732
768
  }
733
- else {
734
- yield payload;
769
+ if (debug) {
770
+ (0, debug_js_1.printStepTasks)(loop.step, Object.values(loop.tasks));
735
771
  }
736
- }
737
- }
738
- }
739
- try {
740
- loop = await loop_js_1.PregelLoop.initialize({
741
- input,
742
- config,
743
- checkpointer,
744
- nodes: this.nodes,
745
- channelSpecs,
746
- managed,
747
- outputKeys,
748
- streamKeys: this.streamChannelsAsIs,
749
- store,
750
- stream: new loop_js_1.StreamProtocol((chunk) => stream.push(chunk), new Set(streamMode)),
751
- });
752
- if (options?.subgraphs) {
753
- loop.config.configurable = {
754
- ...loop.config.configurable,
755
- [constants_js_1.CONFIG_KEY_STREAM]: loop.stream,
756
- };
757
- }
758
- while (await loop.tick({
759
- inputKeys: this.inputChannels,
760
- interruptAfter,
761
- interruptBefore,
762
- manager: runManager,
763
- })) {
764
- if (debug) {
765
- (0, debug_js_1.printStepCheckpoint)(loop.checkpointMetadata.step, loop.channels, this.streamChannelsList);
766
- }
767
- yield* emitCurrentLoopOutputs();
768
- if (debug) {
769
- (0, debug_js_1.printStepTasks)(loop.step, Object.values(loop.tasks));
770
- }
771
- // execute tasks, and wait for one to fail or all to finish.
772
- // each task is independent from all other concurrent tasks
773
- // yield updates/debug output as each task finishes
774
- const taskStream = (0, retry_js_1.executeTasksWithRetry)(Object.values(loop.tasks).filter((task) => task.writes.length === 0), {
775
- stepTimeout: this.stepTimeout,
776
- signal: config.signal,
777
- retryPolicy: this.retryPolicy,
778
- });
779
- // Timeouts will be thrown
780
- for await (const { task, error } of taskStream) {
781
- if (error !== undefined) {
782
- if ((0, errors_js_1.isGraphInterrupt)(error)) {
783
- if (loop.isNested) {
784
- throw error;
772
+ // execute tasks, and wait for one to fail or all to finish.
773
+ // each task is independent from all other concurrent tasks
774
+ // yield updates/debug output as each task finishes
775
+ const taskStream = (0, retry_js_1.executeTasksWithRetry)(Object.values(loop.tasks).filter((task) => task.writes.length === 0), {
776
+ stepTimeout: this.stepTimeout,
777
+ signal: config.signal,
778
+ retryPolicy: this.retryPolicy,
779
+ });
780
+ // Timeouts will be thrown
781
+ for await (const { task, error } of taskStream) {
782
+ if (error !== undefined) {
783
+ if ((0, errors_js_1.isGraphInterrupt)(error)) {
784
+ if (loop.isNested) {
785
+ throw error;
786
+ }
787
+ if (error.interrupts.length) {
788
+ loop.putWrites(task.id, error.interrupts.map((interrupt) => [constants_js_1.INTERRUPT, interrupt]));
789
+ }
785
790
  }
786
- if (error.interrupts.length) {
787
- loop.putWrites(task.id, error.interrupts.map((interrupt) => [constants_js_1.INTERRUPT, interrupt]));
791
+ else {
792
+ loop.putWrites(task.id, [
793
+ [constants_js_1.ERROR, { message: error.message, name: error.name }],
794
+ ]);
788
795
  }
789
796
  }
790
797
  else {
791
- loop.putWrites(task.id, [
792
- [constants_js_1.ERROR, { message: error.message, name: error.name }],
793
- ]);
798
+ loop.putWrites(task.id, task.writes);
799
+ }
800
+ if (error !== undefined && !(0, errors_js_1.isGraphInterrupt)(error)) {
801
+ throw error;
794
802
  }
795
803
  }
796
- else {
797
- loop.putWrites(task.id, task.writes);
804
+ if (debug) {
805
+ (0, debug_js_1.printStepWrites)(loop.step, Object.values(loop.tasks)
806
+ .map((task) => task.writes)
807
+ .flat(), this.streamChannelsList);
798
808
  }
799
- yield* emitCurrentLoopOutputs();
800
- if (error !== undefined && !(0, errors_js_1.isGraphInterrupt)(error)) {
801
- throw error;
809
+ }
810
+ if (loop.status === "out_of_steps") {
811
+ throw new errors_js_1.GraphRecursionError([
812
+ `Recursion limit of ${config.recursionLimit} reached`,
813
+ "without hitting a stop condition. You can increase the",
814
+ `limit by setting the "recursionLimit" config key.`,
815
+ ].join(" "), {
816
+ lc_error_code: "GRAPH_RECURSION_LIMIT",
817
+ });
818
+ }
819
+ }
820
+ catch (e) {
821
+ loopError = e;
822
+ }
823
+ finally {
824
+ try {
825
+ // Call `.stop()` again incase it was not called in the loop, e.g due to an error.
826
+ if (loop) {
827
+ await loop.store?.stop();
802
828
  }
829
+ await Promise.all([
830
+ ...(loop?.checkpointerPromises ?? []),
831
+ ...Array.from(managed.values()).map((mv) => mv.promises()),
832
+ ]);
803
833
  }
804
- if (debug) {
805
- (0, debug_js_1.printStepWrites)(loop.step, Object.values(loop.tasks)
806
- .map((task) => task.writes)
807
- .flat(), this.streamChannelsList);
834
+ catch (e) {
835
+ loopError = loopError ?? e;
836
+ }
837
+ if (loopError) {
838
+ // "Causes any future interactions with the associated stream to error".
839
+ // Wraps ReadableStreamDefaultController#error:
840
+ // https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamDefaultController/error
841
+ stream.error(loopError);
842
+ }
843
+ else {
844
+ // Will end the iterator outside of this method,
845
+ // keeping previously enqueued chunks.
846
+ // Wraps ReadableStreamDefaultController#close:
847
+ // https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamDefaultController/close
848
+ stream.close();
808
849
  }
809
850
  }
810
- yield* emitCurrentLoopOutputs();
811
- if (loop.status === "out_of_steps") {
812
- throw new errors_js_1.GraphRecursionError([
813
- `Recursion limit of ${config.recursionLimit} reached`,
814
- "without hitting a stop condition. You can increase the",
815
- `limit by setting the "recursionLimit" config key.`,
816
- ].join(" "), {
817
- lc_error_code: "GRAPH_RECURSION_LIMIT",
818
- });
851
+ };
852
+ const runLoopPromise = runLoop();
853
+ try {
854
+ for await (const chunk of stream) {
855
+ if (chunk === undefined) {
856
+ throw new Error("Data structure error.");
857
+ }
858
+ const [namespace, mode, payload] = chunk;
859
+ if (streamMode.includes(mode)) {
860
+ if (streamSubgraphs && !streamModeSingle) {
861
+ yield [namespace, mode, payload];
862
+ }
863
+ else if (!streamModeSingle) {
864
+ yield [mode, payload];
865
+ }
866
+ else if (streamSubgraphs) {
867
+ yield [namespace, payload];
868
+ }
869
+ else {
870
+ yield payload;
871
+ }
872
+ }
819
873
  }
820
- await Promise.all(loop?.checkpointerPromises ?? []);
821
- await runManager?.handleChainEnd(loop.output);
822
874
  }
823
875
  catch (e) {
824
- await runManager?.handleChainError(e);
876
+ await runManager?.handleChainError(loopError);
825
877
  throw e;
826
878
  }
827
879
  finally {
828
- // Call `.stop()` again incase it was not called in the loop, e.g due to an error.
829
- if (loop) {
830
- await loop.store?.stop();
831
- }
832
- await Promise.all([
833
- ...(loop?.checkpointerPromises ?? []),
834
- ...Array.from(managed.values()).map((mv) => mv.promises()),
835
- ]);
880
+ await runLoopPromise;
836
881
  }
882
+ await runManager?.handleChainEnd(loop?.output ?? {});
837
883
  }
838
884
  /**
839
885
  * Run the graph with a single input and config.
@@ -77,14 +77,15 @@ export declare class Pregel<Nn extends StrRecord<string, PregelNode>, Cc extends
77
77
  string | string[],
78
78
  // input keys
79
79
  string | string[],
80
- RunnableConfig,
80
+ LangGraphRunnableConfig,
81
81
  // config without pregel keys
82
82
  All | string[],
83
83
  // interrupt before
84
84
  All | string[],
85
85
  // interrupt after
86
86
  BaseCheckpointSaver | undefined,
87
- BaseStore | undefined
87
+ BaseStore | undefined,
88
+ boolean
88
89
  ];
89
90
  /**
90
91
  * Stream graph steps for a single input.