@langchain/langgraph 0.2.31 → 0.2.33

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,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ChannelWrite = exports.PASSTHROUGH = exports.SKIP_WRITE = void 0;
4
+ const runnables_1 = require("@langchain/core/runnables");
4
5
  const constants_js_1 = require("../constants.cjs");
5
6
  const utils_js_1 = require("../utils.cjs");
6
7
  const errors_js_1 = require("../errors.cjs");
@@ -29,7 +30,13 @@ class ChannelWrite extends utils_js_1.RunnableCallable {
29
30
  constructor(writes, tags) {
30
31
  const name = `ChannelWrite<${writes
31
32
  .map((packet) => {
32
- return (0, constants_js_1._isSend)(packet) ? packet.node : packet.channel;
33
+ if ((0, constants_js_1._isSend)(packet)) {
34
+ return packet.node;
35
+ }
36
+ else if ("channel" in packet) {
37
+ return packet.channel;
38
+ }
39
+ return "...";
33
40
  })
34
41
  .join(",")}>`;
35
42
  super({
@@ -48,7 +55,13 @@ class ChannelWrite extends utils_js_1.RunnableCallable {
48
55
  }
49
56
  async _write(input, config) {
50
57
  const writes = this.writes.map((write) => {
51
- if (_isChannelWriteEntry(write) && _isPassthrough(write.value)) {
58
+ if (_isChannelWriteTupleEntry(write) && _isPassthrough(write.value)) {
59
+ return {
60
+ mapper: write.mapper,
61
+ value: input,
62
+ };
63
+ }
64
+ else if (_isChannelWriteEntry(write) && _isPassthrough(write.value)) {
52
65
  return {
53
66
  channel: write.channel,
54
67
  value: input,
@@ -65,36 +78,52 @@ class ChannelWrite extends utils_js_1.RunnableCallable {
65
78
  }
66
79
  // TODO: Support requireAtLeastOneOf
67
80
  static async doWrite(config, writes) {
68
- const sends = writes.filter(constants_js_1._isSend).map((packet) => {
69
- return [constants_js_1.TASKS, packet];
70
- });
71
- const entries = writes.filter((write) => {
72
- return !(0, constants_js_1._isSend)(write);
73
- });
74
- const invalidEntry = entries.find((write) => {
75
- return write.channel === constants_js_1.TASKS;
76
- });
77
- if (invalidEntry) {
78
- throw new errors_js_1.InvalidUpdateError(`Cannot write to the reserved channel ${constants_js_1.TASKS}`);
81
+ // validate
82
+ for (const w of writes) {
83
+ if (_isChannelWriteEntry(w)) {
84
+ if (w.channel === constants_js_1.TASKS) {
85
+ throw new errors_js_1.InvalidUpdateError("Cannot write to the reserved channel TASKS");
86
+ }
87
+ if (_isPassthrough(w.value)) {
88
+ throw new errors_js_1.InvalidUpdateError("PASSTHROUGH value must be replaced");
89
+ }
90
+ }
91
+ if (_isChannelWriteTupleEntry(w)) {
92
+ if (_isPassthrough(w.value)) {
93
+ throw new errors_js_1.InvalidUpdateError("PASSTHROUGH value must be replaced");
94
+ }
95
+ }
96
+ }
97
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
98
+ const writeEntries = [];
99
+ for (const w of writes) {
100
+ if ((0, constants_js_1._isSend)(w)) {
101
+ writeEntries.push([constants_js_1.TASKS, w]);
102
+ }
103
+ else if (_isChannelWriteTupleEntry(w)) {
104
+ const mappedResult = await w.mapper.invoke(w.value, config);
105
+ if (mappedResult != null && mappedResult.length > 0) {
106
+ writeEntries.push(...mappedResult);
107
+ }
108
+ }
109
+ else if (_isChannelWriteEntry(w)) {
110
+ const mappedValue = w.mapper !== undefined
111
+ ? await w.mapper.invoke(w.value, config)
112
+ : w.value;
113
+ if (_isSkipWrite(mappedValue)) {
114
+ continue;
115
+ }
116
+ if (w.skipNone && mappedValue === undefined) {
117
+ continue;
118
+ }
119
+ writeEntries.push([w.channel, mappedValue]);
120
+ }
121
+ else {
122
+ throw new Error(`Invalid write entry: ${JSON.stringify(w)}`);
123
+ }
79
124
  }
80
- const values = await Promise.all(entries.map(async (write) => {
81
- const mappedValue = write.mapper
82
- ? await write.mapper.invoke(write.value, config)
83
- : write.value;
84
- return {
85
- ...write,
86
- value: mappedValue,
87
- };
88
- })).then((writes) => {
89
- return writes
90
- .filter((write) => !write.skipNone || write.value !== null)
91
- .map((write) => {
92
- return [write.channel, write.value];
93
- });
94
- });
95
125
  const write = config.configurable?.[constants_js_1.CONFIG_KEY_SEND];
96
- const filtered = values.filter(([_, value]) => !_isSkipWrite(value));
97
- write([...sends, ...filtered]);
126
+ write(writeEntries);
98
127
  }
99
128
  static isWriter(runnable) {
100
129
  return (
@@ -110,3 +139,8 @@ exports.ChannelWrite = ChannelWrite;
110
139
  function _isChannelWriteEntry(x) {
111
140
  return (x !== undefined && typeof x.channel === "string");
112
141
  }
142
+ function _isChannelWriteTupleEntry(x) {
143
+ return (x !== undefined &&
144
+ !_isChannelWriteEntry(x) &&
145
+ runnables_1.Runnable.isRunnable(x.mapper));
146
+ }
@@ -12,10 +12,10 @@ export declare const PASSTHROUGH: {
12
12
  * or None to skip writing.
13
13
  */
14
14
  export declare class ChannelWrite<RunInput = any> extends RunnableCallable {
15
- writes: Array<ChannelWriteEntry | Send>;
16
- constructor(writes: Array<ChannelWriteEntry | Send>, tags?: string[]);
15
+ writes: Array<ChannelWriteEntry | ChannelWriteTupleEntry | Send>;
16
+ constructor(writes: Array<ChannelWriteEntry | ChannelWriteTupleEntry | Send>, tags?: string[]);
17
17
  _write(input: unknown, config: RunnableConfig): Promise<unknown>;
18
- static doWrite(config: RunnableConfig, writes: (ChannelWriteEntry | Send)[]): Promise<void>;
18
+ static doWrite(config: RunnableConfig, writes: (ChannelWriteEntry | ChannelWriteTupleEntry | Send)[]): Promise<void>;
19
19
  static isWriter(runnable: RunnableLike): runnable is ChannelWrite;
20
20
  static registerWriter<T extends Runnable>(runnable: T): T;
21
21
  }
@@ -25,3 +25,7 @@ export interface ChannelWriteEntry {
25
25
  skipNone?: boolean;
26
26
  mapper?: Runnable;
27
27
  }
28
+ export interface ChannelWriteTupleEntry {
29
+ value: unknown;
30
+ mapper: Runnable<any, [string, any][]>;
31
+ }
@@ -1,3 +1,4 @@
1
+ import { Runnable, } from "@langchain/core/runnables";
1
2
  import { _isSend, CONFIG_KEY_SEND, TASKS } from "../constants.js";
2
3
  import { RunnableCallable } from "../utils.js";
3
4
  import { InvalidUpdateError } from "../errors.js";
@@ -26,7 +27,13 @@ export class ChannelWrite extends RunnableCallable {
26
27
  constructor(writes, tags) {
27
28
  const name = `ChannelWrite<${writes
28
29
  .map((packet) => {
29
- return _isSend(packet) ? packet.node : packet.channel;
30
+ if (_isSend(packet)) {
31
+ return packet.node;
32
+ }
33
+ else if ("channel" in packet) {
34
+ return packet.channel;
35
+ }
36
+ return "...";
30
37
  })
31
38
  .join(",")}>`;
32
39
  super({
@@ -45,7 +52,13 @@ export class ChannelWrite extends RunnableCallable {
45
52
  }
46
53
  async _write(input, config) {
47
54
  const writes = this.writes.map((write) => {
48
- if (_isChannelWriteEntry(write) && _isPassthrough(write.value)) {
55
+ if (_isChannelWriteTupleEntry(write) && _isPassthrough(write.value)) {
56
+ return {
57
+ mapper: write.mapper,
58
+ value: input,
59
+ };
60
+ }
61
+ else if (_isChannelWriteEntry(write) && _isPassthrough(write.value)) {
49
62
  return {
50
63
  channel: write.channel,
51
64
  value: input,
@@ -62,36 +75,52 @@ export class ChannelWrite extends RunnableCallable {
62
75
  }
63
76
  // TODO: Support requireAtLeastOneOf
64
77
  static async doWrite(config, writes) {
65
- const sends = writes.filter(_isSend).map((packet) => {
66
- return [TASKS, packet];
67
- });
68
- const entries = writes.filter((write) => {
69
- return !_isSend(write);
70
- });
71
- const invalidEntry = entries.find((write) => {
72
- return write.channel === TASKS;
73
- });
74
- if (invalidEntry) {
75
- throw new InvalidUpdateError(`Cannot write to the reserved channel ${TASKS}`);
78
+ // validate
79
+ for (const w of writes) {
80
+ if (_isChannelWriteEntry(w)) {
81
+ if (w.channel === TASKS) {
82
+ throw new InvalidUpdateError("Cannot write to the reserved channel TASKS");
83
+ }
84
+ if (_isPassthrough(w.value)) {
85
+ throw new InvalidUpdateError("PASSTHROUGH value must be replaced");
86
+ }
87
+ }
88
+ if (_isChannelWriteTupleEntry(w)) {
89
+ if (_isPassthrough(w.value)) {
90
+ throw new InvalidUpdateError("PASSTHROUGH value must be replaced");
91
+ }
92
+ }
93
+ }
94
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
+ const writeEntries = [];
96
+ for (const w of writes) {
97
+ if (_isSend(w)) {
98
+ writeEntries.push([TASKS, w]);
99
+ }
100
+ else if (_isChannelWriteTupleEntry(w)) {
101
+ const mappedResult = await w.mapper.invoke(w.value, config);
102
+ if (mappedResult != null && mappedResult.length > 0) {
103
+ writeEntries.push(...mappedResult);
104
+ }
105
+ }
106
+ else if (_isChannelWriteEntry(w)) {
107
+ const mappedValue = w.mapper !== undefined
108
+ ? await w.mapper.invoke(w.value, config)
109
+ : w.value;
110
+ if (_isSkipWrite(mappedValue)) {
111
+ continue;
112
+ }
113
+ if (w.skipNone && mappedValue === undefined) {
114
+ continue;
115
+ }
116
+ writeEntries.push([w.channel, mappedValue]);
117
+ }
118
+ else {
119
+ throw new Error(`Invalid write entry: ${JSON.stringify(w)}`);
120
+ }
76
121
  }
77
- const values = await Promise.all(entries.map(async (write) => {
78
- const mappedValue = write.mapper
79
- ? await write.mapper.invoke(write.value, config)
80
- : write.value;
81
- return {
82
- ...write,
83
- value: mappedValue,
84
- };
85
- })).then((writes) => {
86
- return writes
87
- .filter((write) => !write.skipNone || write.value !== null)
88
- .map((write) => {
89
- return [write.channel, write.value];
90
- });
91
- });
92
122
  const write = config.configurable?.[CONFIG_KEY_SEND];
93
- const filtered = values.filter(([_, value]) => !_isSkipWrite(value));
94
- write([...sends, ...filtered]);
123
+ write(writeEntries);
95
124
  }
96
125
  static isWriter(runnable) {
97
126
  return (
@@ -106,3 +135,8 @@ export class ChannelWrite extends RunnableCallable {
106
135
  function _isChannelWriteEntry(x) {
107
136
  return (x !== undefined && typeof x.channel === "string");
108
137
  }
138
+ function _isChannelWriteTupleEntry(x) {
139
+ return (x !== undefined &&
140
+ !_isChannelWriteEntry(x) &&
141
+ Runnable.isRunnable(x.mapper));
142
+ }
package/dist/web.cjs CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.MessagesAnnotation = exports.InMemoryStore = exports.AsyncBatchedStore = exports.BaseStore = exports.BaseCheckpointSaver = exports.emptyCheckpoint = exports.copyCheckpoint = exports.MemorySaver = exports.interrupt = exports.Command = exports.Send = exports.BinaryOperatorAggregate = exports.BaseChannel = exports.Annotation = exports.messagesStateReducer = exports.MessageGraph = exports.CompiledStateGraph = exports.StateGraph = exports.START = exports.Graph = exports.END = void 0;
17
+ exports.MessagesAnnotation = exports.InMemoryStore = exports.AsyncBatchedStore = exports.BaseStore = exports.BaseCheckpointSaver = exports.emptyCheckpoint = exports.copyCheckpoint = exports.MemorySaver = exports.interrupt = exports.isCommand = exports.Command = exports.Send = exports.BinaryOperatorAggregate = exports.BaseChannel = exports.Annotation = exports.messagesStateReducer = exports.MessageGraph = exports.CompiledStateGraph = exports.StateGraph = exports.START = exports.Graph = exports.END = void 0;
18
18
  var index_js_1 = require("./graph/index.cjs");
19
19
  Object.defineProperty(exports, "END", { enumerable: true, get: function () { return index_js_1.END; } });
20
20
  Object.defineProperty(exports, "Graph", { enumerable: true, get: function () { return index_js_1.Graph; } });
@@ -31,6 +31,7 @@ Object.defineProperty(exports, "BinaryOperatorAggregate", { enumerable: true, ge
31
31
  var constants_js_1 = require("./constants.cjs");
32
32
  Object.defineProperty(exports, "Send", { enumerable: true, get: function () { return constants_js_1.Send; } });
33
33
  Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return constants_js_1.Command; } });
34
+ Object.defineProperty(exports, "isCommand", { enumerable: true, get: function () { return constants_js_1.isCommand; } });
34
35
  var interrupt_js_1 = require("./interrupt.cjs");
35
36
  Object.defineProperty(exports, "interrupt", { enumerable: true, get: function () { return interrupt_js_1.interrupt; } });
36
37
  var langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
package/dist/web.d.ts CHANGED
@@ -4,7 +4,7 @@ export * from "./errors.js";
4
4
  export { BaseChannel, type BinaryOperator, BinaryOperatorAggregate, type AnyValue, type WaitForNames, type DynamicBarrierValue, type LastValue, type NamedBarrierValue, type Topic, } from "./channels/index.js";
5
5
  export { type AnnotationRoot as _INTERNAL_ANNOTATION_ROOT } from "./graph/index.js";
6
6
  export { type RetryPolicy } from "./pregel/utils/index.js";
7
- export { Send, Command, type CommandParams, type Interrupt, } from "./constants.js";
7
+ export { Send, Command, type CommandParams, isCommand, type Interrupt, } from "./constants.js";
8
8
  export { interrupt } from "./interrupt.js";
9
9
  export { MemorySaver, type Checkpoint, type CheckpointMetadata, type CheckpointTuple, copyCheckpoint, emptyCheckpoint, BaseCheckpointSaver, type Item, type GetOperation, type SearchOperation, type PutOperation, type Operation, type OperationResults, BaseStore, AsyncBatchedStore, InMemoryStore, type NameSpacePath, type NamespaceMatchType, type MatchCondition, type ListNamespacesOperation, } from "@langchain/langgraph-checkpoint";
10
10
  export * from "./managed/index.js";
package/dist/web.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export { END, Graph, START, StateGraph, CompiledStateGraph, MessageGraph, messagesStateReducer, Annotation, } from "./graph/index.js";
2
2
  export * from "./errors.js";
3
3
  export { BaseChannel, BinaryOperatorAggregate, } from "./channels/index.js";
4
- export { Send, Command, } from "./constants.js";
4
+ export { Send, Command, isCommand, } from "./constants.js";
5
5
  export { interrupt } from "./interrupt.js";
6
6
  export { MemorySaver, copyCheckpoint, emptyCheckpoint, BaseCheckpointSaver, BaseStore, AsyncBatchedStore, InMemoryStore, } from "@langchain/langgraph-checkpoint";
7
7
  export * from "./managed/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph",
3
- "version": "0.2.31",
3
+ "version": "0.2.33",
4
4
  "description": "LangGraph",
5
5
  "type": "module",
6
6
  "engines": {
@@ -43,7 +43,7 @@
43
43
  "@jest/globals": "^29.5.0",
44
44
  "@langchain/anthropic": "^0.3.5",
45
45
  "@langchain/community": "^0.3.9",
46
- "@langchain/core": "^0.3.22",
46
+ "@langchain/core": "^0.3.23",
47
47
  "@langchain/langgraph-checkpoint-postgres": "workspace:*",
48
48
  "@langchain/langgraph-checkpoint-sqlite": "workspace:*",
49
49
  "@langchain/openai": "^0.3.11",