@langchain/langgraph 0.0.10 → 0.0.12

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.
@@ -7,6 +7,15 @@ export function emptyCheckpoint() {
7
7
  versionsSeen: {},
8
8
  };
9
9
  }
10
+ export function copyCheckpoint(checkpoint) {
11
+ return {
12
+ v: checkpoint.v,
13
+ ts: checkpoint.ts,
14
+ channelValues: { ...checkpoint.channelValues },
15
+ channelVersions: { ...checkpoint.channelVersions },
16
+ versionsSeen: { ...checkpoint.versionsSeen },
17
+ };
18
+ }
10
19
  export class BaseCheckpointSaver {
11
20
  constructor() {
12
21
  Object.defineProperty(this, "at", {
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BaseCheckpointSaver = exports.emptyCheckpoint = exports.MemorySaver = void 0;
3
+ exports.BaseCheckpointSaver = exports.emptyCheckpoint = exports.MemorySaverAssertImmutable = exports.MemorySaver = void 0;
4
4
  var memory_js_1 = require("./memory.cjs");
5
5
  Object.defineProperty(exports, "MemorySaver", { enumerable: true, get: function () { return memory_js_1.MemorySaver; } });
6
+ Object.defineProperty(exports, "MemorySaverAssertImmutable", { enumerable: true, get: function () { return memory_js_1.MemorySaverAssertImmutable; } });
6
7
  var base_js_1 = require("./base.cjs");
7
8
  Object.defineProperty(exports, "emptyCheckpoint", { enumerable: true, get: function () { return base_js_1.emptyCheckpoint; } });
8
9
  Object.defineProperty(exports, "BaseCheckpointSaver", { enumerable: true, get: function () { return base_js_1.BaseCheckpointSaver; } });
@@ -1,2 +1,2 @@
1
- export { MemorySaver } from "./memory.js";
1
+ export { MemorySaver, MemorySaverAssertImmutable } from "./memory.js";
2
2
  export { type ConfigurableFieldSpec, type Checkpoint, type CheckpointAt, emptyCheckpoint, BaseCheckpointSaver, } from "./base.js";
@@ -1,2 +1,2 @@
1
- export { MemorySaver } from "./memory.js";
1
+ export { MemorySaver, MemorySaverAssertImmutable } from "./memory.js";
2
2
  export { emptyCheckpoint, BaseCheckpointSaver, } from "./base.js";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MemorySaver = void 0;
3
+ exports.MemorySaverAssertImmutable = exports.MemorySaver = void 0;
4
4
  const base_js_1 = require("./base.cjs");
5
5
  class MemorySaver extends base_js_1.BaseCheckpointSaver {
6
6
  constructor() {
@@ -33,3 +33,33 @@ class MemorySaver extends base_js_1.BaseCheckpointSaver {
33
33
  }
34
34
  }
35
35
  exports.MemorySaver = MemorySaver;
36
+ class MemorySaverAssertImmutable extends MemorySaver {
37
+ constructor() {
38
+ super();
39
+ Object.defineProperty(this, "storageForCopies", {
40
+ enumerable: true,
41
+ configurable: true,
42
+ writable: true,
43
+ value: {}
44
+ });
45
+ this.storageForCopies = {};
46
+ this.at = "end_of_step" /* CheckpointAt.END_OF_STEP */;
47
+ }
48
+ put(config, checkpoint) {
49
+ const threadId = config.configurable?.threadId;
50
+ if (!this.storageForCopies[threadId]) {
51
+ this.storageForCopies[threadId] = {};
52
+ }
53
+ // assert checkpoint hasn't been modified since last written
54
+ const saved = super.get(config);
55
+ if (saved) {
56
+ const savedTs = saved.ts;
57
+ if (this.storageForCopies[threadId][savedTs]) {
58
+ console.assert(this.storageForCopies[threadId][savedTs] === saved, "Checkpoint has been modified");
59
+ }
60
+ }
61
+ this.storageForCopies[threadId][checkpoint.ts] = (0, base_js_1.copyCheckpoint)(checkpoint);
62
+ return super.put(config, checkpoint);
63
+ }
64
+ }
65
+ exports.MemorySaverAssertImmutable = MemorySaverAssertImmutable;
@@ -6,3 +6,8 @@ export declare class MemorySaver extends BaseCheckpointSaver {
6
6
  get(config: RunnableConfig): Checkpoint | undefined;
7
7
  put(config: RunnableConfig, checkpoint: Checkpoint): void;
8
8
  }
9
+ export declare class MemorySaverAssertImmutable extends MemorySaver {
10
+ storageForCopies: Record<string, Record<string, Checkpoint>>;
11
+ constructor();
12
+ put(config: RunnableConfig, checkpoint: Checkpoint): void;
13
+ }
@@ -1,4 +1,4 @@
1
- import { BaseCheckpointSaver, } from "./base.js";
1
+ import { BaseCheckpointSaver, copyCheckpoint, } from "./base.js";
2
2
  export class MemorySaver extends BaseCheckpointSaver {
3
3
  constructor() {
4
4
  super(...arguments);
@@ -29,3 +29,32 @@ export class MemorySaver extends BaseCheckpointSaver {
29
29
  this.storage[config.configurable?.threadId] = checkpoint;
30
30
  }
31
31
  }
32
+ export class MemorySaverAssertImmutable extends MemorySaver {
33
+ constructor() {
34
+ super();
35
+ Object.defineProperty(this, "storageForCopies", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: {}
40
+ });
41
+ this.storageForCopies = {};
42
+ this.at = "end_of_step" /* CheckpointAt.END_OF_STEP */;
43
+ }
44
+ put(config, checkpoint) {
45
+ const threadId = config.configurable?.threadId;
46
+ if (!this.storageForCopies[threadId]) {
47
+ this.storageForCopies[threadId] = {};
48
+ }
49
+ // assert checkpoint hasn't been modified since last written
50
+ const saved = super.get(config);
51
+ if (saved) {
52
+ const savedTs = saved.ts;
53
+ if (this.storageForCopies[threadId][savedTs]) {
54
+ console.assert(this.storageForCopies[threadId][savedTs] === saved, "Checkpoint has been modified");
55
+ }
56
+ }
57
+ this.storageForCopies[threadId][checkpoint.ts] = copyCheckpoint(checkpoint);
58
+ return super.put(config, checkpoint);
59
+ }
60
+ }
@@ -21,9 +21,10 @@ class Branch {
21
21
  this.condition = condition;
22
22
  this.ends = ends;
23
23
  }
24
+ async runnable(
24
25
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
- runnable(input, options) {
26
- const result = this.condition(input, options?.config);
26
+ input, options) {
27
+ const result = await this.condition(input, options?.config);
27
28
  let destination;
28
29
  if (this.ends) {
29
30
  destination = this.ends[result];
@@ -107,9 +108,6 @@ class Graph {
107
108
  if (!this.nodes[startKey]) {
108
109
  throw new Error(`Need to addNode \`${startKey}\` first`);
109
110
  }
110
- if (condition.constructor.name === "AsyncFunction") {
111
- throw new Error("Condition cannot be an async function");
112
- }
113
111
  if (conditionalEdgeMapping) {
114
112
  const mappingValues = Array.from(Object.values(conditionalEdgeMapping));
115
113
  const nodesValues = Object.keys(this.nodes);
@@ -11,7 +11,7 @@ declare class Branch {
11
11
  constructor(condition: CallableFunction, ends?: EndsMap);
12
12
  runnable(input: any, options?: {
13
13
  config?: RunnableConfig;
14
- }): Runnable;
14
+ }): Promise<Runnable>;
15
15
  }
16
16
  export declare class Graph<RunInput = any, RunOutput = any> {
17
17
  nodes: Record<string, Runnable<RunInput, RunOutput>>;
@@ -18,9 +18,10 @@ class Branch {
18
18
  this.condition = condition;
19
19
  this.ends = ends;
20
20
  }
21
+ async runnable(
21
22
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
- runnable(input, options) {
23
- const result = this.condition(input, options?.config);
23
+ input, options) {
24
+ const result = await this.condition(input, options?.config);
24
25
  let destination;
25
26
  if (this.ends) {
26
27
  destination = this.ends[result];
@@ -104,9 +105,6 @@ export class Graph {
104
105
  if (!this.nodes[startKey]) {
105
106
  throw new Error(`Need to addNode \`${startKey}\` first`);
106
107
  }
107
- if (condition.constructor.name === "AsyncFunction") {
108
- throw new Error("Condition cannot be an async function");
109
- }
110
108
  if (conditionalEdgeMapping) {
111
109
  const mappingValues = Array.from(Object.values(conditionalEdgeMapping));
112
110
  const nodesValues = Object.keys(this.nodes);
package/dist/index.cjs CHANGED
@@ -1,9 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MessageGraph = exports.StateGraph = exports.START = exports.Graph = exports.END = void 0;
3
+ exports.BaseCheckpointSaver = exports.emptyCheckpoint = exports.MemorySaverAssertImmutable = exports.MemorySaver = exports.MessageGraph = exports.StateGraph = exports.START = exports.Graph = exports.END = void 0;
4
4
  var index_js_1 = require("./graph/index.cjs");
5
5
  Object.defineProperty(exports, "END", { enumerable: true, get: function () { return index_js_1.END; } });
6
6
  Object.defineProperty(exports, "Graph", { enumerable: true, get: function () { return index_js_1.Graph; } });
7
7
  Object.defineProperty(exports, "START", { enumerable: true, get: function () { return index_js_1.START; } });
8
8
  Object.defineProperty(exports, "StateGraph", { enumerable: true, get: function () { return index_js_1.StateGraph; } });
9
9
  Object.defineProperty(exports, "MessageGraph", { enumerable: true, get: function () { return index_js_1.MessageGraph; } });
10
+ var index_js_2 = require("./checkpoint/index.cjs");
11
+ Object.defineProperty(exports, "MemorySaver", { enumerable: true, get: function () { return index_js_2.MemorySaver; } });
12
+ Object.defineProperty(exports, "MemorySaverAssertImmutable", { enumerable: true, get: function () { return index_js_2.MemorySaverAssertImmutable; } });
13
+ var index_js_3 = require("./checkpoint/index.cjs");
14
+ Object.defineProperty(exports, "emptyCheckpoint", { enumerable: true, get: function () { return index_js_3.emptyCheckpoint; } });
15
+ Object.defineProperty(exports, "BaseCheckpointSaver", { enumerable: true, get: function () { return index_js_3.BaseCheckpointSaver; } });
package/dist/index.d.ts CHANGED
@@ -1 +1,3 @@
1
1
  export { END, Graph, type StateGraphArgs, START, StateGraph, MessageGraph, } from "./graph/index.js";
2
+ export { MemorySaver, MemorySaverAssertImmutable } from "./checkpoint/index.js";
3
+ export { type ConfigurableFieldSpec, type Checkpoint, type CheckpointAt, emptyCheckpoint, BaseCheckpointSaver, } from "./checkpoint/index.js";
package/dist/index.js CHANGED
@@ -1 +1,3 @@
1
1
  export { END, Graph, START, StateGraph, MessageGraph, } from "./graph/index.js";
2
+ export { MemorySaver, MemorySaverAssertImmutable } from "./checkpoint/index.js";
3
+ export { emptyCheckpoint, BaseCheckpointSaver, } from "./checkpoint/index.js";
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ToolExecutor = void 0;
4
4
  const runnables_1 = require("@langchain/core/runnables");
5
- const INVALID_TOOL_MSG_TEMPLATE = `{requestedToolName} is not a valid tool, try one of [availableToolNamesString].`;
5
+ const INVALID_TOOL_MSG_TEMPLATE = `{requestedToolName} is not a valid tool, try one of {availableToolNamesString}.`;
6
6
  class ToolExecutor extends runnables_1.RunnableBinding {
7
7
  constructor(fields) {
8
8
  const fieldsWithDefaults = {
@@ -1,5 +1,5 @@
1
1
  import { RunnableBinding, RunnableLambda, } from "@langchain/core/runnables";
2
- const INVALID_TOOL_MSG_TEMPLATE = `{requestedToolName} is not a valid tool, try one of [availableToolNamesString].`;
2
+ const INVALID_TOOL_MSG_TEMPLATE = `{requestedToolName} is not a valid tool, try one of {availableToolNamesString}.`;
3
3
  export class ToolExecutor extends RunnableBinding {
4
4
  constructor(fields) {
5
5
  const fieldsWithDefaults = {
@@ -56,12 +56,6 @@ class Channel {
56
56
  tags,
57
57
  });
58
58
  }
59
- static subscribeToEach(inbox, key) {
60
- return new read_js_1.ChannelBatch({
61
- channel: inbox,
62
- key,
63
- });
64
- }
65
59
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
60
  static writeTo(...args) {
67
61
  // const channelPairs: Array<[string, WriteValue<RunInput, RunOutput>]> =
@@ -405,72 +399,54 @@ function _prepareNextTasks(checkpoint, processes, channels) {
405
399
  const tasks = [];
406
400
  // Check if any processes should be run in next step
407
401
  // If so, prepare the values to be passed to them
408
- for (const name in processes) {
409
- if (Object.prototype.hasOwnProperty.call(processes, name)) {
410
- const proc = processes[name];
411
- let seen = checkpoint.versionsSeen[name];
412
- if (!seen) {
413
- checkpoint.versionsSeen[name] = {};
414
- seen = checkpoint.versionsSeen[name];
415
- }
416
- if ("triggers" in proc) {
417
- // If any of the channels read by this process were updated
418
- if (proc.triggers.some((chan) => checkpoint.channelVersions[chan] > (seen[chan] ?? 0))) {
419
- // If all channels subscribed by this process have been initialized
420
- try {
421
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
422
- let val = {};
423
- if (typeof proc.channels === "string") {
424
- val[proc.channels] = _readChannel(channels, proc.channels);
425
- }
426
- else {
427
- for (const [k, chan] of Object.entries(proc.channels)) {
428
- val[k] = _readChannel(channels, chan);
429
- }
430
- }
431
- // Processes that subscribe to a single keyless channel get
432
- // the value directly, instead of a dict
433
- if (typeof proc.channels === "string") {
434
- val = val[proc.channels];
435
- }
436
- else if (Object.keys(proc.channels).length === 1 &&
437
- proc.channels[Object.keys(proc.channels)[0]] === undefined) {
438
- val = val[Object.keys(proc.channels)[0]];
439
- }
440
- // Update seen versions
441
- proc.triggers.forEach((chan) => {
442
- const version = checkpoint.channelVersions[chan];
443
- if (version !== undefined) {
444
- seen[chan] = version;
445
- }
446
- });
447
- // skip if condition is not met
448
- if (proc.when === undefined || proc.when(val)) {
449
- tasks.push([proc, val, name]);
450
- }
451
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
452
- }
453
- catch (error) {
454
- if (error.name === base_js_1.EmptyChannelError.name) {
455
- continue;
456
- }
457
- else {
458
- throw error;
459
- }
402
+ for (const [name, proc] of Object.entries(processes)) {
403
+ let seen = checkpoint.versionsSeen[name];
404
+ if (!seen) {
405
+ checkpoint.versionsSeen[name] = {};
406
+ seen = checkpoint.versionsSeen[name];
407
+ }
408
+ // If any of the channels read by this process were updated
409
+ if (proc.triggers.some((chan) => checkpoint.channelVersions[chan] > (seen[chan] ?? 0))) {
410
+ // If all channels subscribed by this process have been initialized
411
+ try {
412
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
413
+ let val = {};
414
+ if (typeof proc.channels === "string") {
415
+ val[proc.channels] = _readChannel(channels, proc.channels);
416
+ }
417
+ else {
418
+ for (const [k, chan] of Object.entries(proc.channels)) {
419
+ val[k] = _readChannel(channels, chan);
460
420
  }
461
421
  }
462
- }
463
- else if ("channel" in proc) {
464
- // If the channel read by this process was updated
465
- if (checkpoint.channelVersions[proc.channel] > (seen[proc.channel] ?? 0)) {
466
- // Here we don't catch EmptyChannelError because the channel
467
- // must be initialized if the previous `if` condition is true
468
- let val = channels[proc.channel].get();
469
- if (proc.key !== undefined) {
470
- val = [{ [proc.key]: val }];
422
+ // Processes that subscribe to a single keyless channel get
423
+ // the value directly, instead of a dict
424
+ if (typeof proc.channels === "string") {
425
+ val = val[proc.channels];
426
+ }
427
+ else if (Object.keys(proc.channels).length === 1 &&
428
+ proc.channels[Object.keys(proc.channels)[0]] === undefined) {
429
+ val = val[Object.keys(proc.channels)[0]];
430
+ }
431
+ // Update seen versions
432
+ proc.triggers.forEach((chan) => {
433
+ const version = checkpoint.channelVersions[chan];
434
+ if (version !== undefined) {
435
+ seen[chan] = version;
471
436
  }
437
+ });
438
+ // skip if condition is not met
439
+ if (proc.when === undefined || proc.when(val)) {
472
440
  tasks.push([proc, val, name]);
473
- seen[proc.channel] = checkpoint.channelVersions[proc.channel];
441
+ }
442
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
443
+ }
444
+ catch (error) {
445
+ if (error.name === base_js_1.EmptyChannelError.name) {
446
+ continue;
447
+ }
448
+ else {
449
+ throw error;
474
450
  }
475
451
  }
476
452
  }
@@ -3,7 +3,7 @@ import { CallbackManagerForChainRun } from "@langchain/core/callbacks/manager";
3
3
  import { IterableReadableStream } from "@langchain/core/utils/stream";
4
4
  import { BaseChannel } from "../channels/base.js";
5
5
  import { BaseCheckpointSaver } from "../checkpoint/base.js";
6
- import { ChannelBatch, ChannelInvoke } from "./read.js";
6
+ import { ChannelInvoke } from "./read.js";
7
7
  import { ChannelWrite } from "./write.js";
8
8
  export declare class GraphRecursionError extends Error {
9
9
  constructor(message?: string);
@@ -19,7 +19,6 @@ export declare class Channel {
19
19
  when?: (arg: any) => boolean;
20
20
  tags?: string[];
21
21
  }): ChannelInvoke;
22
- static subscribeToEach(inbox: string, key?: string): ChannelBatch;
23
22
  static writeTo(...args: any[]): ChannelWrite;
24
23
  }
25
24
  export interface PregelInterface {
@@ -47,7 +46,7 @@ export interface PregelInterface {
47
46
  * @default []
48
47
  */
49
48
  interrupt?: string[];
50
- nodes: Record<string, ChannelInvoke | ChannelBatch>;
49
+ nodes: Record<string, ChannelInvoke>;
51
50
  checkpointer?: BaseCheckpointSaver;
52
51
  stepTimeout?: number;
53
52
  }
@@ -64,7 +63,7 @@ export declare class Pregel extends Runnable<PregelInputType, PregelOutputType,
64
63
  input: string | Array<string>;
65
64
  hidden: Array<string>;
66
65
  debug: boolean;
67
- nodes: Record<string, ChannelInvoke | ChannelBatch>;
66
+ nodes: Record<string, ChannelInvoke>;
68
67
  checkpointer?: BaseCheckpointSaver;
69
68
  stepTimeout?: number;
70
69
  interrupt: string[];
@@ -3,7 +3,7 @@ import { Runnable, _coerceToRunnable, ensureConfig, patchConfig, } from "@langch
3
3
  import { IterableReadableStream } from "@langchain/core/utils/stream";
4
4
  import { EmptyChannelError, createCheckpoint, emptyChannels, } from "../channels/base.js";
5
5
  import { emptyCheckpoint, } from "../checkpoint/base.js";
6
- import { ChannelBatch, ChannelInvoke } from "./read.js";
6
+ import { ChannelInvoke } from "./read.js";
7
7
  import { validateGraph } from "./validate.js";
8
8
  import { ReservedChannelsMap } from "./reserved.js";
9
9
  import { mapInput, mapOutput } from "./io.js";
@@ -52,12 +52,6 @@ export class Channel {
52
52
  tags,
53
53
  });
54
54
  }
55
- static subscribeToEach(inbox, key) {
56
- return new ChannelBatch({
57
- channel: inbox,
58
- key,
59
- });
60
- }
61
55
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
56
  static writeTo(...args) {
63
57
  // const channelPairs: Array<[string, WriteValue<RunInput, RunOutput>]> =
@@ -399,72 +393,54 @@ function _prepareNextTasks(checkpoint, processes, channels) {
399
393
  const tasks = [];
400
394
  // Check if any processes should be run in next step
401
395
  // If so, prepare the values to be passed to them
402
- for (const name in processes) {
403
- if (Object.prototype.hasOwnProperty.call(processes, name)) {
404
- const proc = processes[name];
405
- let seen = checkpoint.versionsSeen[name];
406
- if (!seen) {
407
- checkpoint.versionsSeen[name] = {};
408
- seen = checkpoint.versionsSeen[name];
409
- }
410
- if ("triggers" in proc) {
411
- // If any of the channels read by this process were updated
412
- if (proc.triggers.some((chan) => checkpoint.channelVersions[chan] > (seen[chan] ?? 0))) {
413
- // If all channels subscribed by this process have been initialized
414
- try {
415
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
416
- let val = {};
417
- if (typeof proc.channels === "string") {
418
- val[proc.channels] = _readChannel(channels, proc.channels);
419
- }
420
- else {
421
- for (const [k, chan] of Object.entries(proc.channels)) {
422
- val[k] = _readChannel(channels, chan);
423
- }
424
- }
425
- // Processes that subscribe to a single keyless channel get
426
- // the value directly, instead of a dict
427
- if (typeof proc.channels === "string") {
428
- val = val[proc.channels];
429
- }
430
- else if (Object.keys(proc.channels).length === 1 &&
431
- proc.channels[Object.keys(proc.channels)[0]] === undefined) {
432
- val = val[Object.keys(proc.channels)[0]];
433
- }
434
- // Update seen versions
435
- proc.triggers.forEach((chan) => {
436
- const version = checkpoint.channelVersions[chan];
437
- if (version !== undefined) {
438
- seen[chan] = version;
439
- }
440
- });
441
- // skip if condition is not met
442
- if (proc.when === undefined || proc.when(val)) {
443
- tasks.push([proc, val, name]);
444
- }
445
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
446
- }
447
- catch (error) {
448
- if (error.name === EmptyChannelError.name) {
449
- continue;
450
- }
451
- else {
452
- throw error;
453
- }
396
+ for (const [name, proc] of Object.entries(processes)) {
397
+ let seen = checkpoint.versionsSeen[name];
398
+ if (!seen) {
399
+ checkpoint.versionsSeen[name] = {};
400
+ seen = checkpoint.versionsSeen[name];
401
+ }
402
+ // If any of the channels read by this process were updated
403
+ if (proc.triggers.some((chan) => checkpoint.channelVersions[chan] > (seen[chan] ?? 0))) {
404
+ // If all channels subscribed by this process have been initialized
405
+ try {
406
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
407
+ let val = {};
408
+ if (typeof proc.channels === "string") {
409
+ val[proc.channels] = _readChannel(channels, proc.channels);
410
+ }
411
+ else {
412
+ for (const [k, chan] of Object.entries(proc.channels)) {
413
+ val[k] = _readChannel(channels, chan);
454
414
  }
455
415
  }
456
- }
457
- else if ("channel" in proc) {
458
- // If the channel read by this process was updated
459
- if (checkpoint.channelVersions[proc.channel] > (seen[proc.channel] ?? 0)) {
460
- // Here we don't catch EmptyChannelError because the channel
461
- // must be initialized if the previous `if` condition is true
462
- let val = channels[proc.channel].get();
463
- if (proc.key !== undefined) {
464
- val = [{ [proc.key]: val }];
416
+ // Processes that subscribe to a single keyless channel get
417
+ // the value directly, instead of a dict
418
+ if (typeof proc.channels === "string") {
419
+ val = val[proc.channels];
420
+ }
421
+ else if (Object.keys(proc.channels).length === 1 &&
422
+ proc.channels[Object.keys(proc.channels)[0]] === undefined) {
423
+ val = val[Object.keys(proc.channels)[0]];
424
+ }
425
+ // Update seen versions
426
+ proc.triggers.forEach((chan) => {
427
+ const version = checkpoint.channelVersions[chan];
428
+ if (version !== undefined) {
429
+ seen[chan] = version;
465
430
  }
431
+ });
432
+ // skip if condition is not met
433
+ if (proc.when === undefined || proc.when(val)) {
466
434
  tasks.push([proc, val, name]);
467
- seen[proc.channel] = checkpoint.channelVersions[proc.channel];
435
+ }
436
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
437
+ }
438
+ catch (error) {
439
+ if (error.name === EmptyChannelError.name) {
440
+ continue;
441
+ }
442
+ else {
443
+ throw error;
468
444
  }
469
445
  }
470
446
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ChannelBatch = exports.ChannelInvoke = exports.ChannelRead = void 0;
3
+ exports.ChannelInvoke = exports.ChannelRead = void 0;
4
4
  const runnables_1 = require("@langchain/core/runnables");
5
5
  const constants_js_1 = require("../constants.cjs");
6
6
  class ChannelRead extends runnables_1.RunnableLambda {
@@ -144,74 +144,3 @@ class ChannelInvoke extends runnables_1.RunnableBinding {
144
144
  }
145
145
  }
146
146
  exports.ChannelInvoke = ChannelInvoke;
147
- class ChannelBatch extends runnables_1.RunnableEach {
148
- constructor(fields) {
149
- super({
150
- ...fields,
151
- bound: fields.bound ?? defaultRunnableBound,
152
- });
153
- Object.defineProperty(this, "lc_graph_name", {
154
- enumerable: true,
155
- configurable: true,
156
- writable: true,
157
- value: "ChannelBatch"
158
- });
159
- Object.defineProperty(this, "channel", {
160
- enumerable: true,
161
- configurable: true,
162
- writable: true,
163
- value: void 0
164
- });
165
- Object.defineProperty(this, "key", {
166
- enumerable: true,
167
- configurable: true,
168
- writable: true,
169
- value: void 0
170
- });
171
- this.channel = fields.channel;
172
- this.key = fields.key;
173
- }
174
- join(channels) {
175
- if (!this.key) {
176
- throw new Error(`Cannot join() additional channels without a key.\nPass a key arg to Channel.subscribeToEach().`);
177
- }
178
- const channelsMap = {};
179
- for (const chan of channels) {
180
- channelsMap[chan] = new ChannelRead(chan);
181
- }
182
- const joiner = runnables_1.RunnablePassthrough.assign({ ...channelsMap });
183
- if (this.bound === defaultRunnableBound) {
184
- return new ChannelBatch({
185
- channel: this.channel,
186
- key: this.key,
187
- bound: joiner,
188
- });
189
- }
190
- else {
191
- return new ChannelBatch({
192
- channel: this.channel,
193
- key: this.key,
194
- bound: this.bound.pipe(joiner),
195
- });
196
- }
197
- }
198
- // @ts-expect-error @TODO: fix later
199
- pipe(coerceable) {
200
- if (this.bound === defaultRunnableBound) {
201
- return new ChannelBatch({
202
- channel: this.channel,
203
- key: this.key,
204
- bound: (0, runnables_1._coerceToRunnable)(coerceable),
205
- });
206
- }
207
- else {
208
- // Delegate to `or` in `this.bound`
209
- return new ChannelBatch({
210
- channel: this.channel,
211
- key: this.key,
212
- bound: this.bound.pipe(coerceable),
213
- });
214
- }
215
- }
216
- }
217
- exports.ChannelBatch = ChannelBatch;
@@ -1,4 +1,4 @@
1
- import { Runnable, RunnableBinding, RunnableBindingArgs, RunnableConfig, RunnableEach, RunnableLambda, RunnableLike } from "@langchain/core/runnables";
1
+ import { RunnableBinding, RunnableBindingArgs, RunnableConfig, RunnableLambda, RunnableLike } from "@langchain/core/runnables";
2
2
  import { ConfigurableFieldSpec } from "../checkpoint/index.js";
3
3
  export declare class ChannelRead<RunInput = any, RunOutput = any> extends RunnableLambda<RunInput, RunOutput> {
4
4
  lc_graph_name: string;
@@ -25,19 +25,4 @@ export declare class ChannelInvoke<RunInput = ChannelInvokeInputType, RunOutput
25
25
  join(channels: Array<string>): ChannelInvoke<RunInput, RunOutput>;
26
26
  pipe<NewRunOutput>(coerceable: RunnableLike): ChannelInvoke<RunInput, Exclude<NewRunOutput, Error>>;
27
27
  }
28
- interface ChannelBatchArgs {
29
- channel: string;
30
- key?: string;
31
- bound?: Runnable;
32
- }
33
- export type ChannelBatchInputType = any;
34
- export type ChannelBatchOutputType = any;
35
- export declare class ChannelBatch extends RunnableEach<ChannelBatchInputType, ChannelBatchOutputType, RunnableConfig> {
36
- lc_graph_name: string;
37
- channel: string;
38
- key?: string;
39
- constructor(fields: ChannelBatchArgs);
40
- join(channels: Array<string>): ChannelBatch;
41
- pipe(coerceable: RunnableLike): ChannelBatch;
42
- }
43
28
  export {};