@langchain/langgraph 0.0.11 → 0.0.13

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 (134) hide show
  1. package/dist/channels/any_value.cjs +57 -0
  2. package/dist/channels/any_value.d.ts +16 -0
  3. package/dist/channels/any_value.js +53 -0
  4. package/dist/channels/base.cjs +19 -28
  5. package/dist/channels/base.d.ts +13 -19
  6. package/dist/channels/base.js +17 -24
  7. package/dist/channels/binop.cjs +4 -3
  8. package/dist/channels/binop.d.ts +1 -1
  9. package/dist/channels/binop.js +3 -2
  10. package/dist/channels/dynamic_barrier_value.cjs +88 -0
  11. package/dist/channels/dynamic_barrier_value.d.ts +26 -0
  12. package/dist/channels/dynamic_barrier_value.js +84 -0
  13. package/dist/channels/ephemeral_value.cjs +64 -0
  14. package/dist/channels/ephemeral_value.d.ts +14 -0
  15. package/dist/channels/ephemeral_value.js +60 -0
  16. package/dist/channels/index.cjs +1 -3
  17. package/dist/channels/index.d.ts +1 -1
  18. package/dist/channels/index.js +1 -1
  19. package/dist/channels/last_value.cjs +11 -5
  20. package/dist/channels/last_value.d.ts +5 -1
  21. package/dist/channels/last_value.js +9 -3
  22. package/dist/channels/named_barrier_value.cjs +71 -0
  23. package/dist/channels/named_barrier_value.d.ts +18 -0
  24. package/dist/channels/named_barrier_value.js +66 -0
  25. package/dist/channels/topic.cjs +5 -3
  26. package/dist/channels/topic.d.ts +3 -3
  27. package/dist/channels/topic.js +5 -3
  28. package/dist/checkpoint/base.cjs +30 -12
  29. package/dist/checkpoint/base.d.ts +39 -22
  30. package/dist/checkpoint/base.js +28 -11
  31. package/dist/checkpoint/id.cjs +40 -0
  32. package/dist/checkpoint/id.d.ts +2 -0
  33. package/dist/checkpoint/id.js +35 -0
  34. package/dist/checkpoint/index.cjs +2 -2
  35. package/dist/checkpoint/index.d.ts +2 -2
  36. package/dist/checkpoint/index.js +2 -2
  37. package/dist/checkpoint/memory.cjs +63 -49
  38. package/dist/checkpoint/memory.d.ts +7 -10
  39. package/dist/checkpoint/memory.js +62 -47
  40. package/dist/checkpoint/sqlite.cjs +170 -0
  41. package/dist/checkpoint/sqlite.d.ts +14 -0
  42. package/dist/checkpoint/sqlite.js +163 -0
  43. package/dist/constants.cjs +3 -1
  44. package/dist/constants.d.ts +2 -0
  45. package/dist/constants.js +2 -0
  46. package/dist/errors.cjs +31 -0
  47. package/dist/errors.d.ts +12 -0
  48. package/dist/errors.js +24 -0
  49. package/dist/graph/graph.cjs +234 -96
  50. package/dist/graph/graph.d.ts +52 -23
  51. package/dist/graph/graph.js +233 -97
  52. package/dist/graph/index.cjs +2 -2
  53. package/dist/graph/index.d.ts +2 -2
  54. package/dist/graph/index.js +2 -2
  55. package/dist/graph/message.cjs +4 -3
  56. package/dist/graph/message.d.ts +4 -1
  57. package/dist/graph/message.js +4 -3
  58. package/dist/graph/state.cjs +237 -102
  59. package/dist/graph/state.d.ts +41 -18
  60. package/dist/graph/state.js +238 -104
  61. package/dist/index.cjs +6 -2
  62. package/dist/index.d.ts +3 -2
  63. package/dist/index.js +2 -1
  64. package/dist/prebuilt/agent_executor.cjs +22 -36
  65. package/dist/prebuilt/agent_executor.d.ts +7 -10
  66. package/dist/prebuilt/agent_executor.js +23 -37
  67. package/dist/prebuilt/chat_agent_executor.cjs +13 -13
  68. package/dist/prebuilt/chat_agent_executor.d.ts +3 -1
  69. package/dist/prebuilt/chat_agent_executor.js +15 -15
  70. package/dist/prebuilt/index.cjs +4 -1
  71. package/dist/prebuilt/index.d.ts +1 -0
  72. package/dist/prebuilt/index.js +1 -0
  73. package/dist/prebuilt/tool_node.cjs +59 -0
  74. package/dist/prebuilt/tool_node.d.ts +17 -0
  75. package/dist/prebuilt/tool_node.js +54 -0
  76. package/dist/pregel/debug.cjs +6 -8
  77. package/dist/pregel/debug.d.ts +2 -2
  78. package/dist/pregel/debug.js +5 -7
  79. package/dist/pregel/index.cjs +406 -236
  80. package/dist/pregel/index.d.ts +77 -41
  81. package/dist/pregel/index.js +408 -241
  82. package/dist/pregel/io.cjs +117 -30
  83. package/dist/pregel/io.d.ts +11 -3
  84. package/dist/pregel/io.js +111 -28
  85. package/dist/pregel/read.cjs +126 -46
  86. package/dist/pregel/read.d.ts +27 -18
  87. package/dist/pregel/read.js +125 -45
  88. package/dist/pregel/types.cjs +2 -0
  89. package/dist/pregel/types.d.ts +32 -0
  90. package/dist/pregel/types.js +1 -0
  91. package/dist/pregel/validate.cjs +58 -51
  92. package/dist/pregel/validate.d.ts +14 -13
  93. package/dist/pregel/validate.js +56 -50
  94. package/dist/pregel/write.cjs +46 -30
  95. package/dist/pregel/write.d.ts +18 -8
  96. package/dist/pregel/write.js +45 -29
  97. package/dist/serde/base.cjs +2 -0
  98. package/dist/serde/base.d.ts +4 -0
  99. package/dist/serde/base.js +1 -0
  100. package/dist/setup/async_local_storage.cjs +2 -2
  101. package/dist/setup/async_local_storage.js +1 -1
  102. package/dist/tests/channels.test.d.ts +1 -0
  103. package/dist/tests/channels.test.js +151 -0
  104. package/dist/tests/chatbot.int.test.d.ts +1 -0
  105. package/dist/tests/chatbot.int.test.js +61 -0
  106. package/dist/tests/checkpoints.test.d.ts +1 -0
  107. package/dist/tests/checkpoints.test.js +190 -0
  108. package/dist/tests/graph.test.d.ts +1 -0
  109. package/dist/tests/graph.test.js +15 -0
  110. package/dist/tests/prebuilt.int.test.d.ts +1 -0
  111. package/dist/tests/prebuilt.int.test.js +101 -0
  112. package/dist/tests/prebuilt.test.d.ts +1 -0
  113. package/dist/tests/prebuilt.test.js +195 -0
  114. package/dist/tests/pregel.io.test.d.ts +1 -0
  115. package/dist/tests/pregel.io.test.js +332 -0
  116. package/dist/tests/pregel.read.test.d.ts +1 -0
  117. package/dist/tests/pregel.read.test.js +109 -0
  118. package/dist/tests/pregel.test.d.ts +1 -0
  119. package/dist/tests/pregel.test.js +1879 -0
  120. package/dist/tests/pregel.validate.test.d.ts +1 -0
  121. package/dist/tests/pregel.validate.test.js +198 -0
  122. package/dist/tests/pregel.write.test.d.ts +1 -0
  123. package/dist/tests/pregel.write.test.js +44 -0
  124. package/dist/tests/tracing.int.test.d.ts +1 -0
  125. package/dist/tests/tracing.int.test.js +449 -0
  126. package/dist/tests/utils.d.ts +22 -0
  127. package/dist/tests/utils.js +76 -0
  128. package/dist/utils.cjs +74 -0
  129. package/dist/utils.d.ts +18 -0
  130. package/dist/utils.js +70 -0
  131. package/package.json +12 -8
  132. package/dist/pregel/reserved.cjs +0 -6
  133. package/dist/pregel/reserved.d.ts +0 -3
  134. package/dist/pregel/reserved.js +0 -3
@@ -1,6 +1,50 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mapOutput = exports.mapInput = void 0;
3
+ exports.single = exports.mapOutputUpdates = exports.mapOutputValues = exports.mapInput = exports.readChannels = exports.readChannel = void 0;
4
+ const constants_js_1 = require("../constants.cjs");
5
+ const errors_js_1 = require("../errors.cjs");
6
+ function readChannel(channels, chan, catch_ = true, returnException = false) {
7
+ try {
8
+ return channels[chan].get();
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ }
11
+ catch (e) {
12
+ if (e.name === errors_js_1.EmptyChannelError.name) {
13
+ if (returnException) {
14
+ return e;
15
+ }
16
+ else if (catch_) {
17
+ return null;
18
+ }
19
+ }
20
+ throw e;
21
+ }
22
+ }
23
+ exports.readChannel = readChannel;
24
+ function readChannels(channels, select, skipEmpty = true
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+ ) {
27
+ if (Array.isArray(select)) {
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ const values = {};
30
+ for (const k of select) {
31
+ try {
32
+ values[k] = readChannel(channels, k, !skipEmpty);
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ }
35
+ catch (e) {
36
+ if (e.name === errors_js_1.EmptyChannelError.name) {
37
+ continue;
38
+ }
39
+ }
40
+ }
41
+ return values;
42
+ }
43
+ else {
44
+ return readChannel(channels, select);
45
+ }
46
+ }
47
+ exports.readChannels = readChannels;
4
48
  /**
5
49
  * Map input chunk to a sequence of pending writes in the form [channel, value].
6
50
  */
@@ -9,49 +53,92 @@ function* mapInput(inputChannels,
9
53
  chunk
10
54
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
55
  ) {
12
- if (typeof inputChannels === "string") {
13
- yield [inputChannels, chunk];
14
- }
15
- else {
16
- if ((chunk && typeof chunk !== "object") || Array.isArray(chunk)) {
17
- throw new Error(`Expected chunk to be an object, got ${typeof chunk}`);
18
- }
19
- for (const k in chunk) {
20
- if (inputChannels.includes(k)) {
21
- yield [k, chunk[k]];
22
- }
23
- else {
24
- console.warn(`Input channel ${k} not found in ${inputChannels}`);
56
+ if (chunk) {
57
+ if (Array.isArray(inputChannels) &&
58
+ typeof chunk === "object" &&
59
+ !Array.isArray(chunk) &&
60
+ !!chunk) {
61
+ for (const k in chunk) {
62
+ if (inputChannels.includes(k)) {
63
+ yield [k, chunk[k]];
64
+ }
25
65
  }
26
66
  }
67
+ else if (Array.isArray(inputChannels)) {
68
+ throw new Error("Input chunk must be an object when inputChannels is an array");
69
+ }
70
+ else {
71
+ yield [inputChannels, chunk];
72
+ }
27
73
  }
28
74
  }
29
75
  exports.mapInput = mapInput;
30
76
  /**
31
- * Map pending writes (a list of [channel, value]) to output chunk.
77
+ * Map pending writes (a sequence of tuples (channel, value)) to output chunk.
32
78
  */
33
- function mapOutput(outputChannels,
34
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
- pendingWrites, channels
79
+ function* mapOutputValues(outputChannels, pendingWrites, channels
36
80
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
81
  ) {
38
- if (typeof outputChannels === "string") {
39
- if (pendingWrites.some(([chan, _]) => chan === outputChannels)) {
40
- return channels[outputChannels].get();
82
+ if (Array.isArray(outputChannels)) {
83
+ if (pendingWrites.find(([chan, _]) => outputChannels.includes(chan))) {
84
+ yield readChannels(channels, outputChannels);
41
85
  }
42
86
  }
43
87
  else {
44
- const updated = pendingWrites
45
- .filter(([chan, _]) => outputChannels.includes(chan))
46
- .map(([chan, _]) => chan);
47
- if (updated.length > 0) {
88
+ if (pendingWrites.some(([chan, _]) => chan === outputChannels)) {
48
89
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
- return updated.reduce((acc, chan) => {
50
- acc[chan] = channels[chan].get();
51
- return acc;
52
- }, {});
90
+ yield readChannel(channels, outputChannels);
91
+ }
92
+ }
93
+ }
94
+ exports.mapOutputValues = mapOutputValues;
95
+ /**
96
+ * Map pending writes (a sequence of tuples (channel, value)) to output chunk.
97
+ */
98
+ function* mapOutputUpdates(outputChannels, tasks
99
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
100
+ ) {
101
+ const outputTasks = tasks.filter((task) => task.config === undefined || !task.config.tags?.includes(constants_js_1.TAG_HIDDEN));
102
+ if (Array.isArray(outputChannels)) {
103
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
104
+ const updated = {};
105
+ for (const task of outputTasks) {
106
+ if (task.writes.some(([chan, _]) => outputChannels.includes(chan))) {
107
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
108
+ const nodes = {};
109
+ for (const [chan, value] of task.writes) {
110
+ if (outputChannels.includes(chan)) {
111
+ nodes[chan] = value;
112
+ }
113
+ }
114
+ updated[task.name] = nodes;
115
+ }
116
+ }
117
+ if (Object.keys(updated).length > 0) {
118
+ yield updated;
119
+ }
120
+ }
121
+ else {
122
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
123
+ const updated = {};
124
+ for (const task of outputTasks) {
125
+ for (const [chan, value] of task.writes) {
126
+ if (chan === outputChannels) {
127
+ updated[task.name] = value;
128
+ }
129
+ }
130
+ }
131
+ if (Object.keys(updated).length > 0) {
132
+ yield updated;
53
133
  }
54
134
  }
135
+ }
136
+ exports.mapOutputUpdates = mapOutputUpdates;
137
+ function single(iter) {
138
+ // eslint-disable-next-line no-unreachable-loop
139
+ for (const value of iter) {
140
+ return value;
141
+ }
55
142
  return undefined;
56
143
  }
57
- exports.mapOutput = mapOutput;
144
+ exports.single = single;
@@ -1,9 +1,17 @@
1
1
  import { BaseChannel } from "../channels/base.js";
2
+ import { PregelExecutableTask } from "./types.js";
3
+ export declare function readChannel<C extends PropertyKey>(channels: Record<C, BaseChannel>, chan: C, catch_?: boolean, returnException?: boolean): unknown | null;
4
+ export declare function readChannels<C extends PropertyKey>(channels: Record<C, BaseChannel>, select: C | Array<C>, skipEmpty?: boolean): Record<string, any> | any;
2
5
  /**
3
6
  * Map input chunk to a sequence of pending writes in the form [channel, value].
4
7
  */
5
- export declare function mapInput(inputChannels: string | Array<string>, chunk?: any): Generator<[string, any]>;
8
+ export declare function mapInput<C extends PropertyKey>(inputChannels: C | Array<C>, chunk?: any): Generator<[C, any]>;
6
9
  /**
7
- * Map pending writes (a list of [channel, value]) to output chunk.
10
+ * Map pending writes (a sequence of tuples (channel, value)) to output chunk.
8
11
  */
9
- export declare function mapOutput(outputChannels: string | Array<string>, pendingWrites: Array<[string, any]>, channels: Record<string, BaseChannel>): any | undefined;
12
+ export declare function mapOutputValues<C extends PropertyKey>(outputChannels: C | Array<C>, pendingWrites: readonly [C, unknown][], channels: Record<C, BaseChannel>): Generator<Record<string, any>, any>;
13
+ /**
14
+ * Map pending writes (a sequence of tuples (channel, value)) to output chunk.
15
+ */
16
+ export declare function mapOutputUpdates<N extends PropertyKey, C extends PropertyKey>(outputChannels: C | Array<C>, tasks: readonly PregelExecutableTask<N, C>[]): Generator<Record<N, any | Record<string, any>>>;
17
+ export declare function single<T>(iter: IterableIterator<T>): T | undefined;
package/dist/pregel/io.js CHANGED
@@ -1,3 +1,45 @@
1
+ import { TAG_HIDDEN } from "../constants.js";
2
+ import { EmptyChannelError } from "../errors.js";
3
+ export function readChannel(channels, chan, catch_ = true, returnException = false) {
4
+ try {
5
+ return channels[chan].get();
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ }
8
+ catch (e) {
9
+ if (e.name === EmptyChannelError.name) {
10
+ if (returnException) {
11
+ return e;
12
+ }
13
+ else if (catch_) {
14
+ return null;
15
+ }
16
+ }
17
+ throw e;
18
+ }
19
+ }
20
+ export function readChannels(channels, select, skipEmpty = true
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ ) {
23
+ if (Array.isArray(select)) {
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ const values = {};
26
+ for (const k of select) {
27
+ try {
28
+ values[k] = readChannel(channels, k, !skipEmpty);
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
+ }
31
+ catch (e) {
32
+ if (e.name === EmptyChannelError.name) {
33
+ continue;
34
+ }
35
+ }
36
+ }
37
+ return values;
38
+ }
39
+ else {
40
+ return readChannel(channels, select);
41
+ }
42
+ }
1
43
  /**
2
44
  * Map input chunk to a sequence of pending writes in the form [channel, value].
3
45
  */
@@ -6,47 +48,88 @@ export function* mapInput(inputChannels,
6
48
  chunk
7
49
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
50
  ) {
9
- if (typeof inputChannels === "string") {
10
- yield [inputChannels, chunk];
11
- }
12
- else {
13
- if ((chunk && typeof chunk !== "object") || Array.isArray(chunk)) {
14
- throw new Error(`Expected chunk to be an object, got ${typeof chunk}`);
15
- }
16
- for (const k in chunk) {
17
- if (inputChannels.includes(k)) {
18
- yield [k, chunk[k]];
19
- }
20
- else {
21
- console.warn(`Input channel ${k} not found in ${inputChannels}`);
51
+ if (chunk) {
52
+ if (Array.isArray(inputChannels) &&
53
+ typeof chunk === "object" &&
54
+ !Array.isArray(chunk) &&
55
+ !!chunk) {
56
+ for (const k in chunk) {
57
+ if (inputChannels.includes(k)) {
58
+ yield [k, chunk[k]];
59
+ }
22
60
  }
23
61
  }
62
+ else if (Array.isArray(inputChannels)) {
63
+ throw new Error("Input chunk must be an object when inputChannels is an array");
64
+ }
65
+ else {
66
+ yield [inputChannels, chunk];
67
+ }
24
68
  }
25
69
  }
26
70
  /**
27
- * Map pending writes (a list of [channel, value]) to output chunk.
71
+ * Map pending writes (a sequence of tuples (channel, value)) to output chunk.
28
72
  */
29
- export function mapOutput(outputChannels,
30
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
- pendingWrites, channels
73
+ export function* mapOutputValues(outputChannels, pendingWrites, channels
32
74
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
75
  ) {
34
- if (typeof outputChannels === "string") {
35
- if (pendingWrites.some(([chan, _]) => chan === outputChannels)) {
36
- return channels[outputChannels].get();
76
+ if (Array.isArray(outputChannels)) {
77
+ if (pendingWrites.find(([chan, _]) => outputChannels.includes(chan))) {
78
+ yield readChannels(channels, outputChannels);
37
79
  }
38
80
  }
39
81
  else {
40
- const updated = pendingWrites
41
- .filter(([chan, _]) => outputChannels.includes(chan))
42
- .map(([chan, _]) => chan);
43
- if (updated.length > 0) {
82
+ if (pendingWrites.some(([chan, _]) => chan === outputChannels)) {
44
83
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
- return updated.reduce((acc, chan) => {
46
- acc[chan] = channels[chan].get();
47
- return acc;
48
- }, {});
84
+ yield readChannel(channels, outputChannels);
85
+ }
86
+ }
87
+ }
88
+ /**
89
+ * Map pending writes (a sequence of tuples (channel, value)) to output chunk.
90
+ */
91
+ export function* mapOutputUpdates(outputChannels, tasks
92
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
+ ) {
94
+ const outputTasks = tasks.filter((task) => task.config === undefined || !task.config.tags?.includes(TAG_HIDDEN));
95
+ if (Array.isArray(outputChannels)) {
96
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
97
+ const updated = {};
98
+ for (const task of outputTasks) {
99
+ if (task.writes.some(([chan, _]) => outputChannels.includes(chan))) {
100
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
101
+ const nodes = {};
102
+ for (const [chan, value] of task.writes) {
103
+ if (outputChannels.includes(chan)) {
104
+ nodes[chan] = value;
105
+ }
106
+ }
107
+ updated[task.name] = nodes;
108
+ }
109
+ }
110
+ if (Object.keys(updated).length > 0) {
111
+ yield updated;
112
+ }
113
+ }
114
+ else {
115
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
116
+ const updated = {};
117
+ for (const task of outputTasks) {
118
+ for (const [chan, value] of task.writes) {
119
+ if (chan === outputChannels) {
120
+ updated[task.name] = value;
121
+ }
122
+ }
123
+ }
124
+ if (Object.keys(updated).length > 0) {
125
+ yield updated;
49
126
  }
50
127
  }
128
+ }
129
+ export function single(iter) {
130
+ // eslint-disable-next-line no-unreachable-loop
131
+ for (const value of iter) {
132
+ return value;
133
+ }
51
134
  return undefined;
52
135
  }
@@ -1,18 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ChannelInvoke = exports.ChannelRead = void 0;
3
+ exports.PregelNode = exports.ChannelRead = void 0;
4
4
  const runnables_1 = require("@langchain/core/runnables");
5
5
  const constants_js_1 = require("../constants.cjs");
6
- class ChannelRead extends runnables_1.RunnableLambda {
7
- constructor(channel) {
6
+ const write_js_1 = require("./write.cjs");
7
+ const utils_js_1 = require("../utils.cjs");
8
+ class ChannelRead extends utils_js_1.RunnableCallable {
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ constructor(channel,
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ mapper, fresh = false) {
8
13
  super({
9
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
- func: (input, options) => {
11
- if ("config" in options) {
12
- return this._read(input, options.config);
13
- }
14
- return this._read(input, options ?? {});
15
- },
14
+ func: (_, config) => ChannelRead.doRead(config, this.channel, this.fresh, this.mapper),
16
15
  });
17
16
  Object.defineProperty(this, "lc_graph_name", {
18
17
  enumerable: true,
@@ -26,42 +25,45 @@ class ChannelRead extends runnables_1.RunnableLambda {
26
25
  writable: true,
27
26
  value: void 0
28
27
  });
28
+ Object.defineProperty(this, "fresh", {
29
+ enumerable: true,
30
+ configurable: true,
31
+ writable: true,
32
+ value: false
33
+ });
34
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
+ Object.defineProperty(this, "mapper", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: void 0
40
+ });
41
+ this.fresh = fresh;
42
+ this.mapper = mapper;
29
43
  this.channel = channel;
30
- this.name = `ChannelRead<${channel}>`;
44
+ this.name = Array.isArray(channel)
45
+ ? `ChannelRead<${channel.join(",")}>`
46
+ : `ChannelRead<${channel}>`;
31
47
  }
32
- get configSpecs() {
33
- return [
34
- {
35
- id: constants_js_1.CONFIG_KEY_READ,
36
- name: constants_js_1.CONFIG_KEY_READ,
37
- description: null,
38
- default: null,
39
- // TODO FIX THIS
40
- annotation: "Callable[[BaseChannel], Any]",
41
- isShared: true,
42
- dependencies: null,
43
- },
44
- ];
45
- }
46
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
- _read(_, config) {
48
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
+ static doRead(config, channel, fresh, mapper) {
49
49
  const read = config.configurable?.[constants_js_1.CONFIG_KEY_READ];
50
50
  if (!read) {
51
51
  throw new Error(`Runnable ${this} is not configured with a read function. Make sure to call in the context of a Pregel process`);
52
52
  }
53
- if (Array.isArray(this.channel)) {
54
- const results = Object.fromEntries(this.channel.map((chan) => [chan, read(chan)]));
55
- return results;
53
+ if (mapper) {
54
+ return mapper(read(channel, fresh));
55
+ }
56
+ else {
57
+ return read(channel, fresh);
56
58
  }
57
- return read(this.channel);
58
59
  }
59
60
  }
60
61
  exports.ChannelRead = ChannelRead;
61
- const defaultRunnableBound = /* #__PURE__ */ new runnables_1.RunnablePassthrough();
62
- class ChannelInvoke extends runnables_1.RunnableBinding {
62
+ const defaultRunnableBound =
63
+ /* #__PURE__ */ new runnables_1.RunnablePassthrough();
64
+ class PregelNode extends runnables_1.RunnableBinding {
63
65
  constructor(fields) {
64
- const { channels, triggers, when } = fields;
66
+ const { channels, triggers, mapper, writers, bound, kwargs } = fields;
65
67
  const mergedTags = [
66
68
  ...(fields.config?.tags ? fields.config.tags : []),
67
69
  ...(fields.tags ? fields.tags : []),
@@ -79,7 +81,7 @@ class ChannelInvoke extends runnables_1.RunnableBinding {
79
81
  enumerable: true,
80
82
  configurable: true,
81
83
  writable: true,
82
- value: "ChannelInvoke"
84
+ value: "PregelNode"
83
85
  });
84
86
  Object.defineProperty(this, "channels", {
85
87
  enumerable: true,
@@ -94,48 +96,126 @@ class ChannelInvoke extends runnables_1.RunnableBinding {
94
96
  value: []
95
97
  });
96
98
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
97
- Object.defineProperty(this, "when", {
99
+ Object.defineProperty(this, "mapper", {
98
100
  enumerable: true,
99
101
  configurable: true,
100
102
  writable: true,
101
103
  value: void 0
102
104
  });
105
+ Object.defineProperty(this, "writers", {
106
+ enumerable: true,
107
+ configurable: true,
108
+ writable: true,
109
+ value: []
110
+ });
111
+ Object.defineProperty(this, "bound", {
112
+ enumerable: true,
113
+ configurable: true,
114
+ writable: true,
115
+ value: defaultRunnableBound
116
+ });
117
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
118
+ Object.defineProperty(this, "kwargs", {
119
+ enumerable: true,
120
+ configurable: true,
121
+ writable: true,
122
+ value: {}
123
+ });
103
124
  this.channels = channels;
104
125
  this.triggers = triggers;
105
- this.when = when;
126
+ this.mapper = mapper;
127
+ this.writers = writers ?? this.writers;
128
+ this.bound = bound ?? this.bound;
129
+ this.kwargs = kwargs ?? this.kwargs;
130
+ }
131
+ getWriters() {
132
+ const newWriters = [...this.writers];
133
+ while (newWriters.length > 1 &&
134
+ // eslint-disable-next-line no-instanceof/no-instanceof
135
+ newWriters[newWriters.length - 1] instanceof write_js_1.ChannelWrite &&
136
+ // eslint-disable-next-line no-instanceof/no-instanceof
137
+ newWriters[newWriters.length - 2] instanceof write_js_1.ChannelWrite) {
138
+ // we can combine writes if they are consecutive
139
+ newWriters[newWriters.length - 2].writes.push(...newWriters[newWriters.length - 1].writes);
140
+ newWriters.pop();
141
+ }
142
+ return newWriters;
143
+ }
144
+ getNode() {
145
+ const writers = this.getWriters();
146
+ if (this.bound === defaultRunnableBound && writers.length === 0) {
147
+ return undefined;
148
+ }
149
+ else if (this.bound === defaultRunnableBound && writers.length === 1) {
150
+ return writers[0];
151
+ }
152
+ else if (this.bound === defaultRunnableBound) {
153
+ return new runnables_1.RunnableSequence({
154
+ first: writers[0],
155
+ middle: writers.slice(1, writers.length - 1),
156
+ last: writers[writers.length - 1],
157
+ });
158
+ }
159
+ else if (writers.length > 0) {
160
+ return new runnables_1.RunnableSequence({
161
+ first: this.bound,
162
+ middle: writers.slice(0, writers.length - 1),
163
+ last: writers[writers.length - 1],
164
+ });
165
+ }
166
+ else {
167
+ return this.bound;
168
+ }
106
169
  }
107
170
  join(channels) {
171
+ if (!Array.isArray(channels)) {
172
+ throw new Error("channels must be a list");
173
+ }
108
174
  if (typeof this.channels !== "object") {
109
175
  throw new Error("all channels must be named when using .join()");
110
176
  }
111
- return new ChannelInvoke({
177
+ return new PregelNode({
112
178
  channels: {
113
179
  ...this.channels,
114
180
  ...Object.fromEntries(channels.map((chan) => [chan, chan])),
115
181
  },
116
182
  triggers: this.triggers,
117
- when: this.when,
183
+ mapper: this.mapper,
184
+ writers: this.writers,
118
185
  bound: this.bound,
119
186
  kwargs: this.kwargs,
120
187
  config: this.config,
121
188
  });
122
189
  }
123
190
  pipe(coerceable) {
124
- if (this.bound === defaultRunnableBound) {
125
- return new ChannelInvoke({
191
+ if (write_js_1.ChannelWrite.isWriter(coerceable)) {
192
+ return new PregelNode({
193
+ channels: this.channels,
194
+ triggers: this.triggers,
195
+ mapper: this.mapper,
196
+ writers: [...this.writers, coerceable],
197
+ bound: this.bound,
198
+ config: this.config,
199
+ kwargs: this.kwargs,
200
+ });
201
+ }
202
+ else if (this.bound === defaultRunnableBound) {
203
+ return new PregelNode({
126
204
  channels: this.channels,
127
205
  triggers: this.triggers,
128
- when: this.when,
206
+ mapper: this.mapper,
207
+ writers: this.writers,
129
208
  bound: (0, runnables_1._coerceToRunnable)(coerceable),
130
209
  config: this.config,
131
210
  kwargs: this.kwargs,
132
211
  });
133
212
  }
134
213
  else {
135
- return new ChannelInvoke({
214
+ return new PregelNode({
136
215
  channels: this.channels,
137
216
  triggers: this.triggers,
138
- when: this.when,
217
+ mapper: this.mapper,
218
+ writers: this.writers,
139
219
  bound: this.bound.pipe(coerceable),
140
220
  config: this.config,
141
221
  kwargs: this.kwargs,
@@ -143,4 +223,4 @@ class ChannelInvoke extends runnables_1.RunnableBinding {
143
223
  }
144
224
  }
145
225
  }
146
- exports.ChannelInvoke = ChannelInvoke;
226
+ exports.PregelNode = PregelNode;
@@ -1,28 +1,37 @@
1
- import { RunnableBinding, RunnableBindingArgs, RunnableConfig, RunnableLambda, RunnableLike } from "@langchain/core/runnables";
2
- import { ConfigurableFieldSpec } from "../checkpoint/index.js";
3
- export declare class ChannelRead<RunInput = any, RunOutput = any> extends RunnableLambda<RunInput, RunOutput> {
1
+ import { Runnable, RunnableBinding, RunnableBindingArgs, RunnableConfig, RunnableLike } from "@langchain/core/runnables";
2
+ import { RunnableCallable } from "../utils.js";
3
+ export declare class ChannelRead<RunInput = any> extends RunnableCallable {
4
4
  lc_graph_name: string;
5
5
  channel: string | Array<string>;
6
- constructor(channel: string | Array<string>);
7
- get configSpecs(): ConfigurableFieldSpec[];
8
- _read(_: any, config: RunnableConfig): any;
6
+ fresh: boolean;
7
+ mapper?: (args: any) => any;
8
+ constructor(channel: string | Array<string>, mapper?: (args: any) => any, fresh?: boolean);
9
+ static doRead<T = unknown>(config: RunnableConfig, channel: string | Array<string>, fresh: boolean, mapper?: (args: unknown) => unknown): T;
9
10
  }
10
- interface ChannelInvokeArgs<RunInput, RunOutput> extends Partial<RunnableBindingArgs<RunInput, RunOutput>> {
11
- channels: Record<string, string> | string;
11
+ interface PregelNodeArgs<RunInput, RunOutput> extends Partial<RunnableBindingArgs<RunInput, RunOutput>> {
12
+ channels: Record<string, string> | string[];
12
13
  triggers: Array<string>;
13
- when?: (args: any) => boolean;
14
- config?: RunnableConfig;
14
+ mapper?: (args: any) => any;
15
+ writers?: Runnable<RunOutput, unknown>[];
15
16
  tags?: string[];
17
+ bound?: Runnable<RunInput, RunOutput>;
18
+ kwargs?: Record<string, any>;
19
+ config?: RunnableConfig;
16
20
  }
17
- export type ChannelInvokeInputType = any;
18
- export type ChannelInvokeOutputType = any;
19
- export declare class ChannelInvoke<RunInput = ChannelInvokeInputType, RunOutput = ChannelInvokeOutputType> extends RunnableBinding<RunInput, RunOutput, RunnableConfig> {
21
+ export type PregelNodeInputType = any;
22
+ export type PregelNodeOutputType = any;
23
+ export declare class PregelNode<RunInput = PregelNodeInputType, RunOutput = PregelNodeOutputType> extends RunnableBinding<RunInput, RunOutput, RunnableConfig> {
20
24
  lc_graph_name: string;
21
- channels: Record<string, string> | string;
25
+ channels: Record<string, string> | string[];
22
26
  triggers: string[];
23
- when?: (args: any) => boolean;
24
- constructor(fields: ChannelInvokeArgs<RunInput, RunOutput>);
25
- join(channels: Array<string>): ChannelInvoke<RunInput, RunOutput>;
26
- pipe<NewRunOutput>(coerceable: RunnableLike): ChannelInvoke<RunInput, Exclude<NewRunOutput, Error>>;
27
+ mapper?: (args: any) => any;
28
+ writers: Runnable[];
29
+ bound: Runnable<RunInput, RunOutput>;
30
+ kwargs: Record<string, any>;
31
+ constructor(fields: PregelNodeArgs<RunInput, RunOutput>);
32
+ getWriters(): Array<Runnable>;
33
+ getNode(): Runnable<RunInput, RunOutput> | undefined;
34
+ join(channels: Array<string>): PregelNode<RunInput, RunOutput>;
35
+ pipe<NewRunOutput>(coerceable: RunnableLike): PregelNode<RunInput, Exclude<NewRunOutput, Error>>;
27
36
  }
28
37
  export {};