@langchain/langgraph 0.1.10-rc.3 → 0.2.0-rc.0

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,9 +1,10 @@
1
1
  import { BaseMessage } from "@langchain/core/messages";
2
+ import { Messages } from "./message.js";
2
3
  /**
3
4
  * Prebuilt state annotation that combines returned messages.
4
5
  * Can handle standard messages and special modifiers like {@link RemoveMessage}
5
6
  * instances.
6
7
  */
7
8
  export declare const MessagesAnnotation: import("./annotation.js").AnnotationRoot<{
8
- messages: import("../web.js").BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
9
+ messages: import("../web.js").BinaryOperatorAggregate<BaseMessage[], Messages>;
9
10
  }>;
@@ -112,6 +112,16 @@ class StateGraph extends graph_js_1.Graph {
112
112
  writable: true,
113
113
  value: void 0
114
114
  });
115
+ /**
116
+ * Map schemas to managed values
117
+ * @internal
118
+ */
119
+ Object.defineProperty(this, "_schemaDefinitions", {
120
+ enumerable: true,
121
+ configurable: true,
122
+ writable: true,
123
+ value: new Map()
124
+ });
115
125
  if (isStateGraphArgsWithInputOutputSchemas(fields)) {
116
126
  this._schemaDefinition = fields.input.spec;
117
127
  this._inputDefinition = fields.input.spec;
@@ -154,6 +164,11 @@ class StateGraph extends graph_js_1.Graph {
154
164
  ]);
155
165
  }
156
166
  _addSchema(stateDefinition) {
167
+ if (this._schemaDefinitions.has(stateDefinition)) {
168
+ return;
169
+ }
170
+ // TODO: Support managed values
171
+ this._schemaDefinitions.set(stateDefinition, stateDefinition);
157
172
  for (const [key, val] of Object.entries(stateDefinition)) {
158
173
  let channel;
159
174
  if (typeof val === "function") {
@@ -188,10 +203,14 @@ class StateGraph extends graph_js_1.Graph {
188
203
  if (key === graph_js_1.END || key === graph_js_1.START) {
189
204
  throw new Error(`Node \`${key}\` is reserved.`);
190
205
  }
206
+ if (options?.input !== undefined) {
207
+ this._addSchema(options.input.spec);
208
+ }
191
209
  const nodeSpec = {
192
210
  runnable: (0, runnables_1._coerceToRunnable)(action),
193
211
  retryPolicy: options?.retryPolicy,
194
212
  metadata: options?.metadata,
213
+ input: options?.input?.spec ?? this._schemaDefinition,
195
214
  };
196
215
  this.nodes[key] = nodeSpec;
197
216
  return this;
@@ -228,7 +247,7 @@ class StateGraph extends graph_js_1.Graph {
228
247
  ...(Array.isArray(interruptAfter) ? interruptAfter : []),
229
248
  ]);
230
249
  // prepare output channels
231
- const outputKeys = Object.keys(this._outputDefinition);
250
+ const outputKeys = Object.keys(this._schemaDefinitions.get(this._outputDefinition));
232
251
  const outputChannels = outputKeys.length === 1 && outputKeys[0] === ROOT ? ROOT : outputKeys;
233
252
  const streamKeys = Object.keys(this.channels);
234
253
  const streamChannels = streamKeys.length === 1 && streamKeys[0] === ROOT ? ROOT : streamKeys;
@@ -284,7 +303,7 @@ function _getChannels(schema) {
284
303
  }
285
304
  class CompiledStateGraph extends graph_js_1.CompiledGraph {
286
305
  attachNode(key, node) {
287
- const stateKeys = Object.keys(this.builder._inputDefinition);
306
+ const stateKeys = Object.keys(this.builder.channels);
288
307
  function getStateKey(key, input) {
289
308
  if (!input) {
290
309
  return write_js_1.SKIP_WRITE;
@@ -319,21 +338,26 @@ class CompiledStateGraph extends graph_js_1.CompiledGraph {
319
338
  });
320
339
  }
321
340
  else {
341
+ const inputDefinition = node?.input ?? this.builder._schemaDefinition;
342
+ const inputValues = Object.fromEntries(Object.keys(this.builder._schemaDefinitions.get(inputDefinition)).map((k) => [k, k]));
343
+ const isSingleInput = Object.keys(inputValues).length === 1 && ROOT in inputValues;
322
344
  this.channels[key] = new ephemeral_value_js_1.EphemeralValue(false);
323
345
  this.nodes[key] = new read_js_1.PregelNode({
324
346
  triggers: [],
325
347
  // read state keys
326
- channels: stateKeys.length === 1 && stateKeys[0] === ROOT
327
- ? stateKeys
328
- : stateKeys.reduce((acc, k) => {
329
- acc[k] = k;
330
- return acc;
331
- }, {}),
348
+ channels: isSingleInput ? Object.keys(inputValues) : inputValues,
332
349
  // publish to this channel and state keys
333
350
  writers: [
334
351
  new write_js_1.ChannelWrite(stateWriteEntries.concat({ channel: key, value: key }), [constants_js_1.TAG_HIDDEN]),
335
352
  ],
353
+ mapper: isSingleInput
354
+ ? undefined
355
+ : // eslint-disable-next-line @typescript-eslint/no-explicit-any
356
+ (input) => {
357
+ return Object.fromEntries(Object.entries(input).filter(([k]) => k in inputValues));
358
+ },
336
359
  bound: node?.runnable,
360
+ metadata: node?.metadata,
337
361
  retryPolicy: node?.retryPolicy,
338
362
  });
339
363
  }
@@ -15,11 +15,12 @@ export interface StateGraphArgs<Channels extends object | unknown> {
15
15
  }>;
16
16
  }
17
17
  export type StateGraphNodeSpec<RunInput, RunOutput> = NodeSpec<RunInput, RunOutput> & {
18
- input?: any;
18
+ input?: StateDefinition;
19
19
  retryPolicy?: RetryPolicy;
20
20
  };
21
21
  export type StateGraphAddNodeOptions = {
22
22
  retryPolicy?: RetryPolicy;
23
+ input?: AnnotationRoot<any>;
23
24
  } & AddNodeOptions;
24
25
  export type StateGraphArgsWithStateSchema<SD extends StateDefinition, I extends StateDefinition, O extends StateDefinition> = {
25
26
  stateSchema: AnnotationRoot<SD>;
@@ -101,10 +102,15 @@ export declare class StateGraph<SD extends StateDefinition | unknown, S = SD ext
101
102
  _inputDefinition: I;
102
103
  /** @internal */
103
104
  _outputDefinition: O;
105
+ /**
106
+ * Map schemas to managed values
107
+ * @internal
108
+ */
109
+ _schemaDefinitions: Map<any, any>;
104
110
  constructor(fields: SD extends StateDefinition ? SD | AnnotationRoot<SD> | StateGraphArgs<S> | StateGraphArgsWithStateSchema<SD, I, O> | StateGraphArgsWithInputOutputSchemas<SD, O> : StateGraphArgs<S>);
105
111
  get allEdges(): Set<[string, string]>;
106
112
  _addSchema(stateDefinition: StateDefinition): void;
107
- addNode<K extends string, NodeInput = S>(key: K, action: RunnableLike<NodeInput, U>, options?: StateGraphAddNodeOptions): StateGraph<SD, S, U, N | K, I, O>;
113
+ addNode<K extends string, NodeInput = S>(key: K, action: RunnableLike<NodeInput, U extends object ? U & Record<string, any> : U>, options?: StateGraphAddNodeOptions): StateGraph<SD, S, U, N | K, I, O>;
108
114
  addEdge(startKey: typeof START | N | N[], endKey: N | typeof END): this;
109
115
  compile({ checkpointer, interruptBefore, interruptAfter, }?: {
110
116
  checkpointer?: BaseCheckpointSaver;
@@ -109,6 +109,16 @@ export class StateGraph extends Graph {
109
109
  writable: true,
110
110
  value: void 0
111
111
  });
112
+ /**
113
+ * Map schemas to managed values
114
+ * @internal
115
+ */
116
+ Object.defineProperty(this, "_schemaDefinitions", {
117
+ enumerable: true,
118
+ configurable: true,
119
+ writable: true,
120
+ value: new Map()
121
+ });
112
122
  if (isStateGraphArgsWithInputOutputSchemas(fields)) {
113
123
  this._schemaDefinition = fields.input.spec;
114
124
  this._inputDefinition = fields.input.spec;
@@ -151,6 +161,11 @@ export class StateGraph extends Graph {
151
161
  ]);
152
162
  }
153
163
  _addSchema(stateDefinition) {
164
+ if (this._schemaDefinitions.has(stateDefinition)) {
165
+ return;
166
+ }
167
+ // TODO: Support managed values
168
+ this._schemaDefinitions.set(stateDefinition, stateDefinition);
154
169
  for (const [key, val] of Object.entries(stateDefinition)) {
155
170
  let channel;
156
171
  if (typeof val === "function") {
@@ -185,10 +200,14 @@ export class StateGraph extends Graph {
185
200
  if (key === END || key === START) {
186
201
  throw new Error(`Node \`${key}\` is reserved.`);
187
202
  }
203
+ if (options?.input !== undefined) {
204
+ this._addSchema(options.input.spec);
205
+ }
188
206
  const nodeSpec = {
189
207
  runnable: _coerceToRunnable(action),
190
208
  retryPolicy: options?.retryPolicy,
191
209
  metadata: options?.metadata,
210
+ input: options?.input?.spec ?? this._schemaDefinition,
192
211
  };
193
212
  this.nodes[key] = nodeSpec;
194
213
  return this;
@@ -225,7 +244,7 @@ export class StateGraph extends Graph {
225
244
  ...(Array.isArray(interruptAfter) ? interruptAfter : []),
226
245
  ]);
227
246
  // prepare output channels
228
- const outputKeys = Object.keys(this._outputDefinition);
247
+ const outputKeys = Object.keys(this._schemaDefinitions.get(this._outputDefinition));
229
248
  const outputChannels = outputKeys.length === 1 && outputKeys[0] === ROOT ? ROOT : outputKeys;
230
249
  const streamKeys = Object.keys(this.channels);
231
250
  const streamChannels = streamKeys.length === 1 && streamKeys[0] === ROOT ? ROOT : streamKeys;
@@ -280,7 +299,7 @@ function _getChannels(schema) {
280
299
  }
281
300
  export class CompiledStateGraph extends CompiledGraph {
282
301
  attachNode(key, node) {
283
- const stateKeys = Object.keys(this.builder._inputDefinition);
302
+ const stateKeys = Object.keys(this.builder.channels);
284
303
  function getStateKey(key, input) {
285
304
  if (!input) {
286
305
  return SKIP_WRITE;
@@ -315,21 +334,26 @@ export class CompiledStateGraph extends CompiledGraph {
315
334
  });
316
335
  }
317
336
  else {
337
+ const inputDefinition = node?.input ?? this.builder._schemaDefinition;
338
+ const inputValues = Object.fromEntries(Object.keys(this.builder._schemaDefinitions.get(inputDefinition)).map((k) => [k, k]));
339
+ const isSingleInput = Object.keys(inputValues).length === 1 && ROOT in inputValues;
318
340
  this.channels[key] = new EphemeralValue(false);
319
341
  this.nodes[key] = new PregelNode({
320
342
  triggers: [],
321
343
  // read state keys
322
- channels: stateKeys.length === 1 && stateKeys[0] === ROOT
323
- ? stateKeys
324
- : stateKeys.reduce((acc, k) => {
325
- acc[k] = k;
326
- return acc;
327
- }, {}),
344
+ channels: isSingleInput ? Object.keys(inputValues) : inputValues,
328
345
  // publish to this channel and state keys
329
346
  writers: [
330
347
  new ChannelWrite(stateWriteEntries.concat({ channel: key, value: key }), [TAG_HIDDEN]),
331
348
  ],
349
+ mapper: isSingleInput
350
+ ? undefined
351
+ : // eslint-disable-next-line @typescript-eslint/no-explicit-any
352
+ (input) => {
353
+ return Object.fromEntries(Object.entries(input).filter(([k]) => k in inputValues));
354
+ },
332
355
  bound: node?.runnable,
356
+ metadata: node?.metadata,
333
357
  retryPolicy: node?.retryPolicy,
334
358
  });
335
359
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph",
3
- "version": "0.1.10-rc.3",
3
+ "version": "0.2.0-rc.0",
4
4
  "description": "LangGraph",
5
5
  "type": "module",
6
6
  "engines": {
@@ -31,26 +31,19 @@
31
31
  "author": "LangChain",
32
32
  "license": "MIT",
33
33
  "dependencies": {
34
- "@langchain/core": ">=0.2.31 <0.3.0",
35
34
  "@langchain/langgraph-checkpoint": "~0.0.4",
36
- "@langchain/langgraph-checkpoint-sqlite": "~0.0.1",
37
35
  "double-ended-queue": "^2.1.0-0",
38
36
  "uuid": "^10.0.0",
39
37
  "zod": "^3.23.8"
40
38
  },
41
39
  "peerDependencies": {
42
- "better-sqlite3": "^9.5.0"
43
- },
44
- "peerDependenciesMeta": {
45
- "better-sqlite3": {
46
- "optional": true
47
- }
40
+ "@langchain/core": ">=0.2.31 <0.3.0"
48
41
  },
49
42
  "devDependencies": {
50
43
  "@jest/globals": "^29.5.0",
51
44
  "@langchain/anthropic": "^0.2.12",
52
- "@langchain/community": "^0.2.25",
53
- "@langchain/core": "^0.2.29",
45
+ "@langchain/community": "^0.2.31",
46
+ "@langchain/core": "^0.2.31",
54
47
  "@langchain/openai": "^0.2.4",
55
48
  "@langchain/scripts": ">=0.1.2 <0.2.0",
56
49
  "@swc/core": "^1.3.90",