@langchain/langgraph 0.2.16 → 0.2.17

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.
@@ -13,6 +13,7 @@ const write_js_1 = require("../pregel/write.cjs");
13
13
  const constants_js_1 = require("../constants.cjs");
14
14
  const utils_js_1 = require("../utils.cjs");
15
15
  const errors_js_1 = require("../errors.cjs");
16
+ const subgraph_js_1 = require("../pregel/utils/subgraph.cjs");
16
17
  /** Special reserved node name denoting the start of a graph. */
17
18
  exports.START = "__start__";
18
19
  /** Special reserved node name denoting the end of a graph. */
@@ -140,11 +141,13 @@ class Graph {
140
141
  if (key === exports.END) {
141
142
  throw new Error(`Node \`${key}\` is reserved.`);
142
143
  }
144
+ const runnable = (0, runnables_1._coerceToRunnable)(
145
+ // Account for arbitrary state due to Send API
146
+ action);
143
147
  this.nodes[key] = {
144
- runnable: (0, runnables_1._coerceToRunnable)(
145
- // Account for arbitrary state due to Send API
146
- action),
148
+ runnable,
147
149
  metadata: options?.metadata,
150
+ subgraphs: (0, subgraph_js_1.isPregelLike)(runnable) ? [runnable] : options?.subgraphs,
148
151
  };
149
152
  return this;
150
153
  }
@@ -300,6 +303,7 @@ class CompiledGraph extends index_js_1.Pregel {
300
303
  channels: [],
301
304
  triggers: [],
302
305
  metadata: node.metadata,
306
+ subgraphs: node.subgraphs,
303
307
  })
304
308
  .pipe(node.runnable)
305
309
  .pipe(new write_js_1.ChannelWrite([{ channel: key, value: write_js_1.PASSTHROUGH }], [constants_js_1.TAG_HIDDEN]));
@@ -28,9 +28,11 @@ export declare class Branch<IO, N extends string, CallOptions extends LangGraphR
28
28
  export type NodeSpec<RunInput, RunOutput> = {
29
29
  runnable: Runnable<RunInput, RunOutput>;
30
30
  metadata?: Record<string, unknown>;
31
+ subgraphs?: Pregel<any, any>[];
31
32
  };
32
33
  export type AddNodeOptions = {
33
34
  metadata?: Record<string, unknown>;
35
+ subgraphs?: Pregel<any, any>[];
34
36
  };
35
37
  export declare class Graph<N extends string = typeof END, RunInput = any, RunOutput = any, NodeSpecType extends NodeSpec<RunInput, RunOutput> = NodeSpec<RunInput, RunOutput>, C extends StateDefinition = StateDefinition> {
36
38
  nodes: Record<N, NodeSpecType>;
@@ -10,6 +10,7 @@ import { ChannelWrite, PASSTHROUGH } from "../pregel/write.js";
10
10
  import { _isSend, CHECKPOINT_NAMESPACE_END, CHECKPOINT_NAMESPACE_SEPARATOR, TAG_HIDDEN, } from "../constants.js";
11
11
  import { gatherIteratorSync, RunnableCallable } from "../utils.js";
12
12
  import { InvalidUpdateError, NodeInterrupt } from "../errors.js";
13
+ import { isPregelLike } from "../pregel/utils/subgraph.js";
13
14
  /** Special reserved node name denoting the start of a graph. */
14
15
  export const START = "__start__";
15
16
  /** Special reserved node name denoting the end of a graph. */
@@ -136,11 +137,13 @@ export class Graph {
136
137
  if (key === END) {
137
138
  throw new Error(`Node \`${key}\` is reserved.`);
138
139
  }
140
+ const runnable = _coerceToRunnable(
141
+ // Account for arbitrary state due to Send API
142
+ action);
139
143
  this.nodes[key] = {
140
- runnable: _coerceToRunnable(
141
- // Account for arbitrary state due to Send API
142
- action),
144
+ runnable,
143
145
  metadata: options?.metadata,
146
+ subgraphs: isPregelLike(runnable) ? [runnable] : options?.subgraphs,
144
147
  };
145
148
  return this;
146
149
  }
@@ -295,6 +298,7 @@ export class CompiledGraph extends Pregel {
295
298
  channels: [],
296
299
  triggers: [],
297
300
  metadata: node.metadata,
301
+ subgraphs: node.subgraphs,
298
302
  })
299
303
  .pipe(node.runnable)
300
304
  .pipe(new ChannelWrite([{ channel: key, value: PASSTHROUGH }], [TAG_HIDDEN]));
@@ -14,6 +14,7 @@ const constants_js_1 = require("../constants.cjs");
14
14
  const errors_js_1 = require("../errors.cjs");
15
15
  const annotation_js_1 = require("./annotation.cjs");
16
16
  const base_js_2 = require("../managed/base.cjs");
17
+ const subgraph_js_1 = require("../pregel/utils/subgraph.cjs");
17
18
  const ROOT = "__root__";
18
19
  /**
19
20
  * A graph whose nodes communicate by reading and writing to a shared state.
@@ -216,11 +217,16 @@ class StateGraph extends graph_js_1.Graph {
216
217
  if (options?.input !== undefined) {
217
218
  this._addSchema(options.input.spec);
218
219
  }
220
+ const runnable = (0, runnables_1._coerceToRunnable)(action);
219
221
  const nodeSpec = {
220
- runnable: (0, runnables_1._coerceToRunnable)(action),
222
+ runnable,
221
223
  retryPolicy: options?.retryPolicy,
222
224
  metadata: options?.metadata,
223
225
  input: options?.input?.spec ?? this._schemaDefinition,
226
+ subgraphs: (0, subgraph_js_1.isPregelLike)(runnable)
227
+ ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
228
+ [runnable]
229
+ : options?.subgraphs,
224
230
  };
225
231
  this.nodes[key] = nodeSpec;
226
232
  return this;
@@ -377,6 +383,7 @@ class CompiledStateGraph extends graph_js_1.CompiledGraph {
377
383
  bound: node?.runnable,
378
384
  metadata: node?.metadata,
379
385
  retryPolicy: node?.retryPolicy,
386
+ subgraphs: node?.subgraphs,
380
387
  });
381
388
  }
382
389
  }
@@ -11,6 +11,7 @@ import { _isSend, CHECKPOINT_NAMESPACE_END, CHECKPOINT_NAMESPACE_SEPARATOR, TAG_
11
11
  import { InvalidUpdateError } from "../errors.js";
12
12
  import { getChannel, } from "./annotation.js";
13
13
  import { isConfiguredManagedValue } from "../managed/base.js";
14
+ import { isPregelLike } from "../pregel/utils/subgraph.js";
14
15
  const ROOT = "__root__";
15
16
  /**
16
17
  * A graph whose nodes communicate by reading and writing to a shared state.
@@ -213,11 +214,16 @@ export class StateGraph extends Graph {
213
214
  if (options?.input !== undefined) {
214
215
  this._addSchema(options.input.spec);
215
216
  }
217
+ const runnable = _coerceToRunnable(action);
216
218
  const nodeSpec = {
217
- runnable: _coerceToRunnable(action),
219
+ runnable,
218
220
  retryPolicy: options?.retryPolicy,
219
221
  metadata: options?.metadata,
220
222
  input: options?.input?.spec ?? this._schemaDefinition,
223
+ subgraphs: isPregelLike(runnable)
224
+ ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
225
+ [runnable]
226
+ : options?.subgraphs,
221
227
  };
222
228
  this.nodes[key] = nodeSpec;
223
229
  return this;
@@ -373,6 +379,7 @@ export class CompiledStateGraph extends CompiledGraph {
373
379
  bound: node?.runnable,
374
380
  metadata: node?.metadata,
375
381
  retryPolicy: node?.retryPolicy,
382
+ subgraphs: node?.subgraphs,
376
383
  });
377
384
  }
378
385
  }
@@ -2,4 +2,4 @@ export { type AgentExecutorState, createAgentExecutor, } from "./agent_executor.
2
2
  export { type FunctionCallingExecutorState, createFunctionCallingExecutor, } from "./chat_agent_executor.js";
3
3
  export { type AgentState, createReactAgent } from "./react_agent_executor.js";
4
4
  export { type ToolExecutorArgs, type ToolInvocationInterface, ToolExecutor, } from "./tool_executor.js";
5
- export { ToolNode, toolsCondition } from "./tool_node.js";
5
+ export { ToolNode, toolsCondition, type ToolNodeOptions } from "./tool_node.js";
@@ -1,5 +1,5 @@
1
1
  import { BaseMessage } from "@langchain/core/messages";
2
- import { RunnableToolLike } from "@langchain/core/runnables";
2
+ import { RunnableConfig, RunnableToolLike } from "@langchain/core/runnables";
3
3
  import { StructuredToolInterface } from "@langchain/core/tools";
4
4
  import { RunnableCallable } from "../utils.js";
5
5
  import { END } from "../graph/graph.js";
@@ -130,6 +130,6 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
130
130
  tools: (StructuredToolInterface | RunnableToolLike)[];
131
131
  handleToolErrors: boolean;
132
132
  constructor(tools: (StructuredToolInterface | RunnableToolLike)[], options?: ToolNodeOptions);
133
- private run;
133
+ protected run(input: any, config: RunnableConfig): Promise<T>;
134
134
  }
135
135
  export declare function toolsCondition(state: BaseMessage[] | typeof MessagesAnnotation.State): "tools" | typeof END;
@@ -275,6 +275,7 @@ function _prepareSingleTask(taskPath, checkpoint, processes, channels, managed,
275
275
  name: packet.node,
276
276
  input: packet.args,
277
277
  proc: node,
278
+ subgraphs: proc.subgraphs,
278
279
  writes,
279
280
  config: (0, runnables_1.patchConfig)((0, runnables_1.mergeConfigs)(config, {
280
281
  metadata,
@@ -371,6 +372,7 @@ function _prepareSingleTask(taskPath, checkpoint, processes, channels, managed,
371
372
  name,
372
373
  input: val,
373
374
  proc: node,
375
+ subgraphs: proc.subgraphs,
374
376
  writes,
375
377
  config: (0, runnables_1.patchConfig)((0, runnables_1.mergeConfigs)(config, {
376
378
  metadata,
@@ -266,6 +266,7 @@ export function _prepareSingleTask(taskPath, checkpoint, processes, channels, ma
266
266
  name: packet.node,
267
267
  input: packet.args,
268
268
  proc: node,
269
+ subgraphs: proc.subgraphs,
269
270
  writes,
270
271
  config: patchConfig(mergeConfigs(config, {
271
272
  metadata,
@@ -362,6 +363,7 @@ export function _prepareSingleTask(taskPath, checkpoint, processes, channels, ma
362
363
  name,
363
364
  input: val,
364
365
  proc: node,
366
+ subgraphs: proc.subgraphs,
365
367
  writes,
366
368
  config: patchConfig(mergeConfigs(config, {
367
369
  metadata,
@@ -127,7 +127,8 @@ function* mapDebugCheckpoint(step, config, channels, streamChannels, metadata, t
127
127
  const parentNs = config.configurable?.checkpoint_ns;
128
128
  const taskStates = {};
129
129
  for (const task of tasks) {
130
- if (!(0, subgraph_js_1.findSubgraphPregel)(task.proc))
130
+ const candidates = task.subgraphs?.length ? task.subgraphs : [task.proc];
131
+ if (!candidates.find(subgraph_js_1.findSubgraphPregel))
131
132
  continue;
132
133
  let taskNs = `${task.name}:${task.id}`;
133
134
  if (parentNs)
@@ -121,7 +121,8 @@ export function* mapDebugCheckpoint(step, config, channels, streamChannels, meta
121
121
  const parentNs = config.configurable?.checkpoint_ns;
122
122
  const taskStates = {};
123
123
  for (const task of tasks) {
124
- if (!findSubgraphPregel(task.proc))
124
+ const candidates = task.subgraphs?.length ? task.subgraphs : [task.proc];
125
+ if (!candidates.find(findSubgraphPregel))
125
126
  continue;
126
127
  let taskNs = `${task.name}:${task.id}`;
127
128
  if (parentNs)
@@ -255,26 +255,28 @@ class Pregel extends runnables_1.Runnable {
255
255
  continue;
256
256
  }
257
257
  }
258
- const graph = (0, subgraph_js_1.findSubgraphPregel)(node.bound);
259
- // if found, yield recursively
260
- if (graph !== undefined) {
261
- if (name === namespace) {
262
- yield [name, graph];
263
- return;
264
- }
265
- if (namespace === undefined) {
266
- yield [name, graph];
267
- }
268
- if (recurse) {
269
- let newNamespace = namespace;
270
- if (namespace !== undefined) {
271
- newNamespace = namespace.slice(name.length + 1);
258
+ const candidates = node.subgraphs?.length ? node.subgraphs : [node.bound];
259
+ for (const candidate of candidates) {
260
+ const graph = (0, subgraph_js_1.findSubgraphPregel)(candidate);
261
+ if (graph !== undefined) {
262
+ if (name === namespace) {
263
+ yield [name, graph];
264
+ return;
272
265
  }
273
- for (const [subgraphName, subgraph] of graph.getSubgraphs(newNamespace, recurse)) {
274
- yield [
275
- `${name}${constants_js_1.CHECKPOINT_NAMESPACE_SEPARATOR}${subgraphName}`,
276
- subgraph,
277
- ];
266
+ if (namespace === undefined) {
267
+ yield [name, graph];
268
+ }
269
+ if (recurse) {
270
+ let newNamespace = namespace;
271
+ if (namespace !== undefined) {
272
+ newNamespace = namespace.slice(name.length + 1);
273
+ }
274
+ for (const [subgraphName, subgraph] of graph.getSubgraphs(newNamespace, recurse)) {
275
+ yield [
276
+ `${name}${constants_js_1.CHECKPOINT_NAMESPACE_SEPARATOR}${subgraphName}`,
277
+ subgraph,
278
+ ];
279
+ }
278
280
  }
279
281
  }
280
282
  }
@@ -248,26 +248,28 @@ export class Pregel extends Runnable {
248
248
  continue;
249
249
  }
250
250
  }
251
- const graph = findSubgraphPregel(node.bound);
252
- // if found, yield recursively
253
- if (graph !== undefined) {
254
- if (name === namespace) {
255
- yield [name, graph];
256
- return;
257
- }
258
- if (namespace === undefined) {
259
- yield [name, graph];
260
- }
261
- if (recurse) {
262
- let newNamespace = namespace;
263
- if (namespace !== undefined) {
264
- newNamespace = namespace.slice(name.length + 1);
251
+ const candidates = node.subgraphs?.length ? node.subgraphs : [node.bound];
252
+ for (const candidate of candidates) {
253
+ const graph = findSubgraphPregel(candidate);
254
+ if (graph !== undefined) {
255
+ if (name === namespace) {
256
+ yield [name, graph];
257
+ return;
265
258
  }
266
- for (const [subgraphName, subgraph] of graph.getSubgraphs(newNamespace, recurse)) {
267
- yield [
268
- `${name}${CHECKPOINT_NAMESPACE_SEPARATOR}${subgraphName}`,
269
- subgraph,
270
- ];
259
+ if (namespace === undefined) {
260
+ yield [name, graph];
261
+ }
262
+ if (recurse) {
263
+ let newNamespace = namespace;
264
+ if (namespace !== undefined) {
265
+ newNamespace = namespace.slice(name.length + 1);
266
+ }
267
+ for (const [subgraphName, subgraph] of graph.getSubgraphs(newNamespace, recurse)) {
268
+ yield [
269
+ `${name}${CHECKPOINT_NAMESPACE_SEPARATOR}${subgraphName}`,
270
+ subgraph,
271
+ ];
272
+ }
271
273
  }
272
274
  }
273
275
  }
@@ -63,7 +63,7 @@ const defaultRunnableBound =
63
63
  /* #__PURE__ */ new runnables_1.RunnablePassthrough();
64
64
  class PregelNode extends runnables_1.RunnableBinding {
65
65
  constructor(fields) {
66
- const { channels, triggers, mapper, writers, bound, kwargs, metadata, retryPolicy, tags, } = fields;
66
+ const { channels, triggers, mapper, writers, bound, kwargs, metadata, retryPolicy, tags, subgraphs, } = fields;
67
67
  const mergedTags = [
68
68
  ...(fields.config?.tags ? fields.config.tags : []),
69
69
  ...(tags ?? []),
@@ -139,6 +139,12 @@ class PregelNode extends runnables_1.RunnableBinding {
139
139
  writable: true,
140
140
  value: void 0
141
141
  });
142
+ Object.defineProperty(this, "subgraphs", {
143
+ enumerable: true,
144
+ configurable: true,
145
+ writable: true,
146
+ value: void 0
147
+ });
142
148
  this.channels = channels;
143
149
  this.triggers = triggers;
144
150
  this.mapper = mapper;
@@ -148,6 +154,7 @@ class PregelNode extends runnables_1.RunnableBinding {
148
154
  this.metadata = metadata ?? this.metadata;
149
155
  this.tags = mergedTags;
150
156
  this.retryPolicy = retryPolicy;
157
+ this.subgraphs = subgraphs;
151
158
  }
152
159
  getWriters() {
153
160
  const newWriters = [...this.writers];
@@ -20,6 +20,7 @@ interface PregelNodeArgs<RunInput, RunOutput> extends Partial<RunnableBindingArg
20
20
  config?: RunnableConfig;
21
21
  metadata?: Record<string, unknown>;
22
22
  retryPolicy?: RetryPolicy;
23
+ subgraphs?: Runnable[];
23
24
  }
24
25
  export type PregelNodeInputType = any;
25
26
  export type PregelNodeOutputType = any;
@@ -34,6 +35,7 @@ export declare class PregelNode<RunInput = PregelNodeInputType, RunOutput = Preg
34
35
  metadata: Record<string, unknown>;
35
36
  tags: string[];
36
37
  retryPolicy?: RetryPolicy;
38
+ subgraphs?: Runnable[];
37
39
  constructor(fields: PregelNodeArgs<RunInput, RunOutput>);
38
40
  getWriters(): Array<Runnable>;
39
41
  getNode(): Runnable<RunInput, RunOutput> | undefined;
@@ -59,7 +59,7 @@ const defaultRunnableBound =
59
59
  /* #__PURE__ */ new RunnablePassthrough();
60
60
  export class PregelNode extends RunnableBinding {
61
61
  constructor(fields) {
62
- const { channels, triggers, mapper, writers, bound, kwargs, metadata, retryPolicy, tags, } = fields;
62
+ const { channels, triggers, mapper, writers, bound, kwargs, metadata, retryPolicy, tags, subgraphs, } = fields;
63
63
  const mergedTags = [
64
64
  ...(fields.config?.tags ? fields.config.tags : []),
65
65
  ...(tags ?? []),
@@ -135,6 +135,12 @@ export class PregelNode extends RunnableBinding {
135
135
  writable: true,
136
136
  value: void 0
137
137
  });
138
+ Object.defineProperty(this, "subgraphs", {
139
+ enumerable: true,
140
+ configurable: true,
141
+ writable: true,
142
+ value: void 0
143
+ });
138
144
  this.channels = channels;
139
145
  this.triggers = triggers;
140
146
  this.mapper = mapper;
@@ -144,6 +150,7 @@ export class PregelNode extends RunnableBinding {
144
150
  this.metadata = metadata ?? this.metadata;
145
151
  this.tags = mergedTags;
146
152
  this.retryPolicy = retryPolicy;
153
+ this.subgraphs = subgraphs;
147
154
  }
148
155
  getWriters() {
149
156
  const newWriters = [...this.writers];
@@ -71,6 +71,7 @@ export interface PregelExecutableTask<N extends PropertyKey, C extends PropertyK
71
71
  readonly retry_policy?: RetryPolicy;
72
72
  readonly id: string;
73
73
  readonly path?: [string, ...(string | number)[]];
74
+ readonly subgraphs?: Runnable[];
74
75
  }
75
76
  export interface StateSnapshot {
76
77
  /**
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.findSubgraphPregel = void 0;
3
+ exports.findSubgraphPregel = exports.isPregelLike = void 0;
4
4
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
5
  function isRunnableSequence(x) {
6
6
  return "steps" in x && Array.isArray(x.steps);
@@ -15,6 +15,7 @@ x
15
15
  "outputChannels" &&
16
16
  x.outputChannels !== undefined);
17
17
  }
18
+ exports.isPregelLike = isPregelLike;
18
19
  function findSubgraphPregel(candidate
19
20
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
21
  ) {
@@ -1,3 +1,4 @@
1
- import { Runnable } from "@langchain/core/runnables";
1
+ import { Runnable, RunnableLike } from "@langchain/core/runnables";
2
2
  import type { PregelInterface } from "../types.js";
3
+ export declare function isPregelLike(x: PregelInterface<any, any> | RunnableLike<any, any, any>): x is PregelInterface<any, any>;
3
4
  export declare function findSubgraphPregel(candidate: Runnable): PregelInterface<any, any> | undefined;
@@ -2,7 +2,7 @@
2
2
  function isRunnableSequence(x) {
3
3
  return "steps" in x && Array.isArray(x.steps);
4
4
  }
5
- function isPregelLike(
5
+ export function isPregelLike(
6
6
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
7
  x
8
8
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph",
3
- "version": "0.2.16",
3
+ "version": "0.2.17",
4
4
  "description": "LangGraph",
5
5
  "type": "module",
6
6
  "engines": {