langchain 1.2.12 → 1.2.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.
- package/CHANGELOG.md +22 -0
- package/README.md +8 -1
- package/dist/agents/ReactAgent.cjs +59 -39
- package/dist/agents/ReactAgent.cjs.map +1 -1
- package/dist/agents/ReactAgent.js +60 -40
- package/dist/agents/ReactAgent.js.map +1 -1
- package/dist/agents/annotation.cjs +67 -49
- package/dist/agents/annotation.cjs.map +1 -1
- package/dist/agents/annotation.js +70 -52
- package/dist/agents/annotation.js.map +1 -1
- package/dist/agents/index.cjs.map +1 -1
- package/dist/agents/index.d.cts +45 -22
- package/dist/agents/index.d.cts.map +1 -1
- package/dist/agents/index.d.ts +45 -22
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/middleware/hitl.cjs +1 -1
- package/dist/agents/middleware/hitl.d.ts +1 -1
- package/dist/agents/middleware/hitl.js +1 -1
- package/dist/agents/middleware/llmToolSelector.d.ts +1 -1
- package/dist/agents/middleware/modelCallLimit.d.ts +1 -1
- package/dist/agents/middleware/pii.d.ts +1 -1
- package/dist/agents/middleware/piiRedaction.d.ts +1 -1
- package/dist/agents/middleware/provider/anthropic/promptCaching.cjs +15 -37
- package/dist/agents/middleware/provider/anthropic/promptCaching.cjs.map +1 -1
- package/dist/agents/middleware/provider/anthropic/promptCaching.d.ts +1 -1
- package/dist/agents/middleware/provider/anthropic/promptCaching.js +15 -37
- package/dist/agents/middleware/provider/anthropic/promptCaching.js.map +1 -1
- package/dist/agents/middleware/summarization.cjs +1 -1
- package/dist/agents/middleware/summarization.d.ts +1 -1
- package/dist/agents/middleware/summarization.js +21 -21
- package/dist/agents/middleware/summarization.js.map +1 -1
- package/dist/agents/middleware/toolCallLimit.cjs +1 -1
- package/dist/agents/middleware/toolCallLimit.d.ts +1 -1
- package/dist/agents/middleware/toolCallLimit.js +11 -11
- package/dist/agents/middleware/toolCallLimit.js.map +1 -1
- package/dist/agents/middleware/toolEmulator.cjs +1 -1
- package/dist/agents/middleware/toolEmulator.cjs.map +1 -1
- package/dist/agents/middleware/toolEmulator.js +1 -1
- package/dist/agents/middleware/toolEmulator.js.map +1 -1
- package/dist/agents/middleware/types.cjs.map +1 -1
- package/dist/agents/middleware/types.d.cts +40 -21
- package/dist/agents/middleware/types.d.cts.map +1 -1
- package/dist/agents/middleware/types.d.ts +40 -21
- package/dist/agents/middleware/types.d.ts.map +1 -1
- package/dist/agents/middleware/types.js.map +1 -1
- package/dist/agents/middleware.cjs +20 -1
- package/dist/agents/middleware.cjs.map +1 -1
- package/dist/agents/middleware.d.cts +25 -5
- package/dist/agents/middleware.d.cts.map +1 -1
- package/dist/agents/middleware.d.ts +25 -5
- package/dist/agents/middleware.d.ts.map +1 -1
- package/dist/agents/middleware.js +20 -1
- package/dist/agents/middleware.js.map +1 -1
- package/dist/agents/nodes/AfterAgentNode.cjs.map +1 -1
- package/dist/agents/nodes/AfterAgentNode.js.map +1 -1
- package/dist/agents/nodes/AfterModelNode.cjs.map +1 -1
- package/dist/agents/nodes/AfterModelNode.js.map +1 -1
- package/dist/agents/nodes/AgentNode.cjs +1 -1
- package/dist/agents/nodes/AgentNode.cjs.map +1 -1
- package/dist/agents/nodes/AgentNode.js +1 -1
- package/dist/agents/nodes/AgentNode.js.map +1 -1
- package/dist/agents/nodes/BeforeAgentNode.cjs.map +1 -1
- package/dist/agents/nodes/BeforeAgentNode.js.map +1 -1
- package/dist/agents/nodes/BeforeModelNode.cjs.map +1 -1
- package/dist/agents/nodes/BeforeModelNode.js.map +1 -1
- package/dist/agents/nodes/ToolNode.cjs +69 -20
- package/dist/agents/nodes/ToolNode.cjs.map +1 -1
- package/dist/agents/nodes/ToolNode.js +69 -20
- package/dist/agents/nodes/ToolNode.js.map +1 -1
- package/dist/agents/nodes/middleware.cjs.map +1 -1
- package/dist/agents/nodes/middleware.js.map +1 -1
- package/dist/agents/nodes/utils.cjs +22 -9
- package/dist/agents/nodes/utils.cjs.map +1 -1
- package/dist/agents/nodes/utils.js +19 -6
- package/dist/agents/nodes/utils.js.map +1 -1
- package/dist/agents/tests/utils.cjs +1 -1
- package/dist/agents/tests/utils.d.ts +1 -1
- package/dist/agents/tests/utils.js +1 -1
- package/dist/agents/types.d.cts +5 -5
- package/dist/agents/types.d.cts.map +1 -1
- package/dist/agents/types.d.ts +5 -5
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/utils.cjs +32 -4
- package/dist/agents/utils.cjs.map +1 -1
- package/dist/agents/utils.js +32 -4
- package/dist/agents/utils.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# langchain
|
|
2
2
|
|
|
3
|
+
## 1.2.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#9854](https://github.com/langchain-ai/langchainjs/pull/9854) [`160b5bf`](https://github.com/langchain-ai/langchainjs/commit/160b5bfe49f31190d28ec10a95075ef845c49fa3) Thanks [@christian-bromann](https://github.com/christian-bromann)! - fix(anthropic): apply cache_control at final formatting layer
|
|
8
|
+
|
|
9
|
+
- [#9850](https://github.com/langchain-ai/langchainjs/pull/9850) [`b56bf9e`](https://github.com/langchain-ai/langchainjs/commit/b56bf9e05a3190be58835e336ffb775c5d585fca) Thanks [@joeljohn159](https://github.com/joeljohn159)! - Fix `ToolNode` to route missing tool errors through `handleToolErrors` instead of throwing, allowing agents to recover when LLMs hallucinate tool names.
|
|
10
|
+
|
|
11
|
+
- [#9847](https://github.com/langchain-ai/langchainjs/pull/9847) [`9cd35ae`](https://github.com/langchain-ai/langchainjs/commit/9cd35ae6ed878be88d3e68371df92cebc8d880ee) Thanks [@christian-bromann](https://github.com/christian-bromann)! - feat(langchain): add dynamic tool registration via middleware
|
|
12
|
+
|
|
13
|
+
- [#9839](https://github.com/langchain-ai/langchainjs/pull/9839) [`134121a`](https://github.com/langchain-ai/langchainjs/commit/134121a6fc7e0ad1653bb5ce2ec347c61638c4df) Thanks [@maahir30](https://github.com/maahir30)! - ## Add state schema support to agents
|
|
14
|
+
- Introduce `createAgentState` function replacing `createAgentAnnotationConditional`
|
|
15
|
+
- Migrate from Zod-based schemas to LangGraph's native `StateSchema`, `ReducedValue`, and `UntrackedValue` primitives
|
|
16
|
+
- Support both `StateSchema` and Zod v3/v4 objects as input schemas
|
|
17
|
+
- Automatically merge state fields from user-provided schemas and middleware
|
|
18
|
+
- Properly handle reducer metadata extraction from Zod v4 schemas via `schemaMetaRegistry`
|
|
19
|
+
- Generate separate input/output schemas to avoid channel conflicts with reducers
|
|
20
|
+
- Add comprehensive test coverage for state schema functionality
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [[`05a9733`](https://github.com/langchain-ai/langchainjs/commit/05a9733448a10764c0bfd070af859c33e623b998)]:
|
|
23
|
+
- @langchain/core@1.1.17
|
|
24
|
+
|
|
3
25
|
## 1.2.12
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -18,7 +18,13 @@ To help you ship LangChain apps to production faster, check out [LangSmith](http
|
|
|
18
18
|
|
|
19
19
|
You can use npm, pnpm, or yarn to install LangChain.js
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
```sh
|
|
22
|
+
npm install -S langchain
|
|
23
|
+
# or
|
|
24
|
+
pnpm install langchain
|
|
25
|
+
# or
|
|
26
|
+
yarn add langchain
|
|
27
|
+
```
|
|
22
28
|
|
|
23
29
|
## 🚀 Why use LangChain?
|
|
24
30
|
|
|
@@ -33,6 +39,7 @@ Use LangChain for:
|
|
|
33
39
|
|
|
34
40
|
- [LangSmith](https://www.langchain.com/langsmith) - Unified developer platform for building, testing, and monitoring LLM applications. With LangSmith, you can debug poor-performing LLM app runs, evaluate agent trajectories, gain visibility in production, and deploy agents with confidence.
|
|
35
41
|
- [LangGraph](https://docs.langchain.com/oss/javascript/langgraph/overview) - Build agents that can reliably handle complex tasks with LangGraph, our low-level agent orchestration framework. LangGraph offers customizable architecture, long-term memory, and human-in-the-loop workflows — and is trusted in production by companies like LinkedIn, Uber, Klarna, and GitLab.
|
|
42
|
+
- [Deep Agents](https://docs.langchain.com/oss/javascript/deepagents/overview) - Build sophisticated "deep" agents that go beyond simple tool-calling loops. Deep Agents combines planning tools, sub-agent spawning, file system access, and detailed prompts to handle complex, multi-step tasks — inspired by applications like Claude Code and Deep Research.
|
|
36
43
|
|
|
37
44
|
## 🌐 Supported Environments
|
|
38
45
|
|
|
@@ -72,12 +72,12 @@ var ReactAgent = class {
|
|
|
72
72
|
* Create a schema that merges agent base schema with middleware state schemas
|
|
73
73
|
* Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata
|
|
74
74
|
*/
|
|
75
|
-
const { state, input, output } = require_annotation.
|
|
76
|
-
const workflow = new __langchain_langgraph.StateGraph({
|
|
77
|
-
state,
|
|
75
|
+
const { state, input, output } = require_annotation.createAgentState(this.options.responseFormat !== void 0, this.options.stateSchema, this.options.middleware);
|
|
76
|
+
const workflow = new __langchain_langgraph.StateGraph(state, {
|
|
78
77
|
input,
|
|
79
|
-
output
|
|
80
|
-
|
|
78
|
+
output,
|
|
79
|
+
context: this.options.contextSchema
|
|
80
|
+
});
|
|
81
81
|
const allNodeWorkflows = workflow;
|
|
82
82
|
const beforeAgentNodes = [];
|
|
83
83
|
const beforeModelNodes = [];
|
|
@@ -157,10 +157,18 @@ var ReactAgent = class {
|
|
|
157
157
|
*/
|
|
158
158
|
allNodeWorkflows.addNode(require_AgentNode.AGENT_NODE_NAME, this.#agentNode);
|
|
159
159
|
/**
|
|
160
|
-
*
|
|
160
|
+
* Check if any middleware has wrapToolCall defined.
|
|
161
|
+
* If so, we need to create a ToolNode even without pre-registered tools
|
|
162
|
+
* to allow middleware to handle dynamically registered tools.
|
|
161
163
|
*/
|
|
162
|
-
|
|
163
|
-
|
|
164
|
+
const hasWrapToolCallMiddleware = middleware.some((m) => m.wrapToolCall);
|
|
165
|
+
const clientTools = toolClasses.filter(require_utils.isClientTool);
|
|
166
|
+
/**
|
|
167
|
+
* Create ToolNode if we have client-side tools OR if middleware defines wrapToolCall
|
|
168
|
+
* (which may handle dynamically registered tools)
|
|
169
|
+
*/
|
|
170
|
+
if (clientTools.length > 0 || hasWrapToolCallMiddleware) {
|
|
171
|
+
const toolNode = new require_ToolNode.ToolNode(clientTools, {
|
|
164
172
|
signal: this.options.signal,
|
|
165
173
|
wrapToolCall: require_utils.wrapToolCall(middleware)
|
|
166
174
|
});
|
|
@@ -176,17 +184,20 @@ var ReactAgent = class {
|
|
|
176
184
|
const loopEntryNode = beforeModelNodes.length > 0 ? beforeModelNodes[0].name : require_AgentNode.AGENT_NODE_NAME;
|
|
177
185
|
const exitNode = afterAgentNodes.length > 0 ? afterAgentNodes[afterAgentNodes.length - 1].name : __langchain_langgraph.END;
|
|
178
186
|
allNodeWorkflows.addEdge(__langchain_langgraph.START, entryNode);
|
|
179
|
-
|
|
187
|
+
/**
|
|
188
|
+
* Determine if we have tools available for routing.
|
|
189
|
+
* This includes both registered client tools AND dynamic tools via middleware.
|
|
190
|
+
*/
|
|
191
|
+
const hasToolsAvailable = clientTools.length > 0 || hasWrapToolCallMiddleware;
|
|
180
192
|
for (let i = 0; i < beforeAgentNodes.length; i++) {
|
|
181
193
|
const node = beforeAgentNodes[i];
|
|
182
194
|
const current = node.name;
|
|
183
195
|
const isLast = i === beforeAgentNodes.length - 1;
|
|
184
196
|
const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;
|
|
185
197
|
if (node.allowed && node.allowed.length > 0) {
|
|
186
|
-
const
|
|
187
|
-
const allowedMapped = node.allowed.map((t) => require_utils$1.parseJumpToTarget(t)).filter((dest) => dest !== require_ToolNode.TOOLS_NODE_NAME || hasTools);
|
|
198
|
+
const allowedMapped = node.allowed.map((t) => require_utils$1.parseJumpToTarget(t)).filter((dest) => dest !== require_ToolNode.TOOLS_NODE_NAME || hasToolsAvailable);
|
|
188
199
|
const destinations = Array.from(new Set([nextDefault, ...allowedMapped.map((dest) => dest === __langchain_langgraph.END ? exitNode : dest)]));
|
|
189
|
-
allNodeWorkflows.addConditionalEdges(current, this.#createBeforeAgentRouter(clientTools, nextDefault, exitNode), destinations);
|
|
200
|
+
allNodeWorkflows.addConditionalEdges(current, this.#createBeforeAgentRouter(clientTools, nextDefault, exitNode, hasToolsAvailable), destinations);
|
|
190
201
|
} else allNodeWorkflows.addEdge(current, nextDefault);
|
|
191
202
|
}
|
|
192
203
|
for (let i = 0; i < beforeModelNodes.length; i++) {
|
|
@@ -195,16 +206,15 @@ var ReactAgent = class {
|
|
|
195
206
|
const isLast = i === beforeModelNodes.length - 1;
|
|
196
207
|
const nextDefault = isLast ? require_AgentNode.AGENT_NODE_NAME : beforeModelNodes[i + 1].name;
|
|
197
208
|
if (node.allowed && node.allowed.length > 0) {
|
|
198
|
-
const
|
|
199
|
-
const allowedMapped = node.allowed.map((t) => require_utils$1.parseJumpToTarget(t)).filter((dest) => dest !== require_ToolNode.TOOLS_NODE_NAME || hasTools);
|
|
209
|
+
const allowedMapped = node.allowed.map((t) => require_utils$1.parseJumpToTarget(t)).filter((dest) => dest !== require_ToolNode.TOOLS_NODE_NAME || hasToolsAvailable);
|
|
200
210
|
const destinations = Array.from(new Set([nextDefault, ...allowedMapped]));
|
|
201
|
-
allNodeWorkflows.addConditionalEdges(current, this.#createBeforeModelRouter(clientTools, nextDefault), destinations);
|
|
211
|
+
allNodeWorkflows.addConditionalEdges(current, this.#createBeforeModelRouter(clientTools, nextDefault, hasToolsAvailable), destinations);
|
|
202
212
|
} else allNodeWorkflows.addEdge(current, nextDefault);
|
|
203
213
|
}
|
|
204
214
|
const lastAfterModelNode = afterModelNodes.at(-1);
|
|
205
215
|
if (afterModelNodes.length > 0 && lastAfterModelNode) allNodeWorkflows.addEdge(require_AgentNode.AGENT_NODE_NAME, lastAfterModelNode.name);
|
|
206
216
|
else {
|
|
207
|
-
const modelPaths = this.#getModelPaths(clientTools);
|
|
217
|
+
const modelPaths = this.#getModelPaths(clientTools, false, hasToolsAvailable);
|
|
208
218
|
const destinations = modelPaths.map((p) => p === __langchain_langgraph.END ? exitNode : p);
|
|
209
219
|
if (destinations.length === 1) allNodeWorkflows.addEdge(require_AgentNode.AGENT_NODE_NAME, destinations[0]);
|
|
210
220
|
else allNodeWorkflows.addConditionalEdges(require_AgentNode.AGENT_NODE_NAME, this.#createModelRouter(exitNode), destinations);
|
|
@@ -214,49 +224,46 @@ var ReactAgent = class {
|
|
|
214
224
|
const current = node.name;
|
|
215
225
|
const nextDefault = afterModelNodes[i - 1].name;
|
|
216
226
|
if (node.allowed && node.allowed.length > 0) {
|
|
217
|
-
const
|
|
218
|
-
const allowedMapped = node.allowed.map((t) => require_utils$1.parseJumpToTarget(t)).filter((dest) => dest !== require_ToolNode.TOOLS_NODE_NAME || hasTools);
|
|
227
|
+
const allowedMapped = node.allowed.map((t) => require_utils$1.parseJumpToTarget(t)).filter((dest) => dest !== require_ToolNode.TOOLS_NODE_NAME || hasToolsAvailable);
|
|
219
228
|
const destinations = Array.from(new Set([nextDefault, ...allowedMapped]));
|
|
220
|
-
allNodeWorkflows.addConditionalEdges(current, this.#createAfterModelSequenceRouter(clientTools, node.allowed, nextDefault), destinations);
|
|
229
|
+
allNodeWorkflows.addConditionalEdges(current, this.#createAfterModelSequenceRouter(clientTools, node.allowed, nextDefault, hasToolsAvailable), destinations);
|
|
221
230
|
} else allNodeWorkflows.addEdge(current, nextDefault);
|
|
222
231
|
}
|
|
223
232
|
if (afterModelNodes.length > 0) {
|
|
224
233
|
const firstAfterModel = afterModelNodes[0];
|
|
225
234
|
const firstAfterModelNode = firstAfterModel.name;
|
|
226
|
-
const modelPaths = this.#getModelPaths(clientTools, true).filter((p) => p !== require_ToolNode.TOOLS_NODE_NAME ||
|
|
235
|
+
const modelPaths = this.#getModelPaths(clientTools, true, hasToolsAvailable).filter((p) => p !== require_ToolNode.TOOLS_NODE_NAME || hasToolsAvailable);
|
|
227
236
|
const allowJump = Boolean(firstAfterModel.allowed && firstAfterModel.allowed.length > 0);
|
|
228
237
|
const destinations = modelPaths.map((p) => p === __langchain_langgraph.END ? exitNode : p);
|
|
229
|
-
allNodeWorkflows.addConditionalEdges(firstAfterModelNode, this.#createAfterModelRouter(clientTools, allowJump, exitNode), destinations);
|
|
238
|
+
allNodeWorkflows.addConditionalEdges(firstAfterModelNode, this.#createAfterModelRouter(clientTools, allowJump, exitNode, hasToolsAvailable), destinations);
|
|
230
239
|
}
|
|
231
240
|
for (let i = afterAgentNodes.length - 1; i > 0; i--) {
|
|
232
241
|
const node = afterAgentNodes[i];
|
|
233
242
|
const current = node.name;
|
|
234
243
|
const nextDefault = afterAgentNodes[i - 1].name;
|
|
235
244
|
if (node.allowed && node.allowed.length > 0) {
|
|
236
|
-
const
|
|
237
|
-
const allowedMapped = node.allowed.map((t) => require_utils$1.parseJumpToTarget(t)).filter((dest) => dest !== require_ToolNode.TOOLS_NODE_NAME || hasTools);
|
|
245
|
+
const allowedMapped = node.allowed.map((t) => require_utils$1.parseJumpToTarget(t)).filter((dest) => dest !== require_ToolNode.TOOLS_NODE_NAME || hasToolsAvailable);
|
|
238
246
|
const destinations = Array.from(new Set([nextDefault, ...allowedMapped]));
|
|
239
|
-
allNodeWorkflows.addConditionalEdges(current, this.#createAfterModelSequenceRouter(clientTools, node.allowed, nextDefault), destinations);
|
|
247
|
+
allNodeWorkflows.addConditionalEdges(current, this.#createAfterModelSequenceRouter(clientTools, node.allowed, nextDefault, hasToolsAvailable), destinations);
|
|
240
248
|
} else allNodeWorkflows.addEdge(current, nextDefault);
|
|
241
249
|
}
|
|
242
250
|
if (afterAgentNodes.length > 0) {
|
|
243
251
|
const firstAfterAgent = afterAgentNodes[0];
|
|
244
252
|
const firstAfterAgentNode = firstAfterAgent.name;
|
|
245
253
|
if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {
|
|
246
|
-
const
|
|
247
|
-
const allowedMapped = firstAfterAgent.allowed.map((t) => require_utils$1.parseJumpToTarget(t)).filter((dest) => dest !== require_ToolNode.TOOLS_NODE_NAME || hasTools);
|
|
254
|
+
const allowedMapped = firstAfterAgent.allowed.map((t) => require_utils$1.parseJumpToTarget(t)).filter((dest) => dest !== require_ToolNode.TOOLS_NODE_NAME || hasToolsAvailable);
|
|
248
255
|
/**
|
|
249
256
|
* For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)
|
|
250
257
|
* The default destination (when no jump occurs) should be END
|
|
251
258
|
*/
|
|
252
259
|
const destinations = Array.from(new Set([__langchain_langgraph.END, ...allowedMapped]));
|
|
253
|
-
allNodeWorkflows.addConditionalEdges(firstAfterAgentNode, this.#createAfterModelSequenceRouter(clientTools, firstAfterAgent.allowed, __langchain_langgraph.END), destinations);
|
|
260
|
+
allNodeWorkflows.addConditionalEdges(firstAfterAgentNode, this.#createAfterModelSequenceRouter(clientTools, firstAfterAgent.allowed, __langchain_langgraph.END, hasToolsAvailable), destinations);
|
|
254
261
|
} else allNodeWorkflows.addEdge(firstAfterAgentNode, __langchain_langgraph.END);
|
|
255
262
|
}
|
|
256
263
|
/**
|
|
257
|
-
* add edges for tools node
|
|
264
|
+
* add edges for tools node (includes both registered tools and dynamic tools via middleware)
|
|
258
265
|
*/
|
|
259
|
-
if (
|
|
266
|
+
if (hasToolsAvailable) {
|
|
260
267
|
const toolReturnTarget = loopEntryNode;
|
|
261
268
|
if (shouldReturnDirect.size > 0) allNodeWorkflows.addConditionalEdges(require_ToolNode.TOOLS_NODE_NAME, this.#createToolsRouter(shouldReturnDirect, exitNode), [toolReturnTarget, exitNode]);
|
|
262
269
|
else allNodeWorkflows.addEdge(require_ToolNode.TOOLS_NODE_NAME, toolReturnTarget);
|
|
@@ -281,11 +288,12 @@ var ReactAgent = class {
|
|
|
281
288
|
* Get possible edge destinations from model node.
|
|
282
289
|
* @param toolClasses names of tools to call
|
|
283
290
|
* @param includeModelRequest whether to include "model_request" as a valid path (for jumpTo routing)
|
|
291
|
+
* @param hasToolsAvailable whether tools are available (includes dynamic tools via middleware)
|
|
284
292
|
* @returns list of possible edge destinations
|
|
285
293
|
*/
|
|
286
|
-
#getModelPaths(toolClasses, includeModelRequest = false) {
|
|
294
|
+
#getModelPaths(toolClasses, includeModelRequest = false, hasToolsAvailable = toolClasses.length > 0) {
|
|
287
295
|
const paths = [];
|
|
288
|
-
if (
|
|
296
|
+
if (hasToolsAvailable) paths.push(require_ToolNode.TOOLS_NODE_NAME);
|
|
289
297
|
if (includeModelRequest) paths.push(require_AgentNode.AGENT_NODE_NAME);
|
|
290
298
|
paths.push(__langchain_langgraph.END);
|
|
291
299
|
return paths;
|
|
@@ -344,9 +352,10 @@ var ReactAgent = class {
|
|
|
344
352
|
* @param toolClasses - Available tool classes for validation
|
|
345
353
|
* @param allowJump - Whether jumping is allowed
|
|
346
354
|
* @param exitNode - The exit node to route to (could be after_agent or END)
|
|
355
|
+
* @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)
|
|
347
356
|
* @returns Router function that handles jumpTo logic and normal routing
|
|
348
357
|
*/
|
|
349
|
-
#createAfterModelRouter(toolClasses, allowJump, exitNode) {
|
|
358
|
+
#createAfterModelRouter(toolClasses, allowJump, exitNode, hasToolsAvailable = toolClasses.length > 0) {
|
|
350
359
|
const hasStructuredResponse = Boolean(this.options.responseFormat);
|
|
351
360
|
return (state) => {
|
|
352
361
|
const builtInState = state;
|
|
@@ -357,7 +366,7 @@ var ReactAgent = class {
|
|
|
357
366
|
const destination = require_utils$1.parseJumpToTarget(builtInState.jumpTo);
|
|
358
367
|
if (destination === __langchain_langgraph.END) return exitNode;
|
|
359
368
|
if (destination === require_ToolNode.TOOLS_NODE_NAME) {
|
|
360
|
-
if (
|
|
369
|
+
if (!hasToolsAvailable) return exitNode;
|
|
361
370
|
return new __langchain_langgraph.Send(require_ToolNode.TOOLS_NODE_NAME, {
|
|
362
371
|
...state,
|
|
363
372
|
jumpTo: void 0
|
|
@@ -391,8 +400,12 @@ var ReactAgent = class {
|
|
|
391
400
|
/**
|
|
392
401
|
* Router for afterModel sequence nodes (connecting later middlewares to earlier ones),
|
|
393
402
|
* honoring allowed jump targets and defaulting to the next node.
|
|
403
|
+
* @param toolClasses - Available tool classes for validation
|
|
404
|
+
* @param allowed - List of allowed jump targets
|
|
405
|
+
* @param nextDefault - Default node to route to
|
|
406
|
+
* @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)
|
|
394
407
|
*/
|
|
395
|
-
#createAfterModelSequenceRouter(toolClasses, allowed, nextDefault) {
|
|
408
|
+
#createAfterModelSequenceRouter(toolClasses, allowed, nextDefault, hasToolsAvailable = toolClasses.length > 0) {
|
|
396
409
|
const allowedSet = new Set(allowed.map((t) => require_utils$1.parseJumpToTarget(t)));
|
|
397
410
|
return (state) => {
|
|
398
411
|
const builtInState = state;
|
|
@@ -400,7 +413,7 @@ var ReactAgent = class {
|
|
|
400
413
|
const dest = require_utils$1.parseJumpToTarget(builtInState.jumpTo);
|
|
401
414
|
if (dest === __langchain_langgraph.END && allowedSet.has(__langchain_langgraph.END)) return __langchain_langgraph.END;
|
|
402
415
|
if (dest === require_ToolNode.TOOLS_NODE_NAME && allowedSet.has(require_ToolNode.TOOLS_NODE_NAME)) {
|
|
403
|
-
if (
|
|
416
|
+
if (!hasToolsAvailable) return __langchain_langgraph.END;
|
|
404
417
|
return new __langchain_langgraph.Send(require_ToolNode.TOOLS_NODE_NAME, {
|
|
405
418
|
...state,
|
|
406
419
|
jumpTo: void 0
|
|
@@ -418,8 +431,12 @@ var ReactAgent = class {
|
|
|
418
431
|
* Create routing function for jumpTo functionality after beforeAgent hooks.
|
|
419
432
|
* Falls back to the default next node if no jumpTo is present.
|
|
420
433
|
* When jumping to END, routes to exitNode (which could be an afterAgent node).
|
|
434
|
+
* @param toolClasses - Available tool classes for validation
|
|
435
|
+
* @param nextDefault - Default node to route to
|
|
436
|
+
* @param exitNode - Exit node to route to (could be after_agent or END)
|
|
437
|
+
* @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)
|
|
421
438
|
*/
|
|
422
|
-
#createBeforeAgentRouter(toolClasses, nextDefault, exitNode) {
|
|
439
|
+
#createBeforeAgentRouter(toolClasses, nextDefault, exitNode, hasToolsAvailable = toolClasses.length > 0) {
|
|
423
440
|
return (state) => {
|
|
424
441
|
const builtInState = state;
|
|
425
442
|
if (!builtInState.jumpTo) return nextDefault;
|
|
@@ -430,7 +447,7 @@ var ReactAgent = class {
|
|
|
430
447
|
*/
|
|
431
448
|
return exitNode;
|
|
432
449
|
if (destination === require_ToolNode.TOOLS_NODE_NAME) {
|
|
433
|
-
if (
|
|
450
|
+
if (!hasToolsAvailable) return exitNode;
|
|
434
451
|
return new __langchain_langgraph.Send(require_ToolNode.TOOLS_NODE_NAME, {
|
|
435
452
|
...state,
|
|
436
453
|
jumpTo: void 0
|
|
@@ -445,15 +462,18 @@ var ReactAgent = class {
|
|
|
445
462
|
/**
|
|
446
463
|
* Create routing function for jumpTo functionality after beforeModel hooks.
|
|
447
464
|
* Falls back to the default next node if no jumpTo is present.
|
|
465
|
+
* @param toolClasses - Available tool classes for validation
|
|
466
|
+
* @param nextDefault - Default node to route to
|
|
467
|
+
* @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)
|
|
448
468
|
*/
|
|
449
|
-
#createBeforeModelRouter(toolClasses, nextDefault) {
|
|
469
|
+
#createBeforeModelRouter(toolClasses, nextDefault, hasToolsAvailable = toolClasses.length > 0) {
|
|
450
470
|
return (state) => {
|
|
451
471
|
const builtInState = state;
|
|
452
472
|
if (!builtInState.jumpTo) return nextDefault;
|
|
453
473
|
const destination = require_utils$1.parseJumpToTarget(builtInState.jumpTo);
|
|
454
474
|
if (destination === __langchain_langgraph.END) return __langchain_langgraph.END;
|
|
455
475
|
if (destination === require_ToolNode.TOOLS_NODE_NAME) {
|
|
456
|
-
if (
|
|
476
|
+
if (!hasToolsAvailable) return __langchain_langgraph.END;
|
|
457
477
|
return new __langchain_langgraph.Send(require_ToolNode.TOOLS_NODE_NAME, {
|
|
458
478
|
...state,
|
|
459
479
|
jumpTo: void 0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactAgent.cjs","names":["StateManager","options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >","#toolBehaviorVersion","validateLLMHasNoBoundTools","isClientTool","createAgentAnnotationConditional","StateGraph","beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][]","#agentNode","AgentNode","normalizeSystemPrompt","beforeAgentNode: BeforeAgentNode | undefined","beforeModelNode: BeforeModelNode | undefined","afterModelNode: AfterModelNode | undefined","afterAgentNode: AfterAgentNode | undefined","BeforeAgentNode","#stateManager","getHookConstraint","BeforeModelNode","AfterModelNode","AfterAgentNode","AGENT_NODE_NAME","ToolNode","wrapToolCall","TOOLS_NODE_NAME","entryNode: string","END","START","parseJumpToTarget","#createBeforeAgentRouter","#createBeforeModelRouter","#getModelPaths","#createModelRouter","#createAfterModelSequenceRouter","#createAfterModelRouter","#createToolsRouter","#graph","toolClasses: (ClientTool | ServerTool)[]","includeModelRequest: boolean","paths: BaseGraphDestination[]","shouldReturnDirect: Set<string>","exitNode: string | typeof END","state: Record<string, unknown>","ToolMessage","AIMessage","Send","allowJump: boolean","allowed: string[]","nextDefault: string","#initializeMiddlewareStates","state: InvokeStateParameter<Types>","config: RunnableConfig","Command","initializeMiddlewareStates","config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >","config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TEncoding\n >","params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }","config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" }","streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]","config?: RunnableConfig","options?: GetStateOptions","options?: CheckpointListOptions","namespace?: string","recurse?: boolean","inputConfig: LangGraphRunnableConfig","values: Record<string, unknown> | unknown","asNode?: string"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\n\nimport {\n StateGraph,\n END,\n START,\n Send,\n Command,\n CompiledStateGraph,\n type GetStateOptions,\n type LangGraphRunnableConfig,\n type StreamMode,\n type StreamOutputMap,\n type PregelOptions,\n} from \"@langchain/langgraph\";\nimport type { CheckpointListOptions } from \"@langchain/langgraph-checkpoint\";\nimport {\n ToolMessage,\n AIMessage,\n MessageStructure,\n} from \"@langchain/core/messages\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport type { Runnable, RunnableConfig } from \"@langchain/core/runnables\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createAgentAnnotationConditional } from \"./annotation.js\";\nimport {\n isClientTool,\n validateLLMHasNoBoundTools,\n wrapToolCall,\n normalizeSystemPrompt,\n} from \"./utils.js\";\n\nimport { AgentNode, AGENT_NODE_NAME } from \"./nodes/AgentNode.js\";\nimport { ToolNode, TOOLS_NODE_NAME } from \"./nodes/ToolNode.js\";\nimport { BeforeAgentNode } from \"./nodes/BeforeAgentNode.js\";\nimport { BeforeModelNode } from \"./nodes/BeforeModelNode.js\";\nimport { AfterModelNode } from \"./nodes/AfterModelNode.js\";\nimport { AfterAgentNode } from \"./nodes/AfterAgentNode.js\";\nimport {\n initializeMiddlewareStates,\n parseJumpToTarget,\n} from \"./nodes/utils.js\";\nimport { StateManager } from \"./state.js\";\n\nimport type {\n WithStateGraphNodes,\n AgentTypeConfig,\n CreateAgentParams,\n ToolsToMessageToolSet,\n} from \"./types.js\";\n\nimport type { BuiltInState, JumpTo, UserInput } from \"./types.js\";\nimport type { InvokeConfiguration, StreamConfiguration } from \"./runtime.js\";\nimport type {\n AgentMiddleware,\n InferMiddlewareContextInputs,\n InferMiddlewareStates,\n InferMiddlewareInputStates,\n InferContextInput,\n AnyAnnotationRoot,\n InferSchemaInput,\n ToAnnotationRoot,\n} from \"./middleware/types.js\";\nimport { type ResponseFormatUndefined } from \"./responses.js\";\nimport { getHookConstraint } from \"./middleware/utils.js\";\n\n/**\n * In the ReAct pattern we have three main nodes:\n * - model_request: The node that makes the model call.\n * - tools: The node that calls the tools.\n * - END: The end of the graph.\n *\n * These are the only nodes that can be jumped to from other nodes.\n */\ntype BaseGraphDestination =\n | typeof TOOLS_NODE_NAME\n | typeof AGENT_NODE_NAME\n | typeof END;\n\n// Helper type to get the state definition with middleware states\ntype MergedAgentState<Types extends AgentTypeConfig> = InferSchemaInput<\n Types[\"State\"]\n> &\n (Types[\"Response\"] extends ResponseFormatUndefined\n ? Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n >\n : Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n > & {\n structuredResponse: Types[\"Response\"];\n }) &\n InferMiddlewareStates<Types[\"Middleware\"]>;\n\ntype InvokeStateParameter<Types extends AgentTypeConfig> =\n | (UserInput<Types[\"State\"]> &\n InferMiddlewareInputStates<Types[\"Middleware\"]>)\n | Command<any, any, any>\n | null;\n\ntype AgentGraph<Types extends AgentTypeConfig> = CompiledStateGraph<\n any,\n any,\n any,\n any,\n MergedAgentState<Types>,\n ToAnnotationRoot<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n >[\"spec\"],\n unknown\n>;\n\n/**\n * ReactAgent is a production-ready ReAct (Reasoning + Acting) agent that combines\n * language models with tools and middleware.\n *\n * The agent is parameterized by a single type bag `Types` that encapsulates all\n * type information:\n *\n * @typeParam Types - An {@link AgentTypeConfig} that bundles:\n * - `Response`: The structured response type\n * - `State`: The custom state schema type\n * - `Context`: The context schema type\n * - `Middleware`: The middleware array type\n * - `Tools`: The combined tools type from agent and middleware\n *\n * @example\n * ```typescript\n * // Using the type bag pattern\n * type MyTypes = AgentTypeConfig<\n * { name: string }, // Response\n * typeof myState, // State\n * typeof myContext, // Context\n * typeof middleware, // Middleware\n * typeof tools // Tools\n * >;\n *\n * const agent: ReactAgent<MyTypes> = createAgent({ ... });\n * ```\n */\nexport class ReactAgent<\n Types extends AgentTypeConfig = AgentTypeConfig<\n Record<string, any>,\n undefined,\n AnyAnnotationRoot,\n readonly AgentMiddleware[],\n readonly (ClientTool | ServerTool)[]\n >,\n> {\n /**\n * Type marker for extracting the AgentTypeConfig from a ReactAgent instance.\n * This is a phantom property used only for type inference.\n * @internal\n */\n declare readonly \"~agentTypes\": Types;\n\n #graph: AgentGraph<Types>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\n\n #stateManager = new StateManager();\n\n constructor(\n public options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >\n ) {\n this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;\n\n /**\n * validate that model option is provided\n */\n if (!options.model) {\n throw new Error(\"`model` option is required to create an agent.\");\n }\n\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n if (typeof options.model !== \"string\") {\n validateLLMHasNoBoundTools(options.model);\n }\n\n /**\n * define complete list of tools based on options and middleware\n */\n const middlewareTools = (this.options.middleware\n ?.filter((m) => m.tools)\n .flatMap((m) => m.tools) ?? []) as (ClientTool | ServerTool)[];\n const toolClasses = [...(options.tools ?? []), ...middlewareTools];\n\n /**\n * If any of the tools are configured to return_directly after running,\n * our graph needs to check if these were called\n */\n const shouldReturnDirect = new Set(\n toolClasses\n .filter(isClientTool)\n .filter((tool) => \"returnDirect\" in tool && tool.returnDirect)\n .map((tool) => tool.name)\n );\n\n /**\n * Create a schema that merges agent base schema with middleware state schemas\n * Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata\n */\n const { state, input, output } = createAgentAnnotationConditional<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined,\n this.options.stateSchema as Types[\"State\"],\n this.options.middleware as Types[\"Middleware\"]\n );\n\n const workflow = new StateGraph(\n {\n state,\n input,\n output,\n },\n this.options.contextSchema\n );\n\n const allNodeWorkflows = workflow as WithStateGraphNodes<\n typeof TOOLS_NODE_NAME | typeof AGENT_NODE_NAME | string,\n typeof workflow\n >;\n\n // Generate node names for middleware nodes that have hooks\n const beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][] = [];\n\n this.#agentNode = new AgentNode({\n model: this.options.model,\n systemMessage: normalizeSystemPrompt(this.options.systemPrompt),\n includeAgentName: this.options.includeAgentName,\n name: this.options.name,\n responseFormat: this.options.responseFormat,\n middleware: this.options.middleware,\n toolClasses,\n shouldReturnDirect,\n signal: this.options.signal,\n wrapModelCallHookMiddleware,\n });\n\n const middlewareNames = new Set<string>();\n const middleware = this.options.middleware ?? [];\n for (let i = 0; i < middleware.length; i++) {\n let beforeAgentNode: BeforeAgentNode | undefined;\n let beforeModelNode: BeforeModelNode | undefined;\n let afterModelNode: AfterModelNode | undefined;\n let afterAgentNode: AfterAgentNode | undefined;\n const m = middleware[i];\n if (middlewareNames.has(m.name)) {\n throw new Error(`Middleware ${m.name} is defined multiple times`);\n }\n\n middlewareNames.add(m.name);\n if (m.beforeAgent) {\n beforeAgentNode = new BeforeAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeAgentNode);\n const name = `${m.name}.before_agent`;\n beforeAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeAgent),\n });\n allNodeWorkflows.addNode(\n name,\n beforeAgentNode,\n beforeAgentNode.nodeOptions\n );\n }\n if (m.beforeModel) {\n beforeModelNode = new BeforeModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeModelNode);\n const name = `${m.name}.before_model`;\n beforeModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeModel),\n });\n allNodeWorkflows.addNode(\n name,\n beforeModelNode,\n beforeModelNode.nodeOptions\n );\n }\n if (m.afterModel) {\n afterModelNode = new AfterModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterModelNode);\n const name = `${m.name}.after_model`;\n afterModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterModel),\n });\n allNodeWorkflows.addNode(\n name,\n afterModelNode,\n afterModelNode.nodeOptions\n );\n }\n if (m.afterAgent) {\n afterAgentNode = new AfterAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterAgentNode);\n const name = `${m.name}.after_agent`;\n afterAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterAgent),\n });\n allNodeWorkflows.addNode(\n name,\n afterAgentNode,\n afterAgentNode.nodeOptions\n );\n }\n\n if (m.wrapModelCall) {\n wrapModelCallHookMiddleware.push([\n m,\n () => this.#stateManager.getState(m.name),\n ]);\n }\n }\n\n /**\n * Add Nodes\n */\n allNodeWorkflows.addNode(AGENT_NODE_NAME, this.#agentNode);\n\n /**\n * add single tool node for all tools\n */\n if (toolClasses.filter(isClientTool).length > 0) {\n const toolNode = new ToolNode(toolClasses.filter(isClientTool), {\n signal: this.options.signal,\n wrapToolCall: wrapToolCall(middleware),\n });\n allNodeWorkflows.addNode(TOOLS_NODE_NAME, toolNode);\n }\n\n /**\n * Add Edges\n */\n // Determine the entry node (runs once at start): before_agent -> before_model -> model_request\n let entryNode: string;\n if (beforeAgentNodes.length > 0) {\n entryNode = beforeAgentNodes[0].name;\n } else if (beforeModelNodes.length > 0) {\n entryNode = beforeModelNodes[0].name;\n } else {\n entryNode = AGENT_NODE_NAME;\n }\n\n // Determine the loop entry node (beginning of agent loop, excludes before_agent)\n // This is where tools will loop back to for the next iteration\n const loopEntryNode =\n beforeModelNodes.length > 0 ? beforeModelNodes[0].name : AGENT_NODE_NAME;\n\n // Determine the exit node (runs once at end): after_agent or END\n const exitNode =\n afterAgentNodes.length > 0\n ? afterAgentNodes[afterAgentNodes.length - 1].name\n : END;\n\n allNodeWorkflows.addEdge(START, entryNode);\n const clientTools = toolClasses.filter(isClientTool);\n\n // Connect beforeAgent nodes (run once at start)\n for (let i = 0; i < beforeAgentNodes.length; i++) {\n const node = beforeAgentNodes[i];\n const current = node.name;\n const isLast = i === beforeAgentNodes.length - 1;\n const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const hasTools = clientTools.length > 0;\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasTools);\n // Replace END with exitNode (which could be an afterAgent node)\n const destinations = Array.from(\n new Set([\n nextDefault,\n ...allowedMapped.map((dest) => (dest === END ? exitNode : dest)),\n ])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeAgentRouter(clientTools, nextDefault, exitNode),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect beforeModel nodes; add conditional routing ONLY if allowed jumps are specified\n for (let i = 0; i < beforeModelNodes.length; i++) {\n const node = beforeModelNodes[i];\n const current = node.name;\n const isLast = i === beforeModelNodes.length - 1;\n const nextDefault = isLast\n ? AGENT_NODE_NAME\n : beforeModelNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const hasTools = clientTools.length > 0;\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasTools);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeModelRouter(clientTools, nextDefault),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect agent to last afterModel node (for reverse order execution)\n const lastAfterModelNode = afterModelNodes.at(-1);\n if (afterModelNodes.length > 0 && lastAfterModelNode) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, lastAfterModelNode.name);\n } else {\n // If no afterModel nodes, connect model_request directly to model paths\n const modelPaths = this.#getModelPaths(clientTools);\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n if (destinations.length === 1) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, destinations[0]);\n } else {\n allNodeWorkflows.addConditionalEdges(\n AGENT_NODE_NAME,\n this.#createModelRouter(exitNode),\n destinations\n );\n }\n }\n\n // Connect afterModel nodes in reverse sequence; add conditional routing ONLY if allowed jumps are specified per node\n for (let i = afterModelNodes.length - 1; i > 0; i--) {\n const node = afterModelNodes[i];\n const current = node.name;\n const nextDefault = afterModelNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const hasTools = clientTools.length > 0;\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasTools);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect first afterModel node (last to execute) to model paths with jumpTo support\n if (afterModelNodes.length > 0) {\n const firstAfterModel = afterModelNodes[0];\n const firstAfterModelNode = firstAfterModel.name;\n\n // Include exitNode in the paths since afterModel should be able to route to after_agent or END\n const modelPaths = this.#getModelPaths(clientTools, true).filter(\n (p) =>\n p !== TOOLS_NODE_NAME || toolClasses.filter(isClientTool).length > 0\n );\n\n const allowJump = Boolean(\n firstAfterModel.allowed && firstAfterModel.allowed.length > 0\n );\n\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterModelNode,\n this.#createAfterModelRouter(clientTools, allowJump, exitNode),\n destinations\n );\n }\n\n // Connect afterAgent nodes (run once at end, in reverse order like afterModel)\n for (let i = afterAgentNodes.length - 1; i > 0; i--) {\n const node = afterAgentNodes[i];\n const current = node.name;\n const nextDefault = afterAgentNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const hasTools = clientTools.length > 0;\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasTools);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect the first afterAgent node (last to execute) to END\n if (afterAgentNodes.length > 0) {\n const firstAfterAgent = afterAgentNodes[0];\n const firstAfterAgentNode = firstAfterAgent.name;\n\n if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {\n const hasTools = clientTools.length > 0;\n const allowedMapped = firstAfterAgent.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasTools);\n\n /**\n * For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)\n * The default destination (when no jump occurs) should be END\n */\n const destinations = Array.from(\n new Set([END, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterAgentNode,\n this.#createAfterModelSequenceRouter(\n clientTools,\n firstAfterAgent.allowed,\n END as string\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(firstAfterAgentNode, END);\n }\n }\n\n /**\n * add edges for tools node\n */\n if (clientTools.length > 0) {\n // Tools should return to loop entry node (not including before_agent)\n const toolReturnTarget = loopEntryNode;\n\n if (shouldReturnDirect.size > 0) {\n allNodeWorkflows.addConditionalEdges(\n TOOLS_NODE_NAME,\n this.#createToolsRouter(shouldReturnDirect, exitNode),\n [toolReturnTarget, exitNode as string]\n );\n } else {\n allNodeWorkflows.addEdge(TOOLS_NODE_NAME, toolReturnTarget);\n }\n }\n\n /**\n * compile the graph\n */\n this.#graph = allNodeWorkflows.compile({\n checkpointer: this.options.checkpointer,\n store: this.options.store,\n name: this.options.name,\n description: this.options.description,\n }) as unknown as AgentGraph<Types>;\n }\n\n /**\n * Get the compiled {@link https://docs.langchain.com/oss/javascript/langgraph/use-graph-api | StateGraph}.\n */\n get graph(): AgentGraph<Types> {\n return this.#graph;\n }\n\n /**\n * Get possible edge destinations from model node.\n * @param toolClasses names of tools to call\n * @param includeModelRequest whether to include \"model_request\" as a valid path (for jumpTo routing)\n * @returns list of possible edge destinations\n */\n #getModelPaths(\n toolClasses: (ClientTool | ServerTool)[],\n includeModelRequest: boolean = false\n ): BaseGraphDestination[] {\n const paths: BaseGraphDestination[] = [];\n if (toolClasses.length > 0) {\n paths.push(TOOLS_NODE_NAME);\n }\n\n if (includeModelRequest) {\n paths.push(AGENT_NODE_NAME);\n }\n\n paths.push(END);\n\n return paths;\n }\n\n /**\n * Create routing function for tools node conditional edges.\n */\n #createToolsRouter(\n shouldReturnDirect: Set<string>,\n exitNode: string | typeof END\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages[messages.length - 1];\n\n // Check if we just executed a returnDirect tool\n if (\n ToolMessage.isInstance(lastMessage) &&\n lastMessage.name &&\n shouldReturnDirect.has(lastMessage.name)\n ) {\n // If we have a response format, route to agent to generate structured response\n // Otherwise, return directly to exit node (could be after_agent or END)\n return this.options.responseFormat ? AGENT_NODE_NAME : exitNode;\n }\n\n // For non-returnDirect tools, always route back to agent\n return AGENT_NODE_NAME;\n };\n }\n\n /**\n * Create routing function for model node conditional edges.\n * @param exitNode - The exit node to route to (could be after_agent or END)\n */\n #createModelRouter(exitNode: string | typeof END = END) {\n /**\n * determine if the agent should continue or not\n */\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls) {\n // If all tool calls are for structured response extraction, go to exit node\n // The AgentNode will handle these internally and return the structured response\n return exitNode;\n }\n\n /**\n * The tool node processes a single message.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n /**\n * Route to tools node (filter out any structured response tool calls)\n */\n const regularToolCalls = lastMessage.tool_calls.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after afterModel hooks.\n *\n * This router checks if the `jumpTo` property is set in the state after afterModel middleware\n * execution. If set, it routes to the specified target (\"model_request\" or \"tools\").\n * If not set, it falls back to the normal model routing logic for afterModel context.\n *\n * The jumpTo property is automatically cleared after use to prevent infinite loops.\n *\n * @param toolClasses - Available tool classes for validation\n * @param allowJump - Whether jumping is allowed\n * @param exitNode - The exit node to route to (could be after_agent or END)\n * @returns Router function that handles jumpTo logic and normal routing\n */\n #createAfterModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowJump: boolean,\n exitNode: string | typeof END\n ) {\n const hasStructuredResponse = Boolean(this.options.responseFormat);\n\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as Omit<BuiltInState, \"jumpTo\"> & {\n jumpTo?: JumpTo;\n };\n // First, check if we just processed a structured response\n // If so, ignore any existing jumpTo and go to exitNode\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n if (\n AIMessage.isInstance(lastMessage) &&\n (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)\n ) {\n return exitNode;\n }\n\n // Check if jumpTo is set in the state and allowed\n if (allowJump && builtInState.jumpTo) {\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n // If trying to jump to tools but no tools are available, go to exitNode\n if (toolClasses.length === 0) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n // destination === \"model_request\"\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n\n // check if there are pending tool calls\n const toolMessages = messages.filter(ToolMessage.isInstance);\n const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);\n const pendingToolCalls = lastAiMessage?.tool_calls?.filter(\n (call) => !toolMessages.some((m) => m.tool_call_id === call.id)\n );\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n return pendingToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n }\n\n // if we exhausted all tool calls, but still have no structured response tool calls,\n // go back to model_request\n const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (\n pendingToolCalls &&\n pendingToolCalls.length === 0 &&\n !hasStructuredResponseCalls &&\n hasStructuredResponse\n ) {\n return AGENT_NODE_NAME;\n }\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n // Check if there are any regular tool calls (non-structured response)\n const hasRegularToolCalls = lastMessage.tool_calls.some(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) {\n return exitNode;\n }\n\n /**\n * For routing from afterModel nodes, always use simple string paths\n * The Send API is handled at the model_request node level\n */\n return TOOLS_NODE_NAME;\n };\n }\n\n /**\n * Router for afterModel sequence nodes (connecting later middlewares to earlier ones),\n * honoring allowed jump targets and defaulting to the next node.\n */\n #createAfterModelSequenceRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowed: string[],\n nextDefault: string\n ) {\n const allowedSet = new Set(allowed.map((t) => parseJumpToTarget(t)));\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (builtInState.jumpTo) {\n const dest = parseJumpToTarget(builtInState.jumpTo);\n if (dest === END && allowedSet.has(END)) {\n return END;\n }\n if (dest === TOOLS_NODE_NAME && allowedSet.has(TOOLS_NODE_NAME)) {\n if (toolClasses.length === 0) return END;\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n if (dest === AGENT_NODE_NAME && allowedSet.has(AGENT_NODE_NAME)) {\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n }\n return nextDefault;\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeAgent hooks.\n * Falls back to the default next node if no jumpTo is present.\n * When jumping to END, routes to exitNode (which could be an afterAgent node).\n */\n #createBeforeAgentRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n exitNode: string | typeof END\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n /**\n * When beforeAgent jumps to END, route to exitNode (first afterAgent node)\n */\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (toolClasses.length === 0) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeModel hooks.\n * Falls back to the default next node if no jumpTo is present.\n */\n #createBeforeModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return END;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (toolClasses.length === 0) {\n return END;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Initialize middleware states if not already present in the input state.\n */\n async #initializeMiddlewareStates(\n state: InvokeStateParameter<Types>,\n config: RunnableConfig\n ): Promise<InvokeStateParameter<Types>> {\n if (\n !this.options.middleware ||\n this.options.middleware.length === 0 ||\n state instanceof Command ||\n !state\n ) {\n return state;\n }\n\n const defaultStates = await initializeMiddlewareStates(\n this.options.middleware,\n state\n );\n const threadState = await this.#graph\n .getState(config)\n .catch(() => ({ values: {} }));\n const updatedState = {\n ...threadState.values,\n ...state,\n } as InvokeStateParameter<Types>;\n if (!updatedState) {\n return updatedState;\n }\n\n // Only add defaults for keys that don't exist in current state\n for (const [key, value] of Object.entries(defaultStates)) {\n if (!(key in updatedState)) {\n updatedState[key as keyof typeof updatedState] = value;\n }\n }\n\n return updatedState;\n }\n\n /**\n * Executes the agent with the given state and returns the final state after all processing.\n *\n * This method runs the agent's entire workflow synchronously, including:\n * - Processing the input messages through any configured middleware\n * - Calling the language model to generate responses\n * - Executing any tool calls made by the model\n * - Running all middleware hooks (beforeModel, afterModel, etc.)\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to the final agent state after execution completes.\n * The returned state includes:\n * - a `messages` property containing an array with all messages (input, AI responses, tool calls/results)\n * - a `structuredResponse` property containing the structured response (if configured)\n * - all state values defined in the middleware\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch],\n * responseFormat: z.object({\n * weather: z.string(),\n * }),\n * });\n *\n * const result = await agent.invoke({\n * messages: [{ role: \"human\", content: \"What's the weather in Paris?\" }]\n * });\n *\n * console.log(result.structuredResponse.weather); // outputs: \"It's sunny and 75°F.\"\n * ```\n */\n async invoke(\n state: InvokeStateParameter<Types>,\n config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >\n ) {\n type FullState = MergedAgentState<Types>;\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n config as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n config as unknown as InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n ) as Promise<FullState>;\n }\n\n /**\n * Executes the agent with streaming, returning an async iterable of state updates as they occur.\n *\n * This method runs the agent's workflow similar to `invoke`, but instead of waiting for\n * completion, it streams high-level state updates in real-time. This allows you to:\n * - Display intermediate results to users as they're generated\n * - Monitor the agent's progress through each step\n * - React to state changes as nodes complete\n *\n * For more granular event-level streaming (like individual LLM tokens), use `streamEvents` instead.\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.streamMode - The streaming mode for the agent execution, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/streaming#supported-stream-modes | Supported stream modes}.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to an IterableReadableStream of state updates.\n * Each update contains the current state after a node completes.\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch]\n * });\n *\n * const stream = await agent.stream({\n * messages: [{ role: \"human\", content: \"What's 2+2 and the weather in NYC?\" }]\n * });\n *\n * for await (const chunk of stream) {\n * console.log(chunk); // State update from each node\n * }\n * ```\n */\n async stream<\n TStreamMode extends StreamMode | StreamMode[] | undefined,\n TEncoding extends \"text/event-stream\" | undefined,\n >(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TEncoding\n >\n ) {\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n config as RunnableConfig\n );\n return this.#graph.stream(\n initializedState,\n config as Record<string, any>\n ) as Promise<\n IterableReadableStream<\n StreamOutputMap<\n TStreamMode,\n false,\n MergedAgentState<Types>,\n MergedAgentState<Types>,\n string,\n unknown,\n unknown,\n TEncoding\n >\n >\n >;\n }\n\n /**\n * Visualize the graph as a PNG image.\n * @param params - Parameters for the drawMermaidPng method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns PNG image as a buffer\n */\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n const image = await representation.drawMermaidPng(params);\n const arrayBuffer = await image.arrayBuffer();\n const buffer = new Uint8Array(arrayBuffer);\n return buffer;\n }\n\n /**\n * Draw the graph as a Mermaid string.\n * @param params - Parameters for the drawMermaid method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns Mermaid string\n */\n async drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n return representation.drawMermaid(params);\n }\n\n /**\n * The following are internal methods to enable support for LangGraph Platform.\n * They are not part of the createAgent public API.\n *\n * Note: we intentionally return as `never` to avoid type errors due to type inference.\n */\n\n /**\n * @internal\n */\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" },\n streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent> {\n return this.#graph.streamEvents(\n state,\n {\n ...(config as Partial<\n PregelOptions<\n any,\n any,\n any,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\"\n >\n >),\n version: config?.version ?? \"v2\",\n },\n streamOptions\n );\n }\n /**\n * @internal\n */\n getGraphAsync(config?: RunnableConfig) {\n return this.#graph.getGraphAsync(config) as never;\n }\n /**\n * @internal\n */\n getState(config: RunnableConfig, options?: GetStateOptions) {\n return this.#graph.getState(config, options) as never;\n }\n /**\n * @internal\n */\n getStateHistory(config: RunnableConfig, options?: CheckpointListOptions) {\n return this.#graph.getStateHistory(config, options) as never;\n }\n /**\n * @internal\n */\n getSubgraphs(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphs(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n getSubgraphAsync(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphsAsync(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n updateState(\n inputConfig: LangGraphRunnableConfig,\n values: Record<string, unknown> | unknown,\n asNode?: string\n ) {\n return this.#graph.updateState(inputConfig, values, asNode) as never;\n }\n\n /**\n * @internal\n */\n get builder() {\n return this.#graph.builder;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ReactAgent.cjs","names":["StateManager","options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >","#toolBehaviorVersion","validateLLMHasNoBoundTools","isClientTool","createAgentState","StateGraph","beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[]","wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][]","#agentNode","AgentNode","normalizeSystemPrompt","beforeAgentNode: BeforeAgentNode | undefined","beforeModelNode: BeforeModelNode | undefined","afterModelNode: AfterModelNode | undefined","afterAgentNode: AfterAgentNode | undefined","BeforeAgentNode","#stateManager","getHookConstraint","BeforeModelNode","AfterModelNode","AfterAgentNode","AGENT_NODE_NAME","ToolNode","wrapToolCall","TOOLS_NODE_NAME","entryNode: string","END","START","parseJumpToTarget","#createBeforeAgentRouter","#createBeforeModelRouter","#getModelPaths","#createModelRouter","#createAfterModelSequenceRouter","#createAfterModelRouter","#createToolsRouter","#graph","toolClasses: (ClientTool | ServerTool)[]","includeModelRequest: boolean","hasToolsAvailable: boolean","paths: BaseGraphDestination[]","shouldReturnDirect: Set<string>","exitNode: string | typeof END","state: Record<string, unknown>","ToolMessage","AIMessage","Send","allowJump: boolean","allowed: string[]","nextDefault: string","#initializeMiddlewareStates","state: InvokeStateParameter<Types>","config: RunnableConfig","Command","initializeMiddlewareStates","config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >","config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TEncoding\n >","params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }","config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" }","streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]","config?: RunnableConfig","options?: GetStateOptions","options?: CheckpointListOptions","namespace?: string","recurse?: boolean","inputConfig: LangGraphRunnableConfig","values: Record<string, unknown> | unknown","asNode?: string"],"sources":["../../src/agents/ReactAgent.ts"],"sourcesContent":["/* eslint-disable no-instanceof/no-instanceof */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { InteropZodObject } from \"@langchain/core/utils/types\";\n\nimport {\n StateGraph,\n END,\n START,\n Send,\n Command,\n CompiledStateGraph,\n type GetStateOptions,\n type LangGraphRunnableConfig,\n type StreamMode,\n type StreamOutputMap,\n type PregelOptions,\n} from \"@langchain/langgraph\";\nimport type { CheckpointListOptions } from \"@langchain/langgraph-checkpoint\";\nimport {\n ToolMessage,\n AIMessage,\n MessageStructure,\n} from \"@langchain/core/messages\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport type { Runnable, RunnableConfig } from \"@langchain/core/runnables\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { createAgentState } from \"./annotation.js\";\nimport {\n isClientTool,\n validateLLMHasNoBoundTools,\n wrapToolCall,\n normalizeSystemPrompt,\n} from \"./utils.js\";\n\nimport { AgentNode, AGENT_NODE_NAME } from \"./nodes/AgentNode.js\";\nimport { ToolNode, TOOLS_NODE_NAME } from \"./nodes/ToolNode.js\";\nimport { BeforeAgentNode } from \"./nodes/BeforeAgentNode.js\";\nimport { BeforeModelNode } from \"./nodes/BeforeModelNode.js\";\nimport { AfterModelNode } from \"./nodes/AfterModelNode.js\";\nimport { AfterAgentNode } from \"./nodes/AfterAgentNode.js\";\nimport {\n initializeMiddlewareStates,\n parseJumpToTarget,\n} from \"./nodes/utils.js\";\nimport { StateManager } from \"./state.js\";\n\nimport type {\n WithStateGraphNodes,\n AgentTypeConfig,\n CreateAgentParams,\n ToolsToMessageToolSet,\n} from \"./types.js\";\n\nimport type { BuiltInState, JumpTo, UserInput } from \"./types.js\";\nimport type { InvokeConfiguration, StreamConfiguration } from \"./runtime.js\";\nimport type {\n AgentMiddleware,\n InferMiddlewareContextInputs,\n InferMiddlewareStates,\n InferMiddlewareInputStates,\n InferContextInput,\n AnyAnnotationRoot,\n InferSchemaInput,\n ToAnnotationRoot,\n} from \"./middleware/types.js\";\nimport { type ResponseFormatUndefined } from \"./responses.js\";\nimport { getHookConstraint } from \"./middleware/utils.js\";\n\n/**\n * In the ReAct pattern we have three main nodes:\n * - model_request: The node that makes the model call.\n * - tools: The node that calls the tools.\n * - END: The end of the graph.\n *\n * These are the only nodes that can be jumped to from other nodes.\n */\ntype BaseGraphDestination =\n | typeof TOOLS_NODE_NAME\n | typeof AGENT_NODE_NAME\n | typeof END;\n\n// Helper type to get the state definition with middleware states\ntype MergedAgentState<Types extends AgentTypeConfig> = InferSchemaInput<\n Types[\"State\"]\n> &\n (Types[\"Response\"] extends ResponseFormatUndefined\n ? Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n >\n : Omit<\n BuiltInState<MessageStructure<ToolsToMessageToolSet<Types[\"Tools\"]>>>,\n \"jumpTo\"\n > & {\n structuredResponse: Types[\"Response\"];\n }) &\n InferMiddlewareStates<Types[\"Middleware\"]>;\n\ntype InvokeStateParameter<Types extends AgentTypeConfig> =\n | (UserInput<Types[\"State\"]> &\n InferMiddlewareInputStates<Types[\"Middleware\"]>)\n | Command<any, any, any>\n | null;\n\ntype AgentGraph<Types extends AgentTypeConfig> = CompiledStateGraph<\n any,\n any,\n any,\n any,\n MergedAgentState<Types>,\n ToAnnotationRoot<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n >[\"spec\"],\n unknown\n>;\n\n/**\n * ReactAgent is a production-ready ReAct (Reasoning + Acting) agent that combines\n * language models with tools and middleware.\n *\n * The agent is parameterized by a single type bag `Types` that encapsulates all\n * type information:\n *\n * @typeParam Types - An {@link AgentTypeConfig} that bundles:\n * - `Response`: The structured response type\n * - `State`: The custom state schema type\n * - `Context`: The context schema type\n * - `Middleware`: The middleware array type\n * - `Tools`: The combined tools type from agent and middleware\n *\n * @example\n * ```typescript\n * // Using the type bag pattern\n * type MyTypes = AgentTypeConfig<\n * { name: string }, // Response\n * typeof myState, // State\n * typeof myContext, // Context\n * typeof middleware, // Middleware\n * typeof tools // Tools\n * >;\n *\n * const agent: ReactAgent<MyTypes> = createAgent({ ... });\n * ```\n */\nexport class ReactAgent<\n Types extends AgentTypeConfig = AgentTypeConfig<\n Record<string, any>,\n undefined,\n AnyAnnotationRoot,\n readonly AgentMiddleware[],\n readonly (ClientTool | ServerTool)[]\n >,\n> {\n /**\n * Type marker for extracting the AgentTypeConfig from a ReactAgent instance.\n * This is a phantom property used only for type inference.\n * @internal\n */\n declare readonly \"~agentTypes\": Types;\n\n #graph: AgentGraph<Types>;\n\n #toolBehaviorVersion: \"v1\" | \"v2\" = \"v2\";\n\n #agentNode: AgentNode<any, AnyAnnotationRoot>;\n\n #stateManager = new StateManager();\n\n constructor(\n public options: CreateAgentParams<\n Types[\"Response\"],\n Types[\"State\"],\n Types[\"Context\"]\n >\n ) {\n this.#toolBehaviorVersion = options.version ?? this.#toolBehaviorVersion;\n\n /**\n * validate that model option is provided\n */\n if (!options.model) {\n throw new Error(\"`model` option is required to create an agent.\");\n }\n\n /**\n * Check if the LLM already has bound tools and throw if it does.\n */\n if (typeof options.model !== \"string\") {\n validateLLMHasNoBoundTools(options.model);\n }\n\n /**\n * define complete list of tools based on options and middleware\n */\n const middlewareTools = (this.options.middleware\n ?.filter((m) => m.tools)\n .flatMap((m) => m.tools) ?? []) as (ClientTool | ServerTool)[];\n const toolClasses = [...(options.tools ?? []), ...middlewareTools];\n\n /**\n * If any of the tools are configured to return_directly after running,\n * our graph needs to check if these were called\n */\n const shouldReturnDirect = new Set(\n toolClasses\n .filter(isClientTool)\n .filter((tool) => \"returnDirect\" in tool && tool.returnDirect)\n .map((tool) => tool.name)\n );\n\n /**\n * Create a schema that merges agent base schema with middleware state schemas\n * Using Zod with withLangGraph ensures LangGraph Studio gets proper metadata\n */\n const { state, input, output } = createAgentState<\n Types[\"State\"],\n Types[\"Middleware\"]\n >(\n this.options.responseFormat !== undefined,\n this.options.stateSchema as Types[\"State\"],\n this.options.middleware as Types[\"Middleware\"]\n );\n\n const workflow = new StateGraph(state, {\n input,\n output,\n context: this.options.contextSchema,\n });\n\n const allNodeWorkflows = workflow as WithStateGraphNodes<\n typeof TOOLS_NODE_NAME | typeof AGENT_NODE_NAME | string,\n typeof workflow\n >;\n\n // Generate node names for middleware nodes that have hooks\n const beforeAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const beforeModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterModelNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const afterAgentNodes: {\n index: number;\n name: string;\n allowed?: string[];\n }[] = [];\n const wrapModelCallHookMiddleware: [\n AgentMiddleware,\n /**\n * ToDo: better type to get the state of middleware\n */\n () => any,\n ][] = [];\n\n this.#agentNode = new AgentNode({\n model: this.options.model,\n systemMessage: normalizeSystemPrompt(this.options.systemPrompt),\n includeAgentName: this.options.includeAgentName,\n name: this.options.name,\n responseFormat: this.options.responseFormat,\n middleware: this.options.middleware,\n toolClasses,\n shouldReturnDirect,\n signal: this.options.signal,\n wrapModelCallHookMiddleware,\n });\n\n const middlewareNames = new Set<string>();\n const middleware = this.options.middleware ?? [];\n for (let i = 0; i < middleware.length; i++) {\n let beforeAgentNode: BeforeAgentNode | undefined;\n let beforeModelNode: BeforeModelNode | undefined;\n let afterModelNode: AfterModelNode | undefined;\n let afterAgentNode: AfterAgentNode | undefined;\n const m = middleware[i];\n if (middlewareNames.has(m.name)) {\n throw new Error(`Middleware ${m.name} is defined multiple times`);\n }\n\n middlewareNames.add(m.name);\n if (m.beforeAgent) {\n beforeAgentNode = new BeforeAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeAgentNode);\n const name = `${m.name}.before_agent`;\n beforeAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeAgent),\n });\n allNodeWorkflows.addNode(\n name,\n beforeAgentNode,\n beforeAgentNode.nodeOptions\n );\n }\n if (m.beforeModel) {\n beforeModelNode = new BeforeModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, beforeModelNode);\n const name = `${m.name}.before_model`;\n beforeModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.beforeModel),\n });\n allNodeWorkflows.addNode(\n name,\n beforeModelNode,\n beforeModelNode.nodeOptions\n );\n }\n if (m.afterModel) {\n afterModelNode = new AfterModelNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterModelNode);\n const name = `${m.name}.after_model`;\n afterModelNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterModel),\n });\n allNodeWorkflows.addNode(\n name,\n afterModelNode,\n afterModelNode.nodeOptions\n );\n }\n if (m.afterAgent) {\n afterAgentNode = new AfterAgentNode(m, {\n getState: () => this.#stateManager.getState(m.name),\n });\n this.#stateManager.addNode(m, afterAgentNode);\n const name = `${m.name}.after_agent`;\n afterAgentNodes.push({\n index: i,\n name,\n allowed: getHookConstraint(m.afterAgent),\n });\n allNodeWorkflows.addNode(\n name,\n afterAgentNode,\n afterAgentNode.nodeOptions\n );\n }\n\n if (m.wrapModelCall) {\n wrapModelCallHookMiddleware.push([\n m,\n () => this.#stateManager.getState(m.name),\n ]);\n }\n }\n\n /**\n * Add Nodes\n */\n allNodeWorkflows.addNode(AGENT_NODE_NAME, this.#agentNode);\n\n /**\n * Check if any middleware has wrapToolCall defined.\n * If so, we need to create a ToolNode even without pre-registered tools\n * to allow middleware to handle dynamically registered tools.\n */\n const hasWrapToolCallMiddleware = middleware.some((m) => m.wrapToolCall);\n const clientTools = toolClasses.filter(isClientTool);\n\n /**\n * Create ToolNode if we have client-side tools OR if middleware defines wrapToolCall\n * (which may handle dynamically registered tools)\n */\n if (clientTools.length > 0 || hasWrapToolCallMiddleware) {\n const toolNode = new ToolNode(clientTools, {\n signal: this.options.signal,\n wrapToolCall: wrapToolCall(middleware),\n });\n allNodeWorkflows.addNode(TOOLS_NODE_NAME, toolNode);\n }\n\n /**\n * Add Edges\n */\n // Determine the entry node (runs once at start): before_agent -> before_model -> model_request\n let entryNode: string;\n if (beforeAgentNodes.length > 0) {\n entryNode = beforeAgentNodes[0].name;\n } else if (beforeModelNodes.length > 0) {\n entryNode = beforeModelNodes[0].name;\n } else {\n entryNode = AGENT_NODE_NAME;\n }\n\n // Determine the loop entry node (beginning of agent loop, excludes before_agent)\n // This is where tools will loop back to for the next iteration\n const loopEntryNode =\n beforeModelNodes.length > 0 ? beforeModelNodes[0].name : AGENT_NODE_NAME;\n\n // Determine the exit node (runs once at end): after_agent or END\n const exitNode =\n afterAgentNodes.length > 0\n ? afterAgentNodes[afterAgentNodes.length - 1].name\n : END;\n\n allNodeWorkflows.addEdge(START, entryNode);\n\n /**\n * Determine if we have tools available for routing.\n * This includes both registered client tools AND dynamic tools via middleware.\n */\n const hasToolsAvailable =\n clientTools.length > 0 || hasWrapToolCallMiddleware;\n\n // Connect beforeAgent nodes (run once at start)\n for (let i = 0; i < beforeAgentNodes.length; i++) {\n const node = beforeAgentNodes[i];\n const current = node.name;\n const isLast = i === beforeAgentNodes.length - 1;\n const nextDefault = isLast ? loopEntryNode : beforeAgentNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n // Replace END with exitNode (which could be an afterAgent node)\n const destinations = Array.from(\n new Set([\n nextDefault,\n ...allowedMapped.map((dest) => (dest === END ? exitNode : dest)),\n ])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeAgentRouter(\n clientTools,\n nextDefault,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect beforeModel nodes; add conditional routing ONLY if allowed jumps are specified\n for (let i = 0; i < beforeModelNodes.length; i++) {\n const node = beforeModelNodes[i];\n const current = node.name;\n const isLast = i === beforeModelNodes.length - 1;\n const nextDefault = isLast\n ? AGENT_NODE_NAME\n : beforeModelNodes[i + 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createBeforeModelRouter(\n clientTools,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect agent to last afterModel node (for reverse order execution)\n const lastAfterModelNode = afterModelNodes.at(-1);\n if (afterModelNodes.length > 0 && lastAfterModelNode) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, lastAfterModelNode.name);\n } else {\n // If no afterModel nodes, connect model_request directly to model paths\n const modelPaths = this.#getModelPaths(\n clientTools,\n false,\n hasToolsAvailable\n );\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n if (destinations.length === 1) {\n allNodeWorkflows.addEdge(AGENT_NODE_NAME, destinations[0]);\n } else {\n allNodeWorkflows.addConditionalEdges(\n AGENT_NODE_NAME,\n this.#createModelRouter(exitNode),\n destinations\n );\n }\n }\n\n // Connect afterModel nodes in reverse sequence; add conditional routing ONLY if allowed jumps are specified per node\n for (let i = afterModelNodes.length - 1; i > 0; i--) {\n const node = afterModelNodes[i];\n const current = node.name;\n const nextDefault = afterModelNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect first afterModel node (last to execute) to model paths with jumpTo support\n if (afterModelNodes.length > 0) {\n const firstAfterModel = afterModelNodes[0];\n const firstAfterModelNode = firstAfterModel.name;\n\n // Include exitNode in the paths since afterModel should be able to route to after_agent or END\n const modelPaths = this.#getModelPaths(\n clientTools,\n true,\n hasToolsAvailable\n ).filter((p) => p !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n const allowJump = Boolean(\n firstAfterModel.allowed && firstAfterModel.allowed.length > 0\n );\n\n // Replace END with exitNode in destinations, since exitNode might be an afterAgent node\n const destinations = modelPaths.map((p) =>\n p === END ? exitNode : p\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterModelNode,\n this.#createAfterModelRouter(\n clientTools,\n allowJump,\n exitNode,\n hasToolsAvailable\n ),\n destinations\n );\n }\n\n // Connect afterAgent nodes (run once at end, in reverse order like afterModel)\n for (let i = afterAgentNodes.length - 1; i > 0; i--) {\n const node = afterAgentNodes[i];\n const current = node.name;\n const nextDefault = afterAgentNodes[i - 1].name;\n\n if (node.allowed && node.allowed.length > 0) {\n const allowedMapped = node.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n const destinations = Array.from(\n new Set([nextDefault, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n current,\n this.#createAfterModelSequenceRouter(\n clientTools,\n node.allowed,\n nextDefault,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(current, nextDefault);\n }\n }\n\n // Connect the first afterAgent node (last to execute) to END\n if (afterAgentNodes.length > 0) {\n const firstAfterAgent = afterAgentNodes[0];\n const firstAfterAgentNode = firstAfterAgent.name;\n\n if (firstAfterAgent.allowed && firstAfterAgent.allowed.length > 0) {\n const allowedMapped = firstAfterAgent.allowed\n .map((t) => parseJumpToTarget(t))\n .filter((dest) => dest !== TOOLS_NODE_NAME || hasToolsAvailable);\n\n /**\n * For after_agent, only use explicitly allowed destinations (don't add loopEntryNode)\n * The default destination (when no jump occurs) should be END\n */\n const destinations = Array.from(\n new Set([END, ...allowedMapped])\n ) as BaseGraphDestination[];\n\n allNodeWorkflows.addConditionalEdges(\n firstAfterAgentNode,\n this.#createAfterModelSequenceRouter(\n clientTools,\n firstAfterAgent.allowed,\n END as string,\n hasToolsAvailable\n ),\n destinations\n );\n } else {\n allNodeWorkflows.addEdge(firstAfterAgentNode, END);\n }\n }\n\n /**\n * add edges for tools node (includes both registered tools and dynamic tools via middleware)\n */\n if (hasToolsAvailable) {\n // Tools should return to loop entry node (not including before_agent)\n const toolReturnTarget = loopEntryNode;\n\n if (shouldReturnDirect.size > 0) {\n allNodeWorkflows.addConditionalEdges(\n TOOLS_NODE_NAME,\n this.#createToolsRouter(shouldReturnDirect, exitNode),\n [toolReturnTarget, exitNode as string]\n );\n } else {\n allNodeWorkflows.addEdge(TOOLS_NODE_NAME, toolReturnTarget);\n }\n }\n\n /**\n * compile the graph\n */\n this.#graph = allNodeWorkflows.compile({\n checkpointer: this.options.checkpointer,\n store: this.options.store,\n name: this.options.name,\n description: this.options.description,\n }) as unknown as AgentGraph<Types>;\n }\n\n /**\n * Get the compiled {@link https://docs.langchain.com/oss/javascript/langgraph/use-graph-api | StateGraph}.\n */\n get graph(): AgentGraph<Types> {\n return this.#graph;\n }\n\n /**\n * Get possible edge destinations from model node.\n * @param toolClasses names of tools to call\n * @param includeModelRequest whether to include \"model_request\" as a valid path (for jumpTo routing)\n * @param hasToolsAvailable whether tools are available (includes dynamic tools via middleware)\n * @returns list of possible edge destinations\n */\n #getModelPaths(\n toolClasses: (ClientTool | ServerTool)[],\n includeModelRequest: boolean = false,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ): BaseGraphDestination[] {\n const paths: BaseGraphDestination[] = [];\n if (hasToolsAvailable) {\n paths.push(TOOLS_NODE_NAME);\n }\n\n if (includeModelRequest) {\n paths.push(AGENT_NODE_NAME);\n }\n\n paths.push(END);\n\n return paths;\n }\n\n /**\n * Create routing function for tools node conditional edges.\n */\n #createToolsRouter(\n shouldReturnDirect: Set<string>,\n exitNode: string | typeof END\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages[messages.length - 1];\n\n // Check if we just executed a returnDirect tool\n if (\n ToolMessage.isInstance(lastMessage) &&\n lastMessage.name &&\n shouldReturnDirect.has(lastMessage.name)\n ) {\n // If we have a response format, route to agent to generate structured response\n // Otherwise, return directly to exit node (could be after_agent or END)\n return this.options.responseFormat ? AGENT_NODE_NAME : exitNode;\n }\n\n // For non-returnDirect tools, always route back to agent\n return AGENT_NODE_NAME;\n };\n }\n\n /**\n * Create routing function for model node conditional edges.\n * @param exitNode - The exit node to route to (could be after_agent or END)\n */\n #createModelRouter(exitNode: string | typeof END = END) {\n /**\n * determine if the agent should continue or not\n */\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls) {\n // If all tool calls are for structured response extraction, go to exit node\n // The AgentNode will handle these internally and return the structured response\n return exitNode;\n }\n\n /**\n * The tool node processes a single message.\n */\n if (this.#toolBehaviorVersion === \"v1\") {\n return TOOLS_NODE_NAME;\n }\n\n /**\n * Route to tools node (filter out any structured response tool calls)\n */\n const regularToolCalls = lastMessage.tool_calls.filter(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (regularToolCalls.length === 0) {\n return exitNode;\n }\n\n return regularToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after afterModel hooks.\n *\n * This router checks if the `jumpTo` property is set in the state after afterModel middleware\n * execution. If set, it routes to the specified target (\"model_request\" or \"tools\").\n * If not set, it falls back to the normal model routing logic for afterModel context.\n *\n * The jumpTo property is automatically cleared after use to prevent infinite loops.\n *\n * @param toolClasses - Available tool classes for validation\n * @param allowJump - Whether jumping is allowed\n * @param exitNode - The exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n * @returns Router function that handles jumpTo logic and normal routing\n */\n #createAfterModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowJump: boolean,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const hasStructuredResponse = Boolean(this.options.responseFormat);\n\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as Omit<BuiltInState, \"jumpTo\"> & {\n jumpTo?: JumpTo;\n };\n // First, check if we just processed a structured response\n // If so, ignore any existing jumpTo and go to exitNode\n const messages = builtInState.messages;\n const lastMessage = messages.at(-1);\n if (\n AIMessage.isInstance(lastMessage) &&\n (!lastMessage.tool_calls || lastMessage.tool_calls.length === 0)\n ) {\n return exitNode;\n }\n\n // Check if jumpTo is set in the state and allowed\n if (allowJump && builtInState.jumpTo) {\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n // If trying to jump to tools but no tools are available, go to exitNode\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n // destination === \"model_request\"\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n\n // check if there are pending tool calls\n const toolMessages = messages.filter(ToolMessage.isInstance);\n const lastAiMessage = messages.filter(AIMessage.isInstance).at(-1);\n const pendingToolCalls = lastAiMessage?.tool_calls?.filter(\n (call) => !toolMessages.some((m) => m.tool_call_id === call.id)\n );\n if (pendingToolCalls && pendingToolCalls.length > 0) {\n return pendingToolCalls.map(\n (toolCall) =>\n new Send(TOOLS_NODE_NAME, { ...state, lg_tool_call: toolCall })\n );\n }\n\n // if we exhausted all tool calls, but still have no structured response tool calls,\n // go back to model_request\n const hasStructuredResponseCalls = lastAiMessage?.tool_calls?.some(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n if (\n pendingToolCalls &&\n pendingToolCalls.length === 0 &&\n !hasStructuredResponseCalls &&\n hasStructuredResponse\n ) {\n return AGENT_NODE_NAME;\n }\n\n if (\n !AIMessage.isInstance(lastMessage) ||\n !lastMessage.tool_calls ||\n lastMessage.tool_calls.length === 0\n ) {\n return exitNode;\n }\n\n // Check if all tool calls are for structured response extraction\n const hasOnlyStructuredResponseCalls = lastMessage.tool_calls.every(\n (toolCall) => toolCall.name.startsWith(\"extract-\")\n );\n\n // Check if there are any regular tool calls (non-structured response)\n const hasRegularToolCalls = lastMessage.tool_calls.some(\n (toolCall) => !toolCall.name.startsWith(\"extract-\")\n );\n\n if (hasOnlyStructuredResponseCalls || !hasRegularToolCalls) {\n return exitNode;\n }\n\n /**\n * For routing from afterModel nodes, always use simple string paths\n * The Send API is handled at the model_request node level\n */\n return TOOLS_NODE_NAME;\n };\n }\n\n /**\n * Router for afterModel sequence nodes (connecting later middlewares to earlier ones),\n * honoring allowed jump targets and defaulting to the next node.\n * @param toolClasses - Available tool classes for validation\n * @param allowed - List of allowed jump targets\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createAfterModelSequenceRouter(\n toolClasses: (ClientTool | ServerTool)[],\n allowed: string[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n const allowedSet = new Set(allowed.map((t) => parseJumpToTarget(t)));\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (builtInState.jumpTo) {\n const dest = parseJumpToTarget(builtInState.jumpTo);\n if (dest === END && allowedSet.has(END)) {\n return END;\n }\n if (dest === TOOLS_NODE_NAME && allowedSet.has(TOOLS_NODE_NAME)) {\n if (!hasToolsAvailable) return END;\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n if (dest === AGENT_NODE_NAME && allowedSet.has(AGENT_NODE_NAME)) {\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n }\n }\n return nextDefault;\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeAgent hooks.\n * Falls back to the default next node if no jumpTo is present.\n * When jumping to END, routes to exitNode (which could be an afterAgent node).\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param exitNode - Exit node to route to (could be after_agent or END)\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeAgentRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n exitNode: string | typeof END,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n /**\n * When beforeAgent jumps to END, route to exitNode (first afterAgent node)\n */\n return exitNode;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return exitNode;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Create routing function for jumpTo functionality after beforeModel hooks.\n * Falls back to the default next node if no jumpTo is present.\n * @param toolClasses - Available tool classes for validation\n * @param nextDefault - Default node to route to\n * @param hasToolsAvailable - Whether tools are available (includes dynamic tools via middleware)\n */\n #createBeforeModelRouter(\n toolClasses: (ClientTool | ServerTool)[],\n nextDefault: string,\n hasToolsAvailable: boolean = toolClasses.length > 0\n ) {\n return (state: Record<string, unknown>) => {\n const builtInState = state as unknown as BuiltInState;\n if (!builtInState.jumpTo) {\n return nextDefault;\n }\n const destination = parseJumpToTarget(builtInState.jumpTo);\n if (destination === END) {\n return END;\n }\n if (destination === TOOLS_NODE_NAME) {\n if (!hasToolsAvailable) {\n return END;\n }\n return new Send(TOOLS_NODE_NAME, { ...state, jumpTo: undefined });\n }\n return new Send(AGENT_NODE_NAME, { ...state, jumpTo: undefined });\n };\n }\n\n /**\n * Initialize middleware states if not already present in the input state.\n */\n async #initializeMiddlewareStates(\n state: InvokeStateParameter<Types>,\n config: RunnableConfig\n ): Promise<InvokeStateParameter<Types>> {\n if (\n !this.options.middleware ||\n this.options.middleware.length === 0 ||\n state instanceof Command ||\n !state\n ) {\n return state;\n }\n\n const defaultStates = await initializeMiddlewareStates(\n this.options.middleware,\n state\n );\n const threadState = await this.#graph\n .getState(config)\n .catch(() => ({ values: {} }));\n const updatedState = {\n ...threadState.values,\n ...state,\n } as InvokeStateParameter<Types>;\n if (!updatedState) {\n return updatedState;\n }\n\n // Only add defaults for keys that don't exist in current state\n for (const [key, value] of Object.entries(defaultStates)) {\n if (!(key in updatedState)) {\n updatedState[key as keyof typeof updatedState] = value;\n }\n }\n\n return updatedState;\n }\n\n /**\n * Executes the agent with the given state and returns the final state after all processing.\n *\n * This method runs the agent's entire workflow synchronously, including:\n * - Processing the input messages through any configured middleware\n * - Calling the language model to generate responses\n * - Executing any tool calls made by the model\n * - Running all middleware hooks (beforeModel, afterModel, etc.)\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to the final agent state after execution completes.\n * The returned state includes:\n * - a `messages` property containing an array with all messages (input, AI responses, tool calls/results)\n * - a `structuredResponse` property containing the structured response (if configured)\n * - all state values defined in the middleware\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch],\n * responseFormat: z.object({\n * weather: z.string(),\n * }),\n * });\n *\n * const result = await agent.invoke({\n * messages: [{ role: \"human\", content: \"What's the weather in Paris?\" }]\n * });\n *\n * console.log(result.structuredResponse.weather); // outputs: \"It's sunny and 75°F.\"\n * ```\n */\n async invoke(\n state: InvokeStateParameter<Types>,\n config?: InvokeConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n >\n ) {\n type FullState = MergedAgentState<Types>;\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n config as RunnableConfig\n );\n\n return this.#graph.invoke(\n initializedState,\n config as unknown as InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>\n ) as Promise<FullState>;\n }\n\n /**\n * Executes the agent with streaming, returning an async iterable of state updates as they occur.\n *\n * This method runs the agent's workflow similar to `invoke`, but instead of waiting for\n * completion, it streams high-level state updates in real-time. This allows you to:\n * - Display intermediate results to users as they're generated\n * - Monitor the agent's progress through each step\n * - React to state changes as nodes complete\n *\n * For more granular event-level streaming (like individual LLM tokens), use `streamEvents` instead.\n *\n * @param state - The initial state for the agent execution. Can be:\n * - An object containing `messages` array and any middleware-specific state properties\n * - A Command object for more advanced control flow\n *\n * @param config - Optional runtime configuration including:\n * @param config.context - The context for the agent execution.\n * @param config.configurable - LangGraph configuration options like `thread_id`, `run_id`, etc.\n * @param config.store - The store for the agent execution for persisting state, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/memory#memory-storage | Memory storage}.\n * @param config.signal - An optional {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} for the agent execution.\n * @param config.streamMode - The streaming mode for the agent execution, see more in {@link https://docs.langchain.com/oss/javascript/langgraph/streaming#supported-stream-modes | Supported stream modes}.\n * @param config.recursionLimit - The recursion limit for the agent execution.\n *\n * @returns A Promise that resolves to an IterableReadableStream of state updates.\n * Each update contains the current state after a node completes.\n *\n * @example\n * ```typescript\n * const agent = new ReactAgent({\n * llm: myModel,\n * tools: [calculator, webSearch]\n * });\n *\n * const stream = await agent.stream({\n * messages: [{ role: \"human\", content: \"What's 2+2 and the weather in NYC?\" }]\n * });\n *\n * for await (const chunk of stream) {\n * console.log(chunk); // State update from each node\n * }\n * ```\n */\n async stream<\n TStreamMode extends StreamMode | StreamMode[] | undefined,\n TEncoding extends \"text/event-stream\" | undefined,\n >(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n TStreamMode,\n TEncoding\n >\n ) {\n const initializedState = await this.#initializeMiddlewareStates(\n state,\n config as RunnableConfig\n );\n return this.#graph.stream(\n initializedState,\n config as Record<string, any>\n ) as Promise<\n IterableReadableStream<\n StreamOutputMap<\n TStreamMode,\n false,\n MergedAgentState<Types>,\n MergedAgentState<Types>,\n string,\n unknown,\n unknown,\n TEncoding\n >\n >\n >;\n }\n\n /**\n * Visualize the graph as a PNG image.\n * @param params - Parameters for the drawMermaidPng method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns PNG image as a buffer\n */\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n const image = await representation.drawMermaidPng(params);\n const arrayBuffer = await image.arrayBuffer();\n const buffer = new Uint8Array(arrayBuffer);\n return buffer;\n }\n\n /**\n * Draw the graph as a Mermaid string.\n * @param params - Parameters for the drawMermaid method.\n * @param params.withStyles - Whether to include styles in the graph.\n * @param params.curveStyle - The style of the graph's curves.\n * @param params.nodeColors - The colors of the graph's nodes.\n * @param params.wrapLabelNWords - The maximum number of words to wrap in a node's label.\n * @param params.backgroundColor - The background color of the graph.\n * @returns Mermaid string\n */\n async drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }) {\n const representation = await this.#graph.getGraphAsync();\n return representation.drawMermaid(params);\n }\n\n /**\n * The following are internal methods to enable support for LangGraph Platform.\n * They are not part of the createAgent public API.\n *\n * Note: we intentionally return as `never` to avoid type errors due to type inference.\n */\n\n /**\n * @internal\n */\n streamEvents(\n state: InvokeStateParameter<Types>,\n config?: StreamConfiguration<\n InferContextInput<\n Types[\"Context\"] extends AnyAnnotationRoot | InteropZodObject\n ? Types[\"Context\"]\n : AnyAnnotationRoot\n > &\n InferMiddlewareContextInputs<Types[\"Middleware\"]>,\n StreamMode | StreamMode[] | undefined,\n \"text/event-stream\" | undefined\n > & { version?: \"v1\" | \"v2\" },\n streamOptions?: Parameters<Runnable[\"streamEvents\"]>[2]\n ): IterableReadableStream<StreamEvent> {\n return this.#graph.streamEvents(\n state,\n {\n ...(config as Partial<\n PregelOptions<\n any,\n any,\n any,\n StreamMode | StreamMode[] | undefined,\n boolean,\n \"text/event-stream\"\n >\n >),\n version: config?.version ?? \"v2\",\n },\n streamOptions\n );\n }\n /**\n * @internal\n */\n getGraphAsync(config?: RunnableConfig) {\n return this.#graph.getGraphAsync(config) as never;\n }\n /**\n * @internal\n */\n getState(config: RunnableConfig, options?: GetStateOptions) {\n return this.#graph.getState(config, options) as never;\n }\n /**\n * @internal\n */\n getStateHistory(config: RunnableConfig, options?: CheckpointListOptions) {\n return this.#graph.getStateHistory(config, options) as never;\n }\n /**\n * @internal\n */\n getSubgraphs(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphs(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n getSubgraphAsync(namespace?: string, recurse?: boolean) {\n return this.#graph.getSubgraphsAsync(namespace, recurse) as never;\n }\n /**\n * @internal\n */\n updateState(\n inputConfig: LangGraphRunnableConfig,\n values: Record<string, unknown> | unknown,\n asNode?: string\n ) {\n return this.#graph.updateState(inputConfig, values, asNode) as never;\n }\n\n /**\n * @internal\n */\n get builder() {\n return this.#graph.builder;\n }\n}\n"],"mappings":"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"}
|