@langchain/langgraph 0.2.41 → 0.2.43-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.
Files changed (86) hide show
  1. package/README.md +237 -154
  2. package/dist/channels/any_value.cjs +10 -10
  3. package/dist/channels/any_value.d.ts +1 -1
  4. package/dist/channels/any_value.js +10 -10
  5. package/dist/channels/ephemeral_value.cjs +10 -9
  6. package/dist/channels/ephemeral_value.d.ts +1 -1
  7. package/dist/channels/ephemeral_value.js +10 -9
  8. package/dist/channels/last_value.cjs +8 -7
  9. package/dist/channels/last_value.d.ts +1 -1
  10. package/dist/channels/last_value.js +8 -7
  11. package/dist/constants.cjs +33 -6
  12. package/dist/constants.d.ts +17 -2
  13. package/dist/constants.js +32 -5
  14. package/dist/errors.d.ts +3 -3
  15. package/dist/func/index.cjs +272 -0
  16. package/dist/func/index.d.ts +310 -0
  17. package/dist/func/index.js +267 -0
  18. package/dist/func/types.cjs +15 -0
  19. package/dist/func/types.d.ts +59 -0
  20. package/dist/func/types.js +11 -0
  21. package/dist/graph/graph.cjs +31 -35
  22. package/dist/graph/graph.d.ts +1 -5
  23. package/dist/graph/graph.js +1 -5
  24. package/dist/graph/index.cjs +1 -3
  25. package/dist/graph/index.d.ts +1 -1
  26. package/dist/graph/index.js +1 -1
  27. package/dist/graph/message.d.ts +1 -1
  28. package/dist/graph/state.cjs +17 -17
  29. package/dist/graph/state.d.ts +2 -1
  30. package/dist/graph/state.js +2 -2
  31. package/dist/index.cjs +8 -0
  32. package/dist/index.d.ts +3 -0
  33. package/dist/index.js +3 -0
  34. package/dist/interrupt.cjs +21 -34
  35. package/dist/interrupt.d.ts +1 -1
  36. package/dist/interrupt.js +22 -35
  37. package/dist/prebuilt/agent_executor.cjs +3 -3
  38. package/dist/prebuilt/agent_executor.d.ts +1 -1
  39. package/dist/prebuilt/agent_executor.js +1 -1
  40. package/dist/prebuilt/chat_agent_executor.cjs +3 -3
  41. package/dist/prebuilt/chat_agent_executor.d.ts +1 -1
  42. package/dist/prebuilt/chat_agent_executor.js +1 -1
  43. package/dist/prebuilt/react_agent_executor.cjs +33 -8
  44. package/dist/prebuilt/react_agent_executor.d.ts +4 -1
  45. package/dist/prebuilt/react_agent_executor.js +31 -6
  46. package/dist/prebuilt/tool_node.cjs +1 -2
  47. package/dist/prebuilt/tool_node.d.ts +1 -1
  48. package/dist/prebuilt/tool_node.js +1 -2
  49. package/dist/pregel/algo.cjs +121 -12
  50. package/dist/pregel/algo.d.ts +8 -6
  51. package/dist/pregel/algo.js +122 -13
  52. package/dist/pregel/call.cjs +77 -0
  53. package/dist/pregel/call.d.ts +15 -0
  54. package/dist/pregel/call.js +71 -0
  55. package/dist/pregel/index.cjs +59 -96
  56. package/dist/pregel/index.d.ts +1 -10
  57. package/dist/pregel/index.js +61 -98
  58. package/dist/pregel/io.cjs +6 -1
  59. package/dist/pregel/io.js +7 -2
  60. package/dist/pregel/loop.cjs +109 -75
  61. package/dist/pregel/loop.d.ts +17 -23
  62. package/dist/pregel/loop.js +110 -75
  63. package/dist/pregel/messages.d.ts +1 -1
  64. package/dist/pregel/retry.cjs +22 -50
  65. package/dist/pregel/retry.d.ts +6 -6
  66. package/dist/pregel/retry.js +22 -50
  67. package/dist/pregel/runner.cjs +275 -0
  68. package/dist/pregel/runner.d.ts +64 -0
  69. package/dist/pregel/runner.js +271 -0
  70. package/dist/pregel/stream.cjs +71 -0
  71. package/dist/pregel/stream.d.ts +17 -0
  72. package/dist/pregel/stream.js +67 -0
  73. package/dist/pregel/types.cjs +54 -0
  74. package/dist/pregel/types.d.ts +78 -6
  75. package/dist/pregel/types.js +51 -1
  76. package/dist/pregel/utils/config.cjs +26 -1
  77. package/dist/pregel/utils/config.d.ts +14 -0
  78. package/dist/pregel/utils/config.js +22 -0
  79. package/dist/pregel/write.d.ts +1 -1
  80. package/dist/utils.cjs +15 -1
  81. package/dist/utils.d.ts +3 -1
  82. package/dist/utils.js +12 -0
  83. package/dist/web.cjs +7 -5
  84. package/dist/web.d.ts +4 -4
  85. package/dist/web.js +3 -3
  86. package/package.json +8 -8
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createAgentExecutor = void 0;
4
4
  const tool_executor_js_1 = require("./tool_executor.cjs");
5
5
  const state_js_1 = require("../graph/state.cjs");
6
- const index_js_1 = require("../graph/index.cjs");
6
+ const constants_js_1 = require("../constants.cjs");
7
7
  /** @ignore */
8
8
  function createAgentExecutor({ agentRunnable, tools, }) {
9
9
  let toolExecutor;
@@ -54,7 +54,7 @@ function createAgentExecutor({ agentRunnable, tools, }) {
54
54
  .addNode("action", executeTools)
55
55
  // Set the entrypoint as `agent`
56
56
  // This means that this node is the first one called
57
- .addEdge(index_js_1.START, "agent")
57
+ .addEdge(constants_js_1.START, "agent")
58
58
  // We now add a conditional edge
59
59
  .addConditionalEdges(
60
60
  // First, we define the start node. We use `agent`.
@@ -72,7 +72,7 @@ function createAgentExecutor({ agentRunnable, tools, }) {
72
72
  // If `tools`, then we call the tool node.
73
73
  continue: "action",
74
74
  // Otherwise we finish.
75
- end: index_js_1.END,
75
+ end: constants_js_1.END,
76
76
  })
77
77
  // We now add a normal edge from `tools` to `agent`.
78
78
  // This means that after `tools` is called, `agent` node is called next.
@@ -18,5 +18,5 @@ export interface AgentExecutorState {
18
18
  export declare function createAgentExecutor({ agentRunnable, tools, }: {
19
19
  agentRunnable: Runnable;
20
20
  tools: Array<Tool> | ToolExecutor;
21
- }): import("../graph/state.js").CompiledStateGraph<AgentExecutorState, Partial<AgentExecutorState>, "__start__" | "agent" | "action", import("../graph/annotation.js").StateDefinition, import("../graph/annotation.js").StateDefinition, import("../graph/annotation.js").StateDefinition>;
21
+ }): import("../graph/state.js").CompiledStateGraph<AgentExecutorState, Partial<AgentExecutorState>, "__start__" | "agent" | "action", import("../web.js").StateDefinition, import("../web.js").StateDefinition, import("../web.js").StateDefinition>;
22
22
  export {};
@@ -1,6 +1,6 @@
1
1
  import { ToolExecutor } from "./tool_executor.js";
2
2
  import { StateGraph } from "../graph/state.js";
3
- import { END, START } from "../graph/index.js";
3
+ import { END, START } from "../constants.js";
4
4
  /** @ignore */
5
5
  export function createAgentExecutor({ agentRunnable, tools, }) {
6
6
  let toolExecutor;
@@ -6,7 +6,7 @@ const messages_1 = require("@langchain/core/messages");
6
6
  const runnables_1 = require("@langchain/core/runnables");
7
7
  const tool_executor_js_1 = require("./tool_executor.cjs");
8
8
  const state_js_1 = require("../graph/state.cjs");
9
- const index_js_1 = require("../graph/index.cjs");
9
+ const constants_js_1 = require("../constants.cjs");
10
10
  /** @deprecated Use {@link createReactAgent} instead with tool calling. */
11
11
  function createFunctionCallingExecutor({ model, tools, }) {
12
12
  let toolExecutor;
@@ -99,7 +99,7 @@ function createFunctionCallingExecutor({ model, tools, }) {
99
99
  .addNode("action", new runnables_1.RunnableLambda({ func: callTool }))
100
100
  // Set the entrypoint as `agent`
101
101
  // This means that this node is the first one called
102
- .addEdge(index_js_1.START, "agent")
102
+ .addEdge(constants_js_1.START, "agent")
103
103
  // We now add a conditional edge
104
104
  .addConditionalEdges(
105
105
  // First, we define the start node. We use `agent`.
@@ -117,7 +117,7 @@ function createFunctionCallingExecutor({ model, tools, }) {
117
117
  // If `tools`, then we call the tool node.
118
118
  continue: "action",
119
119
  // Otherwise we finish.
120
- end: index_js_1.END,
120
+ end: constants_js_1.END,
121
121
  })
122
122
  // We now add a normal edge from `tools` to `agent`.
123
123
  // This means that after `tools` is called, `agent` node is called next.
@@ -3,7 +3,7 @@ import { BaseMessage } from "@langchain/core/messages";
3
3
  import { RunnableToolLike } from "@langchain/core/runnables";
4
4
  import { ToolExecutor } from "./tool_executor.js";
5
5
  import { CompiledStateGraph } from "../graph/state.js";
6
- import { START } from "../graph/index.js";
6
+ import { START } from "../constants.js";
7
7
  /** @deprecated Use {@link createReactAgent} instead with tool calling. */
8
8
  export type FunctionCallingExecutorState = {
9
9
  messages: Array<BaseMessage>;
@@ -3,7 +3,7 @@ import { FunctionMessage } from "@langchain/core/messages";
3
3
  import { RunnableLambda, } from "@langchain/core/runnables";
4
4
  import { ToolExecutor } from "./tool_executor.js";
5
5
  import { StateGraph, } from "../graph/state.js";
6
- import { END, START } from "../graph/index.js";
6
+ import { END, START } from "../constants.js";
7
7
  /** @deprecated Use {@link createReactAgent} instead with tool calling. */
8
8
  export function createFunctionCallingExecutor({ model, tools, }) {
9
9
  let toolExecutor;
@@ -7,6 +7,7 @@ const index_js_1 = require("../graph/index.cjs");
7
7
  const tool_node_js_1 = require("./tool_node.cjs");
8
8
  const annotation_js_1 = require("../graph/annotation.cjs");
9
9
  const message_js_1 = require("../graph/message.cjs");
10
+ const constants_js_1 = require("../constants.cjs");
10
11
  function _convertMessageModifierToStateModifier(messageModifier) {
11
12
  // Handle string or SystemMessage
12
13
  if (typeof messageModifier === "string" ||
@@ -117,7 +118,7 @@ exports.createReactAgentAnnotation = createReactAgentAnnotation;
117
118
  * ```
118
119
  */
119
120
  function createReactAgent(params) {
120
- const { llm, tools, messageModifier, stateModifier, stateSchema, checkpointSaver, interruptBefore, interruptAfter, store, responseFormat, } = params;
121
+ const { llm, tools, messageModifier, stateModifier, stateSchema, checkpointSaver, checkpointer, interruptBefore, interruptAfter, store, responseFormat, } = params;
121
122
  let toolClasses;
122
123
  if (!Array.isArray(tools)) {
123
124
  toolClasses = tools.tools;
@@ -132,12 +133,17 @@ function createReactAgent(params) {
132
133
  // we're passing store here for validation
133
134
  const preprocessor = _getModelPreprocessingRunnable(stateModifier, messageModifier);
134
135
  const modelRunnable = preprocessor.pipe(modelWithTools);
136
+ // If any of the tools are configured to return_directly after running,
137
+ // our graph needs to check if these were called
138
+ const shouldReturnDirect = new Set(toolClasses
139
+ .filter((tool) => "returnDirect" in tool && tool.returnDirect)
140
+ .map((tool) => tool.name));
135
141
  const shouldContinue = (state) => {
136
142
  const { messages } = state;
137
143
  const lastMessage = messages[messages.length - 1];
138
144
  if ((0, messages_1.isAIMessage)(lastMessage) &&
139
145
  (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)) {
140
- return responseFormat != null ? "generate_structured_response" : index_js_1.END;
146
+ return responseFormat != null ? "generate_structured_response" : constants_js_1.END;
141
147
  }
142
148
  else {
143
149
  return "continue";
@@ -171,26 +177,45 @@ function createReactAgent(params) {
171
177
  const workflow = new index_js_1.StateGraph(stateSchema ?? (0, exports.createReactAgentAnnotation)())
172
178
  .addNode("agent", callModel)
173
179
  .addNode("tools", new tool_node_js_1.ToolNode(toolClasses))
174
- .addEdge(index_js_1.START, "agent")
175
- .addEdge("tools", "agent");
180
+ .addEdge(constants_js_1.START, "agent");
176
181
  if (responseFormat !== undefined) {
177
182
  workflow
178
183
  .addNode("generate_structured_response", generateStructuredResponse)
179
- .addEdge("generate_structured_response", index_js_1.END)
184
+ .addEdge("generate_structured_response", constants_js_1.END)
180
185
  .addConditionalEdges("agent", shouldContinue, {
181
186
  continue: "tools",
182
- [index_js_1.END]: index_js_1.END,
187
+ [constants_js_1.END]: constants_js_1.END,
183
188
  generate_structured_response: "generate_structured_response",
184
189
  });
185
190
  }
186
191
  else {
187
192
  workflow.addConditionalEdges("agent", shouldContinue, {
188
193
  continue: "tools",
189
- [index_js_1.END]: index_js_1.END,
194
+ [constants_js_1.END]: constants_js_1.END,
190
195
  });
191
196
  }
197
+ const routeToolResponses = (state) => {
198
+ // Check the last consecutive tool calls
199
+ for (let i = state.messages.length - 1; i >= 0; i -= 1) {
200
+ const message = state.messages[i];
201
+ if (!(0, messages_1.isToolMessage)(message)) {
202
+ break;
203
+ }
204
+ // Check if this tool is configured to return directly
205
+ if (message.name !== undefined && shouldReturnDirect.has(message.name)) {
206
+ return constants_js_1.END;
207
+ }
208
+ }
209
+ return "agent";
210
+ };
211
+ if (shouldReturnDirect.size > 0) {
212
+ workflow.addConditionalEdges("tools", routeToolResponses, ["agent", constants_js_1.END]);
213
+ }
214
+ else {
215
+ workflow.addEdge("tools", "agent");
216
+ }
192
217
  return workflow.compile({
193
- checkpointer: checkpointSaver,
218
+ checkpointer: checkpointer ?? checkpointSaver,
194
219
  interruptBefore,
195
220
  interruptAfter,
196
221
  store,
@@ -4,11 +4,12 @@ import { Runnable, RunnableToolLike } from "@langchain/core/runnables";
4
4
  import { StructuredToolInterface } from "@langchain/core/tools";
5
5
  import { All, BaseCheckpointSaver, BaseStore } from "@langchain/langgraph-checkpoint";
6
6
  import { z } from "zod";
7
- import { START, CompiledStateGraph, AnnotationRoot } from "../graph/index.js";
7
+ import { CompiledStateGraph, AnnotationRoot } from "../graph/index.js";
8
8
  import { MessagesAnnotation } from "../graph/messages_annotation.js";
9
9
  import { ToolNode } from "./tool_node.js";
10
10
  import { LangGraphRunnableConfig } from "../pregel/runnable_types.js";
11
11
  import { Messages } from "../graph/message.js";
12
+ import { START } from "../constants.js";
12
13
  export interface AgentState<StructuredResponseType extends Record<string, any> = Record<string, any>> {
13
14
  messages: BaseMessage[];
14
15
  structuredResponse: StructuredResponseType;
@@ -91,6 +92,8 @@ export type CreateReactAgentParams<A extends AnnotationRoot<any> = AnnotationRoo
91
92
  stateSchema?: A;
92
93
  /** An optional checkpoint saver to persist the agent's state. */
93
94
  checkpointSaver?: BaseCheckpointSaver;
95
+ /** An optional checkpoint saver to persist the agent's state. Alias of "checkpointSaver". */
96
+ checkpointer?: BaseCheckpointSaver;
94
97
  /** An optional list of node names to interrupt before running. */
95
98
  interruptBefore?: N[] | All;
96
99
  /** An optional list of node names to interrupt after running. */
@@ -1,9 +1,10 @@
1
- import { isAIMessage, isBaseMessage, SystemMessage, } from "@langchain/core/messages";
1
+ import { isAIMessage, isBaseMessage, isToolMessage, SystemMessage, } from "@langchain/core/messages";
2
2
  import { Runnable, RunnableLambda, } from "@langchain/core/runnables";
3
- import { END, START, StateGraph, } from "../graph/index.js";
3
+ import { StateGraph, } from "../graph/index.js";
4
4
  import { ToolNode } from "./tool_node.js";
5
5
  import { Annotation } from "../graph/annotation.js";
6
6
  import { messagesStateReducer } from "../graph/message.js";
7
+ import { END, START } from "../constants.js";
7
8
  function _convertMessageModifierToStateModifier(messageModifier) {
8
9
  // Handle string or SystemMessage
9
10
  if (typeof messageModifier === "string" ||
@@ -113,7 +114,7 @@ export const createReactAgentAnnotation = () => Annotation.Root({
113
114
  * ```
114
115
  */
115
116
  export function createReactAgent(params) {
116
- const { llm, tools, messageModifier, stateModifier, stateSchema, checkpointSaver, interruptBefore, interruptAfter, store, responseFormat, } = params;
117
+ const { llm, tools, messageModifier, stateModifier, stateSchema, checkpointSaver, checkpointer, interruptBefore, interruptAfter, store, responseFormat, } = params;
117
118
  let toolClasses;
118
119
  if (!Array.isArray(tools)) {
119
120
  toolClasses = tools.tools;
@@ -128,6 +129,11 @@ export function createReactAgent(params) {
128
129
  // we're passing store here for validation
129
130
  const preprocessor = _getModelPreprocessingRunnable(stateModifier, messageModifier);
130
131
  const modelRunnable = preprocessor.pipe(modelWithTools);
132
+ // If any of the tools are configured to return_directly after running,
133
+ // our graph needs to check if these were called
134
+ const shouldReturnDirect = new Set(toolClasses
135
+ .filter((tool) => "returnDirect" in tool && tool.returnDirect)
136
+ .map((tool) => tool.name));
131
137
  const shouldContinue = (state) => {
132
138
  const { messages } = state;
133
139
  const lastMessage = messages[messages.length - 1];
@@ -167,8 +173,7 @@ export function createReactAgent(params) {
167
173
  const workflow = new StateGraph(stateSchema ?? createReactAgentAnnotation())
168
174
  .addNode("agent", callModel)
169
175
  .addNode("tools", new ToolNode(toolClasses))
170
- .addEdge(START, "agent")
171
- .addEdge("tools", "agent");
176
+ .addEdge(START, "agent");
172
177
  if (responseFormat !== undefined) {
173
178
  workflow
174
179
  .addNode("generate_structured_response", generateStructuredResponse)
@@ -185,8 +190,28 @@ export function createReactAgent(params) {
185
190
  [END]: END,
186
191
  });
187
192
  }
193
+ const routeToolResponses = (state) => {
194
+ // Check the last consecutive tool calls
195
+ for (let i = state.messages.length - 1; i >= 0; i -= 1) {
196
+ const message = state.messages[i];
197
+ if (!isToolMessage(message)) {
198
+ break;
199
+ }
200
+ // Check if this tool is configured to return directly
201
+ if (message.name !== undefined && shouldReturnDirect.has(message.name)) {
202
+ return END;
203
+ }
204
+ }
205
+ return "agent";
206
+ };
207
+ if (shouldReturnDirect.size > 0) {
208
+ workflow.addConditionalEdges("tools", routeToolResponses, ["agent", END]);
209
+ }
210
+ else {
211
+ workflow.addEdge("tools", "agent");
212
+ }
188
213
  return workflow.compile({
189
- checkpointer: checkpointSaver,
214
+ checkpointer: checkpointer ?? checkpointSaver,
190
215
  interruptBefore,
191
216
  interruptAfter,
192
217
  store,
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toolsCondition = exports.ToolNode = void 0;
4
4
  const messages_1 = require("@langchain/core/messages");
5
5
  const utils_js_1 = require("../utils.cjs");
6
- const graph_js_1 = require("../graph/graph.cjs");
7
6
  const errors_js_1 = require("../errors.cjs");
8
7
  const constants_js_1 = require("../constants.cjs");
9
8
  /**
@@ -218,7 +217,7 @@ function toolsCondition(state) {
218
217
  return "tools";
219
218
  }
220
219
  else {
221
- return graph_js_1.END;
220
+ return constants_js_1.END;
222
221
  }
223
222
  }
224
223
  exports.toolsCondition = toolsCondition;
@@ -2,8 +2,8 @@ import { BaseMessage } from "@langchain/core/messages";
2
2
  import { RunnableConfig, RunnableToolLike } from "@langchain/core/runnables";
3
3
  import { StructuredToolInterface } from "@langchain/core/tools";
4
4
  import { RunnableCallable } from "../utils.js";
5
- import { END } from "../graph/graph.js";
6
5
  import { MessagesAnnotation } from "../graph/messages_annotation.js";
6
+ import { END } from "../constants.js";
7
7
  export type ToolNodeOptions = {
8
8
  name?: string;
9
9
  tags?: string[];
@@ -1,8 +1,7 @@
1
1
  import { ToolMessage, isBaseMessage, } from "@langchain/core/messages";
2
2
  import { RunnableCallable } from "../utils.js";
3
- import { END } from "../graph/graph.js";
4
3
  import { isGraphInterrupt } from "../errors.js";
5
- import { isCommand } from "../constants.js";
4
+ import { END, isCommand } from "../constants.js";
6
5
  /**
7
6
  * A node that runs the tools requested in the last AIMessage. It can be used
8
7
  * either in StateGraph with a "messages" key or in MessageGraph. If multiple
@@ -7,8 +7,10 @@ const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
7
7
  const base_js_1 = require("../channels/base.cjs");
8
8
  const io_js_1 = require("./io.cjs");
9
9
  const constants_js_1 = require("../constants.cjs");
10
+ const types_js_1 = require("./types.cjs");
10
11
  const errors_js_1 = require("../errors.cjs");
11
12
  const index_js_1 = require("./utils/index.cjs");
13
+ const call_js_1 = require("./call.cjs");
12
14
  const increment = (current) => {
13
15
  return current !== undefined ? current + 1 : 1;
14
16
  };
@@ -79,7 +81,7 @@ commit, processes, managed,
79
81
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
80
82
  writes) {
81
83
  for (const [chan, value] of writes) {
82
- if (chan === constants_js_1.TASKS) {
84
+ if (chan === constants_js_1.TASKS && value != null) {
83
85
  if (!(0, constants_js_1._isSend)(value)) {
84
86
  throw new errors_js_1.InvalidUpdateError(`Invalid packet type, expected SendProtocol, got ${JSON.stringify(value)}`);
85
87
  }
@@ -93,7 +95,14 @@ writes) {
93
95
  commit(writes);
94
96
  }
95
97
  exports._localWrite = _localWrite;
96
- const IGNORE = new Set([constants_js_1.PUSH, constants_js_1.RESUME, constants_js_1.INTERRUPT]);
98
+ const IGNORE = new Set([
99
+ constants_js_1.NO_WRITES,
100
+ constants_js_1.PUSH,
101
+ constants_js_1.RESUME,
102
+ constants_js_1.INTERRUPT,
103
+ constants_js_1.RETURN,
104
+ constants_js_1.ERROR,
105
+ ]);
97
106
  function _applyWrites(checkpoint, channels, tasks,
98
107
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
108
  getNextVersion) {
@@ -260,7 +269,84 @@ function _prepareSingleTask(taskPath, checkpoint, pendingWrites, processes, chan
260
269
  const { step, checkpointer, manager } = extra;
261
270
  const configurable = config.configurable ?? {};
262
271
  const parentNamespace = configurable.checkpoint_ns ?? "";
263
- if (taskPath[0] === constants_js_1.PUSH) {
272
+ if (taskPath[0] === constants_js_1.PUSH && (0, types_js_1.isCall)(taskPath[taskPath.length - 1])) {
273
+ const call = taskPath[taskPath.length - 1];
274
+ const proc = (0, call_js_1.getRunnableForFunc)(call.name, call.func);
275
+ const triggers = [constants_js_1.PUSH];
276
+ const checkpointNamespace = parentNamespace === ""
277
+ ? call.name
278
+ : `${parentNamespace}${constants_js_1.CHECKPOINT_NAMESPACE_SEPARATOR}${call.name}`;
279
+ const id = (0, langgraph_checkpoint_1.uuid5)(JSON.stringify([
280
+ checkpointNamespace,
281
+ step.toString(),
282
+ call.name,
283
+ constants_js_1.PUSH,
284
+ taskPath[1],
285
+ taskPath[2],
286
+ ]), checkpoint.id);
287
+ const taskCheckpointNamespace = `${checkpointNamespace}${constants_js_1.CHECKPOINT_NAMESPACE_END}${id}`;
288
+ const metadata = {
289
+ langgraph_step: step,
290
+ langgraph_node: call.name,
291
+ langgraph_triggers: triggers,
292
+ langgraph_path: taskPath.slice(0, 3),
293
+ langgraph_checkpoint_ns: taskCheckpointNamespace,
294
+ };
295
+ if (forExecution) {
296
+ const writes = [];
297
+ const task = {
298
+ name: call.name,
299
+ input: call.input,
300
+ proc,
301
+ writes,
302
+ config: (0, runnables_1.patchConfig)((0, runnables_1.mergeConfigs)(config, {
303
+ metadata,
304
+ store: extra.store ?? config.store,
305
+ }), {
306
+ runName: call.name,
307
+ callbacks: manager?.getChild(`graph:step:${step}`),
308
+ configurable: {
309
+ [constants_js_1.CONFIG_KEY_TASK_ID]: id,
310
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
311
+ [constants_js_1.CONFIG_KEY_SEND]: (writes_) => _localWrite(step, (items) => writes.push(...items), processes, managed, writes_),
312
+ [constants_js_1.CONFIG_KEY_READ]: (select_, fresh_ = false) => _localRead(step, checkpoint, channels, managed, {
313
+ name: call.name,
314
+ writes: writes,
315
+ triggers,
316
+ path: taskPath.slice(0, 3),
317
+ }, select_, fresh_),
318
+ [constants_js_1.CONFIG_KEY_CHECKPOINTER]: checkpointer ?? configurable[constants_js_1.CONFIG_KEY_CHECKPOINTER],
319
+ [constants_js_1.CONFIG_KEY_CHECKPOINT_MAP]: {
320
+ ...configurable[constants_js_1.CONFIG_KEY_CHECKPOINT_MAP],
321
+ [parentNamespace]: checkpoint.id,
322
+ },
323
+ [constants_js_1.CONFIG_KEY_SCRATCHPAD]: _scratchpad([
324
+ ...(pendingWrites || []),
325
+ ...(configurable[constants_js_1.CONFIG_KEY_SCRATCHPAD]?.resume || []).map((v) => [id, constants_js_1.RESUME, v]),
326
+ ], id),
327
+ [constants_js_1.CONFIG_KEY_PREVIOUS_STATE]: checkpoint.channel_values[constants_js_1.PREVIOUS],
328
+ checkpoint_id: undefined,
329
+ checkpoint_ns: taskCheckpointNamespace,
330
+ },
331
+ }),
332
+ triggers,
333
+ retry_policy: call.retry,
334
+ id,
335
+ path: taskPath.slice(0, 3),
336
+ writers: [],
337
+ };
338
+ return task;
339
+ }
340
+ else {
341
+ return {
342
+ id,
343
+ name: call.name,
344
+ interrupts: [],
345
+ path: taskPath.slice(0, 3),
346
+ };
347
+ }
348
+ }
349
+ else if (taskPath[0] === constants_js_1.PUSH) {
264
350
  const index = typeof taskPath[1] === "number"
265
351
  ? taskPath[1]
266
352
  : parseInt(taskPath[1], 10);
@@ -332,11 +418,15 @@ function _prepareSingleTask(taskPath, checkpoint, pendingWrites, processes, chan
332
418
  ...configurable[constants_js_1.CONFIG_KEY_CHECKPOINT_MAP],
333
419
  [parentNamespace]: checkpoint.id,
334
420
  },
335
- [constants_js_1.CONFIG_KEY_WRITES]: [
421
+ [constants_js_1.CONFIG_KEY_SCRATCHPAD]: _scratchpad([
336
422
  ...(pendingWrites || []),
337
- ...(configurable[constants_js_1.CONFIG_KEY_WRITES] || []),
338
- ].filter((w) => w[0] === constants_js_1.NULL_TASK_ID || w[0] === taskId),
339
- [constants_js_1.CONFIG_KEY_SCRATCHPAD]: {},
423
+ ...(configurable[constants_js_1.CONFIG_KEY_SCRATCHPAD]?.resume || []).map((v) => [
424
+ taskId,
425
+ constants_js_1.RESUME,
426
+ v,
427
+ ]),
428
+ ], taskId),
429
+ [constants_js_1.CONFIG_KEY_PREVIOUS_STATE]: checkpoint.channel_values[constants_js_1.PREVIOUS],
340
430
  checkpoint_id: undefined,
341
431
  checkpoint_ns: taskCheckpointNamespace,
342
432
  },
@@ -350,7 +440,12 @@ function _prepareSingleTask(taskPath, checkpoint, pendingWrites, processes, chan
350
440
  }
351
441
  }
352
442
  else {
353
- return { id: taskId, name: packet.node, interrupts: [], path: taskPath };
443
+ return {
444
+ id: taskId,
445
+ name: packet.node,
446
+ interrupts: [],
447
+ path: taskPath,
448
+ };
354
449
  }
355
450
  }
356
451
  else if (taskPath[0] === constants_js_1.PULL) {
@@ -438,11 +533,15 @@ function _prepareSingleTask(taskPath, checkpoint, pendingWrites, processes, chan
438
533
  ...configurable[constants_js_1.CONFIG_KEY_CHECKPOINT_MAP],
439
534
  [parentNamespace]: checkpoint.id,
440
535
  },
441
- [constants_js_1.CONFIG_KEY_WRITES]: [
536
+ [constants_js_1.CONFIG_KEY_SCRATCHPAD]: _scratchpad([
442
537
  ...(pendingWrites || []),
443
- ...(configurable[constants_js_1.CONFIG_KEY_WRITES] || []),
444
- ].filter((w) => w[0] === constants_js_1.NULL_TASK_ID || w[0] === taskId),
445
- [constants_js_1.CONFIG_KEY_SCRATCHPAD]: {},
538
+ ...(configurable[constants_js_1.CONFIG_KEY_SCRATCHPAD]?.resume || []).map((v) => [
539
+ taskId,
540
+ constants_js_1.RESUME,
541
+ v,
542
+ ]),
543
+ ], taskId),
544
+ [constants_js_1.CONFIG_KEY_PREVIOUS_STATE]: checkpoint.channel_values[constants_js_1.PREVIOUS],
446
545
  checkpoint_id: undefined,
447
546
  checkpoint_ns: taskCheckpointNamespace,
448
547
  },
@@ -533,3 +632,13 @@ function _procInput(step, proc, managed, channels, forExecution) {
533
632
  }
534
633
  return val;
535
634
  }
635
+ function _scratchpad(pendingWrites, taskId) {
636
+ return {
637
+ callCounter: 0,
638
+ interruptCounter: -1,
639
+ resume: pendingWrites
640
+ .filter(([writeTaskId, chan]) => writeTaskId === taskId && chan === constants_js_1.RESUME)
641
+ .flatMap(([_writeTaskId, _chan, resume]) => resume),
642
+ nullResume: pendingWrites.find(([writeTaskId, chan]) => writeTaskId === constants_js_1.NULL_TASK_ID && chan === constants_js_1.RESUME)?.[2],
643
+ };
644
+ }
@@ -1,10 +1,11 @@
1
1
  import { RunnableConfig } from "@langchain/core/runnables";
2
2
  import { CallbackManagerForChainRun } from "@langchain/core/callbacks/manager";
3
- import { All, BaseCheckpointSaver, Checkpoint, ReadonlyCheckpoint, type PendingWrite, type PendingWriteValue, BaseStore } from "@langchain/langgraph-checkpoint";
3
+ import { All, BaseCheckpointSaver, Checkpoint, ReadonlyCheckpoint, type PendingWrite, type PendingWriteValue, BaseStore, CheckpointPendingWrite } from "@langchain/langgraph-checkpoint";
4
4
  import { BaseChannel } from "../channels/base.js";
5
5
  import { PregelNode } from "./read.js";
6
- import { PregelExecutableTask, PregelTaskDescription } from "./types.js";
6
+ import { PregelExecutableTask, PregelTaskDescription, SimpleTaskPath, TaskPath } from "./types.js";
7
7
  import { ManagedValueMapping } from "../managed/base.js";
8
+ import { IterableReadableWritableStream } from "./stream.js";
8
9
  /**
9
10
  * Construct a type with a set of properties K of type T
10
11
  */
@@ -15,7 +16,7 @@ export type WritesProtocol<C = string> = {
15
16
  name: string;
16
17
  writes: PendingWrite<C>[];
17
18
  triggers: string[];
18
- path?: [string, ...(string | number)[]];
19
+ path?: TaskPath;
19
20
  };
20
21
  export declare const increment: (current?: number) => number;
21
22
  export declare function shouldInterrupt<N extends PropertyKey, C extends PropertyKey>(checkpoint: Checkpoint, interruptNodes: All | N[], tasks: PregelExecutableTask<N, C>[]): boolean;
@@ -28,6 +29,7 @@ export type NextTaskExtraFields = {
28
29
  checkpointer?: BaseCheckpointSaver;
29
30
  manager?: CallbackManagerForChainRun;
30
31
  store?: BaseStore;
32
+ stream?: IterableReadableWritableStream;
31
33
  };
32
34
  export type NextTaskExtraFieldsWithStore = NextTaskExtraFields & {
33
35
  store?: BaseStore;
@@ -37,6 +39,6 @@ export type NextTaskExtraFieldsWithoutStore = NextTaskExtraFields & {
37
39
  };
38
40
  export declare function _prepareNextTasks<Nn extends StrRecord<string, PregelNode>, Cc extends StrRecord<string, BaseChannel>>(checkpoint: ReadonlyCheckpoint, pendingWrites: [string, string, unknown][] | undefined, processes: Nn, channels: Cc, managed: ManagedValueMapping, config: RunnableConfig, forExecution: false, extra: NextTaskExtraFieldsWithoutStore): Record<string, PregelTaskDescription>;
39
41
  export declare function _prepareNextTasks<Nn extends StrRecord<string, PregelNode>, Cc extends StrRecord<string, BaseChannel>>(checkpoint: ReadonlyCheckpoint, pendingWrites: [string, string, unknown][] | undefined, processes: Nn, channels: Cc, managed: ManagedValueMapping, config: RunnableConfig, forExecution: true, extra: NextTaskExtraFieldsWithStore): Record<string, PregelExecutableTask<keyof Nn, keyof Cc>>;
40
- export declare function _prepareSingleTask<Nn extends StrRecord<string, PregelNode>, Cc extends StrRecord<string, BaseChannel>>(taskPath: [string, string | number], checkpoint: ReadonlyCheckpoint, pendingWrites: [string, string, unknown][] | undefined, processes: Nn, channels: Cc, managed: ManagedValueMapping, config: RunnableConfig, forExecution: false, extra: NextTaskExtraFields): PregelTaskDescription | undefined;
41
- export declare function _prepareSingleTask<Nn extends StrRecord<string, PregelNode>, Cc extends StrRecord<string, BaseChannel>>(taskPath: [string, ...(string | number)[]], checkpoint: ReadonlyCheckpoint, pendingWrites: [string, string, unknown][] | undefined, processes: Nn, channels: Cc, managed: ManagedValueMapping, config: RunnableConfig, forExecution: true, extra: NextTaskExtraFields): PregelExecutableTask<keyof Nn, keyof Cc> | undefined;
42
- export declare function _prepareSingleTask<Nn extends StrRecord<string, PregelNode>, Cc extends StrRecord<string, BaseChannel>>(taskPath: [string, ...(string | number)[]], checkpoint: ReadonlyCheckpoint, pendingWrites: [string, string, unknown][] | undefined, processes: Nn, channels: Cc, managed: ManagedValueMapping, config: RunnableConfig, forExecution: boolean, extra: NextTaskExtraFieldsWithStore): PregelTaskDescription | PregelExecutableTask<keyof Nn, keyof Cc> | undefined;
42
+ export declare function _prepareSingleTask<Nn extends StrRecord<string, PregelNode>, Cc extends StrRecord<string, BaseChannel>>(taskPath: SimpleTaskPath, checkpoint: ReadonlyCheckpoint, pendingWrites: CheckpointPendingWrite[] | undefined, processes: Nn, channels: Cc, managed: ManagedValueMapping, config: RunnableConfig, forExecution: false, extra: NextTaskExtraFields): PregelTaskDescription | undefined;
43
+ export declare function _prepareSingleTask<Nn extends StrRecord<string, PregelNode>, Cc extends StrRecord<string, BaseChannel>>(taskPath: TaskPath, checkpoint: ReadonlyCheckpoint, pendingWrites: CheckpointPendingWrite[] | undefined, processes: Nn, channels: Cc, managed: ManagedValueMapping, config: RunnableConfig, forExecution: true, extra: NextTaskExtraFields): PregelExecutableTask<keyof Nn, keyof Cc> | undefined;
44
+ export declare function _prepareSingleTask<Nn extends StrRecord<string, PregelNode>, Cc extends StrRecord<string, BaseChannel>>(taskPath: TaskPath, checkpoint: ReadonlyCheckpoint, pendingWrites: CheckpointPendingWrite[] | undefined, processes: Nn, channels: Cc, managed: ManagedValueMapping, config: RunnableConfig, forExecution: boolean, extra: NextTaskExtraFieldsWithStore): PregelTaskDescription | PregelExecutableTask<keyof Nn, keyof Cc> | undefined;