langchain 1.5.3 → 1.5.5
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 +12 -0
- package/dist/agents/ReactAgent.cjs +6 -6
- package/dist/agents/ReactAgent.cjs.map +1 -1
- package/dist/agents/ReactAgent.d.cts +1 -1
- package/dist/agents/ReactAgent.d.cts.map +1 -1
- package/dist/agents/ReactAgent.d.ts +1 -1
- package/dist/agents/ReactAgent.d.ts.map +1 -1
- package/dist/agents/ReactAgent.js +6 -5
- package/dist/agents/ReactAgent.js.map +1 -1
- package/dist/agents/RunnableCallable.cjs +0 -1
- package/dist/agents/RunnableCallable.cjs.map +1 -1
- package/dist/agents/RunnableCallable.js.map +1 -1
- package/dist/agents/annotation.cjs +0 -1
- package/dist/agents/annotation.cjs.map +1 -1
- package/dist/agents/annotation.js.map +1 -1
- package/dist/agents/constants.d.cts +1 -1
- package/dist/agents/constants.d.cts.map +1 -1
- package/dist/agents/constants.d.ts +1 -1
- package/dist/agents/constants.d.ts.map +1 -1
- package/dist/agents/errors.cjs +0 -1
- package/dist/agents/errors.cjs.map +1 -1
- package/dist/agents/errors.d.cts +0 -1
- package/dist/agents/errors.d.cts.map +1 -1
- package/dist/agents/errors.d.ts +0 -1
- package/dist/agents/errors.d.ts.map +1 -1
- package/dist/agents/errors.js.map +1 -1
- package/dist/agents/index.cjs +21 -7
- package/dist/agents/index.cjs.map +1 -1
- package/dist/agents/index.d.cts +2 -2
- package/dist/agents/index.d.cts.map +1 -1
- package/dist/agents/index.d.ts +2 -2
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +8 -8
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/middleware/constants.cjs +0 -1
- package/dist/agents/middleware/constants.cjs.map +1 -1
- package/dist/agents/middleware/constants.js.map +1 -1
- package/dist/agents/middleware/contextEditing.cjs +0 -1
- package/dist/agents/middleware/contextEditing.cjs.map +1 -1
- package/dist/agents/middleware/contextEditing.d.cts +1 -3
- package/dist/agents/middleware/contextEditing.d.cts.map +1 -1
- package/dist/agents/middleware/contextEditing.d.ts +1 -3
- package/dist/agents/middleware/contextEditing.d.ts.map +1 -1
- package/dist/agents/middleware/contextEditing.js.map +1 -1
- package/dist/agents/middleware/dynamicSystemPrompt.cjs +0 -1
- package/dist/agents/middleware/dynamicSystemPrompt.cjs.map +1 -1
- package/dist/agents/middleware/dynamicSystemPrompt.d.cts +1 -3
- package/dist/agents/middleware/dynamicSystemPrompt.d.cts.map +1 -1
- package/dist/agents/middleware/dynamicSystemPrompt.d.ts +1 -3
- package/dist/agents/middleware/dynamicSystemPrompt.d.ts.map +1 -1
- package/dist/agents/middleware/dynamicSystemPrompt.js.map +1 -1
- package/dist/agents/middleware/error.cjs +0 -1
- package/dist/agents/middleware/error.cjs.map +1 -1
- package/dist/agents/middleware/error.js.map +1 -1
- package/dist/agents/middleware/hitl.cjs +0 -1
- package/dist/agents/middleware/hitl.cjs.map +1 -1
- package/dist/agents/middleware/hitl.d.cts +1 -3
- package/dist/agents/middleware/hitl.d.cts.map +1 -1
- package/dist/agents/middleware/hitl.d.ts +1 -3
- package/dist/agents/middleware/hitl.d.ts.map +1 -1
- package/dist/agents/middleware/hitl.js.map +1 -1
- package/dist/agents/middleware/index.cjs +51 -19
- package/dist/agents/middleware/index.d.cts +3 -1
- package/dist/agents/middleware/index.d.ts +3 -1
- package/dist/agents/middleware/index.js +21 -20
- package/dist/agents/middleware/llmToolSelector.cjs +1 -1
- package/dist/agents/middleware/llmToolSelector.cjs.map +1 -1
- package/dist/agents/middleware/llmToolSelector.d.cts +9 -12
- package/dist/agents/middleware/llmToolSelector.d.cts.map +1 -1
- package/dist/agents/middleware/llmToolSelector.d.ts +9 -12
- package/dist/agents/middleware/llmToolSelector.d.ts.map +1 -1
- package/dist/agents/middleware/llmToolSelector.js +1 -1
- package/dist/agents/middleware/llmToolSelector.js.map +1 -1
- package/dist/agents/middleware/modelCallLimit.cjs +0 -1
- package/dist/agents/middleware/modelCallLimit.cjs.map +1 -1
- package/dist/agents/middleware/modelCallLimit.d.cts +1 -3
- package/dist/agents/middleware/modelCallLimit.d.cts.map +1 -1
- package/dist/agents/middleware/modelCallLimit.d.ts +1 -3
- package/dist/agents/middleware/modelCallLimit.d.ts.map +1 -1
- package/dist/agents/middleware/modelCallLimit.js.map +1 -1
- package/dist/agents/middleware/modelFallback.cjs.map +1 -1
- package/dist/agents/middleware/modelFallback.d.cts +1 -3
- package/dist/agents/middleware/modelFallback.d.cts.map +1 -1
- package/dist/agents/middleware/modelFallback.d.ts +1 -3
- package/dist/agents/middleware/modelFallback.d.ts.map +1 -1
- package/dist/agents/middleware/modelFallback.js.map +1 -1
- package/dist/agents/middleware/modelRetry.cjs +1 -1
- package/dist/agents/middleware/modelRetry.cjs.map +1 -1
- package/dist/agents/middleware/modelRetry.d.cts +2 -4
- package/dist/agents/middleware/modelRetry.d.cts.map +1 -1
- package/dist/agents/middleware/modelRetry.d.ts +2 -4
- package/dist/agents/middleware/modelRetry.d.ts.map +1 -1
- package/dist/agents/middleware/modelRetry.js +1 -1
- package/dist/agents/middleware/modelRetry.js.map +1 -1
- package/dist/agents/middleware/pii.cjs +2 -1
- package/dist/agents/middleware/pii.cjs.map +1 -1
- package/dist/agents/middleware/pii.d.cts +2 -4
- package/dist/agents/middleware/pii.d.cts.map +1 -1
- package/dist/agents/middleware/pii.d.ts +2 -4
- package/dist/agents/middleware/pii.d.ts.map +1 -1
- package/dist/agents/middleware/pii.js +2 -0
- package/dist/agents/middleware/pii.js.map +1 -1
- package/dist/agents/middleware/piiRedaction.cjs +0 -1
- package/dist/agents/middleware/piiRedaction.cjs.map +1 -1
- package/dist/agents/middleware/piiRedaction.d.cts +1 -3
- package/dist/agents/middleware/piiRedaction.d.cts.map +1 -1
- package/dist/agents/middleware/piiRedaction.d.ts +1 -3
- package/dist/agents/middleware/piiRedaction.d.ts.map +1 -1
- package/dist/agents/middleware/piiRedaction.js.map +1 -1
- package/dist/agents/middleware/provider/anthropic/promptCaching.cjs +0 -1
- package/dist/agents/middleware/provider/anthropic/promptCaching.cjs.map +1 -1
- package/dist/agents/middleware/provider/anthropic/promptCaching.d.cts +1 -3
- package/dist/agents/middleware/provider/anthropic/promptCaching.d.cts.map +1 -1
- package/dist/agents/middleware/provider/anthropic/promptCaching.d.ts +1 -3
- package/dist/agents/middleware/provider/anthropic/promptCaching.d.ts.map +1 -1
- package/dist/agents/middleware/provider/anthropic/promptCaching.js.map +1 -1
- package/dist/agents/middleware/provider/aws/promptCaching.cjs +0 -1
- package/dist/agents/middleware/provider/aws/promptCaching.cjs.map +1 -1
- package/dist/agents/middleware/provider/aws/promptCaching.d.cts +1 -3
- package/dist/agents/middleware/provider/aws/promptCaching.d.cts.map +1 -1
- package/dist/agents/middleware/provider/aws/promptCaching.d.ts +1 -3
- package/dist/agents/middleware/provider/aws/promptCaching.d.ts.map +1 -1
- package/dist/agents/middleware/provider/aws/promptCaching.js.map +1 -1
- package/dist/agents/middleware/provider/openai/moderation.cjs +1 -1
- package/dist/agents/middleware/provider/openai/moderation.cjs.map +1 -1
- package/dist/agents/middleware/provider/openai/moderation.d.cts +0 -4
- package/dist/agents/middleware/provider/openai/moderation.d.cts.map +1 -1
- package/dist/agents/middleware/provider/openai/moderation.d.ts +0 -4
- package/dist/agents/middleware/provider/openai/moderation.d.ts.map +1 -1
- package/dist/agents/middleware/provider/openai/moderation.js +1 -1
- package/dist/agents/middleware/provider/openai/moderation.js.map +1 -1
- package/dist/agents/middleware/providerToolSearch.cjs +0 -1
- package/dist/agents/middleware/providerToolSearch.cjs.map +1 -1
- package/dist/agents/middleware/providerToolSearch.d.cts +1 -2
- package/dist/agents/middleware/providerToolSearch.d.cts.map +1 -1
- package/dist/agents/middleware/providerToolSearch.d.ts +1 -2
- package/dist/agents/middleware/providerToolSearch.d.ts.map +1 -1
- package/dist/agents/middleware/providerToolSearch.js.map +1 -1
- package/dist/agents/middleware/summarization.cjs +2 -3
- package/dist/agents/middleware/summarization.cjs.map +1 -1
- package/dist/agents/middleware/summarization.d.cts +16 -20
- package/dist/agents/middleware/summarization.d.cts.map +1 -1
- package/dist/agents/middleware/summarization.d.ts +16 -20
- package/dist/agents/middleware/summarization.d.ts.map +1 -1
- package/dist/agents/middleware/summarization.js +2 -3
- package/dist/agents/middleware/summarization.js.map +1 -1
- package/dist/agents/middleware/todoListMiddleware.cjs +0 -1
- package/dist/agents/middleware/todoListMiddleware.cjs.map +1 -1
- package/dist/agents/middleware/todoListMiddleware.d.cts +2 -5
- package/dist/agents/middleware/todoListMiddleware.d.cts.map +1 -1
- package/dist/agents/middleware/todoListMiddleware.d.ts +2 -5
- package/dist/agents/middleware/todoListMiddleware.d.ts.map +1 -1
- package/dist/agents/middleware/todoListMiddleware.js.map +1 -1
- package/dist/agents/middleware/toolCallLimit.cjs +0 -1
- package/dist/agents/middleware/toolCallLimit.cjs.map +1 -1
- package/dist/agents/middleware/toolCallLimit.d.cts +2 -4
- package/dist/agents/middleware/toolCallLimit.d.cts.map +1 -1
- package/dist/agents/middleware/toolCallLimit.d.ts +2 -4
- package/dist/agents/middleware/toolCallLimit.d.ts.map +1 -1
- package/dist/agents/middleware/toolCallLimit.js.map +1 -1
- package/dist/agents/middleware/toolEmulator.cjs +0 -1
- package/dist/agents/middleware/toolEmulator.cjs.map +1 -1
- package/dist/agents/middleware/toolEmulator.d.cts +0 -1
- package/dist/agents/middleware/toolEmulator.d.cts.map +1 -1
- package/dist/agents/middleware/toolEmulator.d.ts +0 -1
- package/dist/agents/middleware/toolEmulator.d.ts.map +1 -1
- package/dist/agents/middleware/toolEmulator.js.map +1 -1
- package/dist/agents/middleware/toolError.cjs +67 -0
- package/dist/agents/middleware/toolError.cjs.map +1 -0
- package/dist/agents/middleware/toolError.d.cts +63 -0
- package/dist/agents/middleware/toolError.d.cts.map +1 -0
- package/dist/agents/middleware/toolError.d.ts +63 -0
- package/dist/agents/middleware/toolError.d.ts.map +1 -0
- package/dist/agents/middleware/toolError.js +67 -0
- package/dist/agents/middleware/toolError.js.map +1 -0
- package/dist/agents/middleware/toolRetry.cjs +1 -1
- package/dist/agents/middleware/toolRetry.cjs.map +1 -1
- package/dist/agents/middleware/toolRetry.d.cts +1 -2
- package/dist/agents/middleware/toolRetry.d.cts.map +1 -1
- package/dist/agents/middleware/toolRetry.d.ts +1 -2
- package/dist/agents/middleware/toolRetry.d.ts.map +1 -1
- package/dist/agents/middleware/toolRetry.js +1 -1
- package/dist/agents/middleware/toolRetry.js.map +1 -1
- package/dist/agents/middleware/types.cjs.map +1 -1
- package/dist/agents/middleware/types.d.cts +1 -2
- package/dist/agents/middleware/types.d.cts.map +1 -1
- package/dist/agents/middleware/types.d.ts +1 -2
- package/dist/agents/middleware/types.d.ts.map +1 -1
- package/dist/agents/middleware/types.js.map +1 -1
- package/dist/agents/middleware/utils.cjs +0 -1
- package/dist/agents/middleware/utils.cjs.map +1 -1
- package/dist/agents/middleware/utils.d.cts +2 -1
- package/dist/agents/middleware/utils.d.cts.map +1 -1
- package/dist/agents/middleware/utils.d.ts +2 -1
- package/dist/agents/middleware/utils.d.ts.map +1 -1
- package/dist/agents/middleware/utils.js.map +1 -1
- package/dist/agents/middleware.cjs.map +1 -1
- package/dist/agents/middleware.d.cts +0 -1
- package/dist/agents/middleware.d.cts.map +1 -1
- package/dist/agents/middleware.d.ts +0 -1
- package/dist/agents/middleware.d.ts.map +1 -1
- package/dist/agents/middleware.js.map +1 -1
- package/dist/agents/model.cjs.map +1 -1
- package/dist/agents/model.d.cts +0 -1
- package/dist/agents/model.d.cts.map +1 -1
- package/dist/agents/model.d.ts +0 -1
- package/dist/agents/model.d.ts.map +1 -1
- package/dist/agents/model.js.map +1 -1
- package/dist/agents/nodes/AfterAgentNode.cjs +1 -0
- package/dist/agents/nodes/AfterAgentNode.cjs.map +1 -1
- package/dist/agents/nodes/AfterAgentNode.js +1 -0
- package/dist/agents/nodes/AfterAgentNode.js.map +1 -1
- package/dist/agents/nodes/AfterModelNode.cjs +1 -0
- package/dist/agents/nodes/AfterModelNode.cjs.map +1 -1
- package/dist/agents/nodes/AfterModelNode.js +1 -0
- package/dist/agents/nodes/AfterModelNode.js.map +1 -1
- package/dist/agents/nodes/AgentNode.cjs +0 -1
- package/dist/agents/nodes/AgentNode.cjs.map +1 -1
- package/dist/agents/nodes/AgentNode.js.map +1 -1
- package/dist/agents/nodes/BeforeAgentNode.cjs +1 -0
- package/dist/agents/nodes/BeforeAgentNode.cjs.map +1 -1
- package/dist/agents/nodes/BeforeAgentNode.js +1 -0
- package/dist/agents/nodes/BeforeAgentNode.js.map +1 -1
- package/dist/agents/nodes/BeforeModelNode.cjs +1 -0
- package/dist/agents/nodes/BeforeModelNode.cjs.map +1 -1
- package/dist/agents/nodes/BeforeModelNode.js +1 -0
- package/dist/agents/nodes/BeforeModelNode.js.map +1 -1
- package/dist/agents/nodes/ToolNode.cjs +2 -1
- package/dist/agents/nodes/ToolNode.cjs.map +1 -1
- package/dist/agents/nodes/ToolNode.js +2 -1
- package/dist/agents/nodes/ToolNode.js.map +1 -1
- package/dist/agents/nodes/middleware.cjs +0 -1
- package/dist/agents/nodes/middleware.cjs.map +1 -1
- package/dist/agents/nodes/middleware.js.map +1 -1
- package/dist/agents/nodes/types.d.cts +0 -1
- package/dist/agents/nodes/types.d.cts.map +1 -1
- package/dist/agents/nodes/types.d.ts +0 -1
- package/dist/agents/nodes/types.d.ts.map +1 -1
- package/dist/agents/nodes/utils.cjs +0 -1
- package/dist/agents/nodes/utils.cjs.map +1 -1
- package/dist/agents/nodes/utils.js.map +1 -1
- package/dist/agents/responses.cjs +11 -5
- package/dist/agents/responses.cjs.map +1 -1
- package/dist/agents/responses.d.cts +3 -3
- package/dist/agents/responses.d.cts.map +1 -1
- package/dist/agents/responses.d.ts +3 -3
- package/dist/agents/responses.d.ts.map +1 -1
- package/dist/agents/responses.js +11 -5
- package/dist/agents/responses.js.map +1 -1
- package/dist/agents/runtime.d.cts +2 -2
- package/dist/agents/runtime.d.cts.map +1 -1
- package/dist/agents/runtime.d.ts +2 -2
- package/dist/agents/runtime.d.ts.map +1 -1
- package/dist/agents/tests/utils.cjs +0 -1
- package/dist/agents/tests/utils.cjs.map +1 -1
- package/dist/agents/tests/utils.d.cts +2 -9
- package/dist/agents/tests/utils.d.cts.map +1 -1
- package/dist/agents/tests/utils.d.ts +2 -9
- package/dist/agents/tests/utils.d.ts.map +1 -1
- package/dist/agents/tests/utils.js.map +1 -1
- package/dist/agents/transformers/index.cjs +4 -2
- package/dist/agents/transformers/index.d.cts +2 -1
- package/dist/agents/transformers/index.d.ts +2 -1
- package/dist/agents/transformers/index.js +3 -3
- package/dist/agents/transformers/subagent.cjs +0 -1
- package/dist/agents/transformers/subagent.cjs.map +1 -1
- package/dist/agents/transformers/subagent.d.cts +0 -1
- package/dist/agents/transformers/subagent.d.cts.map +1 -1
- package/dist/agents/transformers/subagent.d.ts +0 -1
- package/dist/agents/transformers/subagent.d.ts.map +1 -1
- package/dist/agents/transformers/subagent.js.map +1 -1
- package/dist/agents/transformers/tool-call.cjs +0 -1
- package/dist/agents/transformers/tool-call.cjs.map +1 -1
- package/dist/agents/transformers/tool-call.d.cts +0 -1
- package/dist/agents/transformers/tool-call.d.cts.map +1 -1
- package/dist/agents/transformers/tool-call.d.ts +0 -1
- package/dist/agents/transformers/tool-call.d.ts.map +1 -1
- package/dist/agents/transformers/tool-call.js.map +1 -1
- package/dist/agents/transformers/types.d.cts +3 -3
- package/dist/agents/transformers/types.d.cts.map +1 -1
- package/dist/agents/transformers/types.d.ts +3 -3
- package/dist/agents/transformers/types.d.ts.map +1 -1
- package/dist/agents/types.d.cts +1 -2
- package/dist/agents/types.d.cts.map +1 -1
- package/dist/agents/types.d.ts +1 -2
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/utils.cjs +11 -5
- package/dist/agents/utils.cjs.map +1 -1
- package/dist/agents/utils.js +11 -4
- package/dist/agents/utils.js.map +1 -1
- package/dist/agents/withAgentName.cjs +0 -1
- package/dist/agents/withAgentName.cjs.map +1 -1
- package/dist/agents/withAgentName.js.map +1 -1
- package/dist/browser.cjs +3 -0
- package/dist/browser.d.cts +3 -1
- package/dist/browser.d.ts +3 -1
- package/dist/browser.js +3 -1
- package/dist/chat_models/universal.cjs.map +1 -1
- package/dist/chat_models/universal.d.cts +0 -1
- package/dist/chat_models/universal.d.cts.map +1 -1
- package/dist/chat_models/universal.d.ts +0 -1
- package/dist/chat_models/universal.d.ts.map +1 -1
- package/dist/chat_models/universal.js.map +1 -1
- package/dist/hub/base.cjs +0 -1
- package/dist/hub/base.cjs.map +1 -1
- package/dist/hub/base.d.cts +1 -0
- package/dist/hub/base.d.cts.map +1 -1
- package/dist/hub/base.d.ts +1 -0
- package/dist/hub/base.d.ts.map +1 -1
- package/dist/hub/base.js.map +1 -1
- package/dist/hub/index.cjs.map +1 -1
- package/dist/hub/index.d.cts +0 -1
- package/dist/hub/index.d.cts.map +1 -1
- package/dist/hub/index.d.ts +0 -1
- package/dist/hub/index.d.ts.map +1 -1
- package/dist/hub/index.js.map +1 -1
- package/dist/hub/node.cjs.map +1 -1
- package/dist/hub/node.d.cts +0 -1
- package/dist/hub/node.d.cts.map +1 -1
- package/dist/hub/node.d.ts +0 -1
- package/dist/hub/node.d.ts.map +1 -1
- package/dist/hub/node.js.map +1 -1
- package/dist/index.cjs +3 -0
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/load/import_constants.cjs.map +1 -1
- package/dist/load/import_constants.js.map +1 -1
- package/dist/load/import_map.cjs +56 -0
- package/dist/load/import_map.cjs.map +1 -1
- package/dist/load/import_map.js +1 -1
- package/dist/load/import_map.js.map +1 -1
- package/dist/load/import_type.d.cts.map +1 -1
- package/dist/load/import_type.d.ts.map +1 -1
- package/dist/load/index.cjs +0 -1
- package/dist/load/index.cjs.map +1 -1
- package/dist/load/index.d.cts +0 -1
- package/dist/load/index.d.cts.map +1 -1
- package/dist/load/index.d.ts +0 -1
- package/dist/load/index.d.ts.map +1 -1
- package/dist/load/index.js.map +1 -1
- package/dist/storage/encoder_backed.cjs.map +1 -1
- package/dist/storage/encoder_backed.d.cts +0 -1
- package/dist/storage/encoder_backed.d.cts.map +1 -1
- package/dist/storage/encoder_backed.d.ts +0 -1
- package/dist/storage/encoder_backed.d.ts.map +1 -1
- package/dist/storage/encoder_backed.js.map +1 -1
- package/dist/storage/file_system.cjs +4 -3
- package/dist/storage/file_system.cjs.map +1 -1
- package/dist/storage/file_system.d.cts +20 -1
- package/dist/storage/file_system.d.cts.map +1 -1
- package/dist/storage/file_system.d.ts +20 -1
- package/dist/storage/file_system.d.ts.map +1 -1
- package/dist/storage/file_system.js +4 -3
- package/dist/storage/file_system.js.map +1 -1
- package/dist/tools/headless.cjs +0 -1
- package/dist/tools/headless.cjs.map +1 -1
- package/dist/tools/headless.d.cts +5 -3
- package/dist/tools/headless.d.cts.map +1 -1
- package/dist/tools/headless.d.ts +5 -3
- package/dist/tools/headless.d.ts.map +1 -1
- package/dist/tools/headless.js.map +1 -1
- package/package.json +16 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolNode.cjs","names":["BaseMessage","ToolInvocationError","ToolMessage","RunnableCallable","MiddlewareError","mergeAbortSignals","ToolInputParsingException","#handleError","AIMessage","isCommand","Command","Send"],"sources":["../../../src/agents/nodes/ToolNode.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\n/* oxlint-disable no-instanceof/no-instanceof */\nimport { BaseMessage, ToolMessage, AIMessage } from \"@langchain/core/messages\";\nimport { RunnableConfig, RunnableToolLike } from \"@langchain/core/runnables\";\nimport {\n DynamicTool,\n StructuredToolInterface,\n ToolInputParsingException,\n} from \"@langchain/core/tools\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport type { InteropZodObject } from \"@langchain/core/utils/types\";\nimport {\n isCommand,\n Command,\n Send,\n isGraphInterrupt,\n type LangGraphRunnableConfig,\n StateDefinitionInit,\n} from \"@langchain/langgraph\";\n\nimport { RunnableCallable } from \"../RunnableCallable.js\";\nimport { mergeAbortSignals } from \"./utils.js\";\nimport { MiddlewareError, ToolInvocationError } from \"../errors.js\";\nimport type {\n WrapToolCallHook,\n ToolCallRequest,\n ToAnnotationRoot,\n} from \"../middleware/types.js\";\nimport type { AgentBuiltInState } from \"../runtime.js\";\n\n/**\n * Error message template for when middleware adds tools that can't be executed.\n * This happens when middleware modifies tools in wrapModelCall but doesn't provide\n * a wrapToolCall handler to execute them.\n */\nconst getInvalidToolError = (\n toolName: string,\n availableTools: string[]\n): string =>\n `Error: ${toolName} is not a valid tool, try one of [${availableTools.join(\", \")}].`;\n\n/**\n * The name of the tool node in the state graph.\n */\nexport const TOOLS_NODE_NAME = \"tools\";\n\nexport interface ToolNodeOptions {\n /**\n * The name of the tool node.\n */\n name?: string;\n /**\n * The tags to add to the tool call.\n */\n tags?: string[];\n /**\n * The abort signal to cancel the tool call.\n */\n signal?: AbortSignal;\n /**\n * Whether to throw the error immediately if the tool fails or handle it by the `onToolError` function or via ToolMessage.\n *\n * **Default behavior** (matches Python):\n * - Catches only `ToolInvocationError` (invalid arguments from model) and converts to ToolMessage\n * - Re-raises all other errors including errors from `wrapToolCall` middleware\n *\n * If `true`:\n * - Catches all errors and returns a ToolMessage with the error\n *\n * If `false`:\n * - All errors are thrown immediately\n *\n * If a function is provided:\n * - If function returns a `ToolMessage`, use it as the result\n * - If function returns `undefined`, re-raise the error\n *\n * @default A function that only catches ToolInvocationError\n */\n handleToolErrors?:\n | boolean\n | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined);\n /**\n * Optional wrapper function for tool execution.\n * Allows middleware to intercept and modify tool calls before execution.\n * The wrapper receives the tool call request and a handler function to execute the tool.\n */\n wrapToolCall?: WrapToolCallHook;\n}\n\nconst isBaseMessageArray = (input: unknown): input is BaseMessage[] =>\n Array.isArray(input) && input.every(BaseMessage.isInstance);\n\nconst isMessagesState = (\n input: unknown\n): input is { messages: BaseMessage[] } =>\n typeof input === \"object\" &&\n input != null &&\n \"messages\" in input &&\n isBaseMessageArray(input.messages);\n\nconst isSendInput = (\n input: unknown\n): input is { lg_tool_call: ToolCall; jumpTo?: string } =>\n typeof input === \"object\" && input != null && \"lg_tool_call\" in input;\n\n/**\n * Default error handler for tool errors.\n *\n * This is applied to errors from baseHandler (tool execution).\n * For errors from wrapToolCall middleware, those are handled separately\n * and will bubble up by default.\n *\n * Catches all tool execution errors and converts them to ToolMessage.\n * This allows the LLM to see the error and potentially retry with different arguments.\n */\nfunction defaultHandleToolErrors(\n error: unknown,\n toolCall: ToolCall\n): ToolMessage | undefined {\n if (ToolInvocationError.isInstance(error)) {\n return new ToolMessage({\n content: error.message,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n });\n }\n /**\n * Catch all other tool errors and convert to ToolMessage\n */\n return new ToolMessage({\n content: `${error}\\n Please fix your mistakes.`,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n });\n}\n\n/**\n * `ToolNode` is a built-in LangGraph component that handles tool calls within an agent's workflow.\n * It works seamlessly with `createAgent`, offering advanced tool execution control, built\n * in parallelism, and error handling.\n *\n * @example\n * ```ts\n * import { ToolNode, tool, AIMessage } from \"langchain\";\n * import { z } from \"zod/v3\";\n *\n * const getWeather = tool((input) => {\n * if ([\"sf\", \"san francisco\"].includes(input.location.toLowerCase())) {\n * return \"It's 60 degrees and foggy.\";\n * } else {\n * return \"It's 90 degrees and sunny.\";\n * }\n * }, {\n * name: \"get_weather\",\n * description: \"Call to get the current weather.\",\n * schema: z.object({\n * location: z.string().describe(\"Location to get the weather for.\"),\n * }),\n * });\n *\n * const tools = [getWeather];\n * const toolNode = new ToolNode(tools);\n *\n * const messageWithSingleToolCall = new AIMessage({\n * content: \"\",\n * tool_calls: [\n * {\n * name: \"get_weather\",\n * args: { location: \"sf\" },\n * id: \"tool_call_id\",\n * type: \"tool_call\",\n * }\n * ]\n * })\n *\n * await toolNode.invoke({ messages: [messageWithSingleToolCall] });\n * // Returns tool invocation responses as:\n * // { messages: ToolMessage[] }\n * ```\n */\nexport class ToolNode<\n StateSchema extends StateDefinitionInit = any,\n ContextSchema extends InteropZodObject = any,\n> extends RunnableCallable<StateSchema, ContextSchema> {\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[];\n\n trace = false;\n\n signal?: AbortSignal;\n\n handleToolErrors:\n | boolean\n | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined) =\n defaultHandleToolErrors;\n\n wrapToolCall: WrapToolCallHook | undefined;\n\n constructor(\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[],\n public options?: ToolNodeOptions\n ) {\n const { name, tags, handleToolErrors, signal, wrapToolCall } =\n options ?? {};\n super({\n name,\n tags,\n func: (state, config) =>\n this.run(\n state as ToAnnotationRoot<StateDefinitionInit>[\"State\"] &\n AgentBuiltInState,\n config as RunnableConfig\n ),\n });\n this.tools = tools;\n this.handleToolErrors = handleToolErrors ?? this.handleToolErrors;\n this.signal = signal;\n this.wrapToolCall = wrapToolCall;\n }\n\n /**\n * Handle errors from tool execution or middleware.\n * @param error - The error to handle\n * @param call - The tool call that caused the error\n * @param isMiddlewareError - Whether the error came from wrapToolCall middleware\n * @returns ToolMessage if error is handled, otherwise re-throws\n */\n #handleError(\n error: unknown,\n call: ToolCall,\n isMiddlewareError: boolean\n ): ToolMessage {\n /**\n * {@link NodeInterrupt} errors are a breakpoint to bring a human into the loop.\n * As such, they are not recoverable by the agent and shouldn't be fed\n * back. Instead, re-throw these errors even when `handleToolErrors = true`.\n */\n if (isGraphInterrupt(error)) {\n throw error;\n }\n\n /**\n * If the signal is aborted, we want to bubble up the error to the invoke caller.\n */\n if (this.signal?.aborted) {\n throw error;\n }\n\n /**\n * A recoverable tool error (e.g. tool-input schema validation) can be\n * rewrapped as a {@link MiddlewareError} with the original error on `.cause`\n * — once per `wrapToolCall` middleware, so it may be nested several layers\n * deep. Walk the cause chain to the root; if it's a {@link ToolInvocationError},\n * unwrap it so the intended `handleToolErrors` self-correction path still\n * applies. Genuine middleware errors stay fatal by default.\n */\n let effectiveError = error;\n let errorFromMiddleware = isMiddlewareError;\n if (isMiddlewareError) {\n let unwrapped: unknown = error;\n while (MiddlewareError.isInstance(unwrapped)) {\n unwrapped = unwrapped.cause;\n }\n if (ToolInvocationError.isInstance(unwrapped)) {\n effectiveError = unwrapped;\n errorFromMiddleware = false;\n }\n }\n\n /**\n * If error is from middleware and handleToolErrors is not true, bubble up\n * (default handler and false both re-raise middleware errors)\n */\n if (errorFromMiddleware && this.handleToolErrors !== true) {\n throw effectiveError;\n }\n\n /**\n * If handleToolErrors is false, throw all errors\n */\n if (!this.handleToolErrors) {\n throw effectiveError;\n }\n\n /**\n * Apply handleToolErrors to the error\n */\n if (typeof this.handleToolErrors === \"function\") {\n const result = this.handleToolErrors(effectiveError, call);\n if (result && ToolMessage.isInstance(result)) {\n return result;\n }\n\n /**\n * `handleToolErrors` returned undefined - re-raise\n */\n throw effectiveError;\n } else if (this.handleToolErrors) {\n return new ToolMessage({\n name: call.name,\n content: `${effectiveError}\\n Please fix your mistakes.`,\n tool_call_id: call.id!,\n });\n }\n\n /**\n * Shouldn't reach here, but throw as fallback\n */\n throw effectiveError;\n }\n\n protected async runTool(\n call: ToolCall,\n config: RunnableConfig,\n state: AgentBuiltInState\n ): Promise<ToolMessage | Command> {\n /**\n * Build runtime from LangGraph config\n */\n const lgConfig = config as LangGraphRunnableConfig;\n const runtime = {\n context: lgConfig?.context,\n store: lgConfig?.store,\n configurable: lgConfig?.configurable,\n writer: lgConfig?.writer,\n interrupt: lgConfig?.interrupt,\n signal: lgConfig?.signal,\n };\n\n /**\n * Find the tool instance to include in the request.\n * For dynamically registered tools, this may be undefined.\n */\n const registeredTool = this.tools.find((t) => t.name === call.name);\n\n /**\n * Define the base handler that executes the tool.\n * When wrapToolCall middleware is present, this handler does NOT catch errors\n * so the middleware can handle them.\n * When no middleware, errors are caught and handled here.\n *\n * The handler now accepts an overridden tool from the request, allowing\n * middleware to provide tool implementations for dynamically registered tools.\n */\n const baseHandler = async (\n request: ToolCallRequest\n ): Promise<ToolMessage | Command> => {\n const { toolCall, tool: requestTool } = request;\n\n /**\n * Use the tool from the request (which may be overridden via spread syntax)\n * or fall back to finding it in registered tools.\n * This allows middleware to provide dynamic tool implementations.\n */\n const tool =\n requestTool ?? this.tools.find((t) => t.name === toolCall.name);\n\n if (tool === undefined) {\n /**\n * Tool not found - return a graceful error message rather than throwing.\n * This allows the LLM to see the error and potentially retry.\n */\n const availableTools = this.tools.map((t) => t.name);\n return new ToolMessage({\n content: getInvalidToolError(toolCall.name, availableTools),\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\n });\n }\n\n /**\n * Cast tool to a common invokable type.\n * The tool can be from registered tools (StructuredToolInterface | DynamicTool | RunnableToolLike)\n * or from middleware override (ClientTool | ServerTool).\n */\n const invokableTool = tool as\n | StructuredToolInterface\n | DynamicTool\n | RunnableToolLike;\n\n try {\n const output = await invokableTool.invoke(\n { ...toolCall, type: \"tool_call\" },\n {\n ...config,\n /**\n * extend to match ToolRuntime\n */\n config,\n toolCallId: toolCall.id!,\n state: config.configurable?.__pregel_scratchpad?.currentTaskInput,\n signal: mergeAbortSignals(this.signal, config.signal),\n }\n );\n\n if (ToolMessage.isInstance(output) || isCommand(output)) {\n return output as ToolMessage | Command;\n }\n\n return new ToolMessage({\n name: invokableTool.name,\n content: typeof output === \"string\" ? output : JSON.stringify(output),\n tool_call_id: toolCall.id!,\n });\n } catch (e: unknown) {\n /**\n * Handle errors from tool execution (not from wrapToolCall)\n * If tool invocation fails due to input parsing error, throw a {@link ToolInvocationError}\n */\n if (e instanceof ToolInputParsingException) {\n throw new ToolInvocationError(e, toolCall);\n }\n /**\n * Re-throw to be handled by caller\n */\n throw e;\n }\n };\n\n /**\n * Create request object for middleware\n * Cast to ToolCallRequest<AgentBuiltInState> to satisfy type constraints\n * of wrapToolCall which expects AgentBuiltInState\n */\n const request: ToolCallRequest<AgentBuiltInState> = {\n toolCall: call,\n tool: registeredTool,\n state,\n runtime,\n };\n\n /**\n * If wrapToolCall is provided, use it to wrap the tool execution\n */\n if (this.wrapToolCall) {\n try {\n return await this.wrapToolCall(request, baseHandler);\n } catch (e: unknown) {\n /**\n * Handle middleware errors\n */\n return this.#handleError(e, call, true);\n }\n }\n\n /**\n * No wrapToolCall - if tool wasn't found, return graceful error\n */\n if (!registeredTool) {\n const availableTools = this.tools.map((t) => t.name);\n return new ToolMessage({\n content: getInvalidToolError(call.name, availableTools),\n tool_call_id: call.id!,\n name: call.name,\n status: \"error\",\n });\n }\n\n /**\n * No wrapToolCall - execute tool directly and handle errors here\n */\n try {\n return await baseHandler(request);\n } catch (e: unknown) {\n /**\n * Handle tool errors when no middleware provided\n */\n return this.#handleError(e, call, false);\n }\n }\n\n protected async run(\n state: ToAnnotationRoot<StateSchema>[\"State\"] & AgentBuiltInState,\n config: RunnableConfig\n ): Promise<ContextSchema> {\n let outputs: (ToolMessage | Command)[];\n\n if (isSendInput(state)) {\n const { lg_tool_call: _, jumpTo: __, ...newState } = state;\n outputs = [await this.runTool(state.lg_tool_call, config, newState)];\n } else {\n let messages: BaseMessage[];\n if (isBaseMessageArray(state)) {\n messages = state;\n } else if (isMessagesState(state)) {\n messages = state.messages;\n } else {\n throw new Error(\n \"ToolNode only accepts BaseMessage[] or { messages: BaseMessage[] } as input.\"\n );\n }\n\n const toolMessageIds: Set<string> = new Set(\n messages\n .filter((msg) => msg.getType() === \"tool\")\n .map((msg) => (msg as ToolMessage).tool_call_id)\n );\n\n let aiMessage: AIMessage | undefined;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (AIMessage.isInstance(message)) {\n aiMessage = message;\n break;\n }\n }\n\n if (!AIMessage.isInstance(aiMessage)) {\n throw new Error(\"ToolNode only accepts AIMessages as input.\");\n }\n\n outputs = await Promise.all(\n aiMessage.tool_calls\n ?.filter((call) => call.id == null || !toolMessageIds.has(call.id))\n .map((call) => this.runTool(call, config, state)) ?? []\n );\n }\n\n // Preserve existing behavior for non-command tool outputs for backwards compatibility\n if (!outputs.some(isCommand)) {\n return (Array.isArray(state)\n ? outputs\n : { messages: outputs }) as unknown as ContextSchema;\n }\n\n // Handle mixed Command and non-Command outputs\n const combinedOutputs: (\n | { messages: BaseMessage[] }\n | BaseMessage[]\n | Command\n )[] = [];\n let parentCommand: Command | null = null;\n\n for (const output of outputs) {\n if (isCommand(output)) {\n if (\n output.graph === Command.PARENT &&\n Array.isArray(output.goto) &&\n output.goto.every((send) => isSend(send))\n ) {\n if (parentCommand) {\n (parentCommand.goto as Send[]).push(...(output.goto as Send[]));\n } else {\n parentCommand = new Command({\n graph: Command.PARENT,\n goto: output.goto,\n });\n }\n } else {\n combinedOutputs.push(output);\n }\n } else {\n combinedOutputs.push(\n Array.isArray(state) ? [output] : { messages: [output] }\n );\n }\n }\n\n if (parentCommand) {\n combinedOutputs.push(parentCommand);\n }\n\n return combinedOutputs as unknown as ContextSchema;\n }\n}\n\nexport function isSend(x: unknown): x is Send {\n return x instanceof Send;\n}\n"],"mappings":";;;;;;;;;;;;;AAmCA,MAAM,uBACJ,UACA,mBAEA,UAAU,SAAS,oCAAoC,eAAe,KAAK,KAAK,CAAC;;;;AAKnF,MAAa,kBAAkB;AA6C/B,MAAM,sBAAsB,UAC1B,MAAM,QAAQ,MAAM,IAAI,MAAM,MAAMA,yBAAAA,YAAY,WAAW;AAE7D,MAAM,mBACJ,UAEA,OAAO,UAAU,YACjB,SAAS,QACT,cAAc,SACd,mBAAmB,MAAM,SAAS;AAEpC,MAAM,eACJ,UAEA,OAAO,UAAU,YAAY,SAAS,QAAQ,kBAAkB;;;;;;;;;;;AAYlE,SAAS,wBACP,OACA,UACyB;AACzB,KAAIC,eAAAA,oBAAoB,WAAW,MAAM,CACvC,QAAO,IAAIC,yBAAAA,YAAY;EACrB,SAAS,MAAM;EACf,cAAc,SAAS;EACvB,MAAM,SAAS;EAChB,CAAC;;;;AAKJ,QAAO,IAAIA,yBAAAA,YAAY;EACrB,SAAS,GAAG,MAAM;EAClB,cAAc,SAAS;EACvB,MAAM,SAAS;EAChB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CJ,IAAa,WAAb,cAGUC,yBAAAA,iBAA6C;CACrD;CAEA,QAAQ;CAER;CAEA,mBAGE;CAEF;CAEA,YACE,OACA,SACA;EACA,MAAM,EAAE,MAAM,MAAM,kBAAkB,QAAQ,iBAC5C,WAAW,EAAE;AACf,QAAM;GACJ;GACA;GACA,OAAO,OAAO,WACZ,KAAK,IACH,OAEA,OACD;GACJ,CAAC;AAbK,OAAA,UAAA;AAcP,OAAK,QAAQ;AACb,OAAK,mBAAmB,oBAAoB,KAAK;AACjD,OAAK,SAAS;AACd,OAAK,eAAe;;;;;;;;;CAUtB,aACE,OACA,MACA,mBACa;;;;;;AAMb,OAAA,GAAA,qBAAA,kBAAqB,MAAM,CACzB,OAAM;;;;AAMR,MAAI,KAAK,QAAQ,QACf,OAAM;;;;;;;;;EAWR,IAAI,iBAAiB;EACrB,IAAI,sBAAsB;AAC1B,MAAI,mBAAmB;GACrB,IAAI,YAAqB;AACzB,UAAOC,eAAAA,gBAAgB,WAAW,UAAU,CAC1C,aAAY,UAAU;AAExB,OAAIH,eAAAA,oBAAoB,WAAW,UAAU,EAAE;AAC7C,qBAAiB;AACjB,0BAAsB;;;;;;;AAQ1B,MAAI,uBAAuB,KAAK,qBAAqB,KACnD,OAAM;;;;AAMR,MAAI,CAAC,KAAK,iBACR,OAAM;;;;AAMR,MAAI,OAAO,KAAK,qBAAqB,YAAY;GAC/C,MAAM,SAAS,KAAK,iBAAiB,gBAAgB,KAAK;AAC1D,OAAI,UAAUC,yBAAAA,YAAY,WAAW,OAAO,CAC1C,QAAO;;;;AAMT,SAAM;aACG,KAAK,iBACd,QAAO,IAAIA,yBAAAA,YAAY;GACrB,MAAM,KAAK;GACX,SAAS,GAAG,eAAe;GAC3B,cAAc,KAAK;GACpB,CAAC;;;;AAMJ,QAAM;;CAGR,MAAgB,QACd,MACA,QACA,OACgC;;;;EAIhC,MAAM,WAAW;EACjB,MAAM,UAAU;GACd,SAAS,UAAU;GACnB,OAAO,UAAU;GACjB,cAAc,UAAU;GACxB,QAAQ,UAAU;GAClB,WAAW,UAAU;GACrB,QAAQ,UAAU;GACnB;;;;;EAMD,MAAM,iBAAiB,KAAK,MAAM,MAAM,MAAM,EAAE,SAAS,KAAK,KAAK;;;;;;;;;;EAWnE,MAAM,cAAc,OAClB,YACmC;GACnC,MAAM,EAAE,UAAU,MAAM,gBAAgB;;;;;;GAOxC,MAAM,OACJ,eAAe,KAAK,MAAM,MAAM,MAAM,EAAE,SAAS,SAAS,KAAK;AAEjE,OAAI,SAAS,KAAA,GAAW;;;;;IAKtB,MAAM,iBAAiB,KAAK,MAAM,KAAK,MAAM,EAAE,KAAK;AACpD,WAAO,IAAIA,yBAAAA,YAAY;KACrB,SAAS,oBAAoB,SAAS,MAAM,eAAe;KAC3D,cAAc,SAAS;KACvB,MAAM,SAAS;KACf,QAAQ;KACT,CAAC;;;;;;;GAQJ,MAAM,gBAAgB;AAKtB,OAAI;IACF,MAAM,SAAS,MAAM,cAAc,OACjC;KAAE,GAAG;KAAU,MAAM;KAAa,EAClC;KACE,GAAG;;;;KAIH;KACA,YAAY,SAAS;KACrB,OAAO,OAAO,cAAc,qBAAqB;KACjD,QAAQG,cAAAA,kBAAkB,KAAK,QAAQ,OAAO,OAAO;KACtD,CACF;AAED,QAAIH,yBAAAA,YAAY,WAAW,OAAO,KAAA,GAAA,qBAAA,WAAc,OAAO,CACrD,QAAO;AAGT,WAAO,IAAIA,yBAAAA,YAAY;KACrB,MAAM,cAAc;KACpB,SAAS,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,OAAO;KACrE,cAAc,SAAS;KACxB,CAAC;YACK,GAAY;;;;;AAKnB,QAAI,aAAaI,sBAAAA,0BACf,OAAM,IAAIL,eAAAA,oBAAoB,GAAG,SAAS;;;;AAK5C,UAAM;;;;;;;;EASV,MAAM,UAA8C;GAClD,UAAU;GACV,MAAM;GACN;GACA;GACD;;;;AAKD,MAAI,KAAK,aACP,KAAI;AACF,UAAO,MAAM,KAAK,aAAa,SAAS,YAAY;WAC7C,GAAY;;;;AAInB,UAAO,MAAA,YAAkB,GAAG,MAAM,KAAK;;;;;AAO3C,MAAI,CAAC,gBAAgB;GACnB,MAAM,iBAAiB,KAAK,MAAM,KAAK,MAAM,EAAE,KAAK;AACpD,UAAO,IAAIC,yBAAAA,YAAY;IACrB,SAAS,oBAAoB,KAAK,MAAM,eAAe;IACvD,cAAc,KAAK;IACnB,MAAM,KAAK;IACX,QAAQ;IACT,CAAC;;;;;AAMJ,MAAI;AACF,UAAO,MAAM,YAAY,QAAQ;WAC1B,GAAY;;;;AAInB,UAAO,MAAA,YAAkB,GAAG,MAAM,MAAM;;;CAI5C,MAAgB,IACd,OACA,QACwB;EACxB,IAAI;AAEJ,MAAI,YAAY,MAAM,EAAE;GACtB,MAAM,EAAE,cAAc,GAAG,QAAQ,IAAI,GAAG,aAAa;AACrD,aAAU,CAAC,MAAM,KAAK,QAAQ,MAAM,cAAc,QAAQ,SAAS,CAAC;SAC/D;GACL,IAAI;AACJ,OAAI,mBAAmB,MAAM,CAC3B,YAAW;YACF,gBAAgB,MAAM,CAC/B,YAAW,MAAM;OAEjB,OAAM,IAAI,MACR,+EACD;GAGH,MAAM,iBAA8B,IAAI,IACtC,SACG,QAAQ,QAAQ,IAAI,SAAS,KAAK,OAAO,CACzC,KAAK,QAAS,IAAoB,aAAa,CACnD;GAED,IAAI;AACJ,QAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;IAChD,MAAM,UAAU,SAAS;AACzB,QAAIM,yBAAAA,UAAU,WAAW,QAAQ,EAAE;AACjC,iBAAY;AACZ;;;AAIJ,OAAI,CAACA,yBAAAA,UAAU,WAAW,UAAU,CAClC,OAAM,IAAI,MAAM,6CAA6C;AAG/D,aAAU,MAAM,QAAQ,IACtB,UAAU,YACN,QAAQ,SAAS,KAAK,MAAM,QAAQ,CAAC,eAAe,IAAI,KAAK,GAAG,CAAC,CAClE,KAAK,SAAS,KAAK,QAAQ,MAAM,QAAQ,MAAM,CAAC,IAAI,EAAE,CAC1D;;AAIH,MAAI,CAAC,QAAQ,KAAKC,qBAAAA,UAAU,CAC1B,QAAQ,MAAM,QAAQ,MAAM,GACxB,UACA,EAAE,UAAU,SAAS;EAI3B,MAAM,kBAIA,EAAE;EACR,IAAI,gBAAgC;AAEpC,OAAK,MAAM,UAAU,QACnB,MAAA,GAAA,qBAAA,WAAc,OAAO,CACnB,KACE,OAAO,UAAUC,qBAAAA,QAAQ,UACzB,MAAM,QAAQ,OAAO,KAAK,IAC1B,OAAO,KAAK,OAAO,SAAS,OAAO,KAAK,CAAC,CAEzC,KAAI,cACD,eAAc,KAAgB,KAAK,GAAI,OAAO,KAAgB;MAE/D,iBAAgB,IAAIA,qBAAAA,QAAQ;GAC1B,OAAOA,qBAAAA,QAAQ;GACf,MAAM,OAAO;GACd,CAAC;MAGJ,iBAAgB,KAAK,OAAO;MAG9B,iBAAgB,KACd,MAAM,QAAQ,MAAM,GAAG,CAAC,OAAO,GAAG,EAAE,UAAU,CAAC,OAAO,EAAE,CACzD;AAIL,MAAI,cACF,iBAAgB,KAAK,cAAc;AAGrC,SAAO;;;AAIX,SAAgB,OAAO,GAAuB;AAC5C,QAAO,aAAaC,qBAAAA"}
|
|
1
|
+
{"version":3,"file":"ToolNode.cjs","names":["BaseMessage","ToolInvocationError","ToolMessage","RunnableCallable","MiddlewareError","mergeAbortSignals","ToolInputParsingException","#handleError","AIMessage","isCommand","Command","Send"],"sources":["../../../src/agents/nodes/ToolNode.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\n/* oxlint-disable no-instanceof/no-instanceof */\nimport { BaseMessage, ToolMessage, AIMessage } from \"@langchain/core/messages\";\nimport { RunnableConfig, RunnableToolLike } from \"@langchain/core/runnables\";\nimport {\n DynamicTool,\n StructuredToolInterface,\n ToolInputParsingException,\n} from \"@langchain/core/tools\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport type { InteropZodObject } from \"@langchain/core/utils/types\";\nimport {\n isCommand,\n Command,\n Send,\n isGraphInterrupt,\n type LangGraphRunnableConfig,\n StateDefinitionInit,\n} from \"@langchain/langgraph\";\n\nimport { RunnableCallable } from \"../RunnableCallable.js\";\nimport { mergeAbortSignals } from \"./utils.js\";\nimport { MiddlewareError, ToolInvocationError } from \"../errors.js\";\nimport type {\n WrapToolCallHook,\n ToolCallRequest,\n ToAnnotationRoot,\n} from \"../middleware/types.js\";\nimport type { AgentBuiltInState } from \"../runtime.js\";\n\n/**\n * Error message template for when middleware adds tools that can't be executed.\n * This happens when middleware modifies tools in wrapModelCall but doesn't provide\n * a wrapToolCall handler to execute them.\n */\nconst getInvalidToolError = (\n toolName: string,\n availableTools: string[]\n): string =>\n `Error: ${toolName} is not a valid tool, try one of [${availableTools.join(\", \")}].`;\n\n/**\n * The name of the tool node in the state graph.\n */\nexport const TOOLS_NODE_NAME = \"tools\";\n\nexport interface ToolNodeOptions {\n /**\n * The name of the tool node.\n */\n name?: string;\n /**\n * The tags to add to the tool call.\n */\n tags?: string[];\n /**\n * The abort signal to cancel the tool call.\n */\n signal?: AbortSignal;\n /**\n * Whether to throw the error immediately if the tool fails or handle it by the `onToolError` function or via ToolMessage.\n *\n * **Default behavior** (matches Python):\n * - Catches only `ToolInvocationError` (invalid arguments from model) and converts to ToolMessage\n * - Re-raises all other errors including errors from `wrapToolCall` middleware\n *\n * If `true`:\n * - Catches all errors and returns a ToolMessage with the error\n *\n * If `false`:\n * - All errors are thrown immediately\n *\n * If a function is provided:\n * - If function returns a `ToolMessage`, use it as the result\n * - If function returns `undefined`, re-raise the error\n *\n * @default A function that only catches ToolInvocationError\n */\n handleToolErrors?:\n | boolean\n | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined);\n /**\n * Optional wrapper function for tool execution.\n * Allows middleware to intercept and modify tool calls before execution.\n * The wrapper receives the tool call request and a handler function to execute the tool.\n */\n wrapToolCall?: WrapToolCallHook;\n}\n\nconst isBaseMessageArray = (input: unknown): input is BaseMessage[] =>\n Array.isArray(input) && input.every(BaseMessage.isInstance);\n\nconst isMessagesState = (\n input: unknown\n): input is { messages: BaseMessage[] } =>\n typeof input === \"object\" &&\n input != null &&\n \"messages\" in input &&\n isBaseMessageArray(input.messages);\n\nconst isSendInput = (\n input: unknown\n): input is { lg_tool_call: ToolCall; jumpTo?: string } =>\n typeof input === \"object\" && input != null && \"lg_tool_call\" in input;\n\n/**\n * Default error handler for tool errors.\n *\n * This is applied to errors from baseHandler (tool execution).\n * For errors from wrapToolCall middleware, those are handled separately\n * and will bubble up by default.\n *\n * Catches all tool execution errors and converts them to ToolMessage.\n * This allows the LLM to see the error and potentially retry with different arguments.\n */\nfunction defaultHandleToolErrors(\n error: unknown,\n toolCall: ToolCall\n): ToolMessage | undefined {\n if (ToolInvocationError.isInstance(error)) {\n return new ToolMessage({\n content: error.message,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n });\n }\n /**\n * Catch all other tool errors and convert to ToolMessage\n */\n return new ToolMessage({\n content: `${error}\\n Please fix your mistakes.`,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n });\n}\n\n/**\n * `ToolNode` is a built-in LangGraph component that handles tool calls within an agent's workflow.\n * It works seamlessly with `createAgent`, offering advanced tool execution control, built\n * in parallelism, and error handling.\n *\n * @example\n * ```ts\n * import { ToolNode, tool, AIMessage } from \"langchain\";\n * import { z } from \"zod/v3\";\n *\n * const getWeather = tool((input) => {\n * if ([\"sf\", \"san francisco\"].includes(input.location.toLowerCase())) {\n * return \"It's 60 degrees and foggy.\";\n * } else {\n * return \"It's 90 degrees and sunny.\";\n * }\n * }, {\n * name: \"get_weather\",\n * description: \"Call to get the current weather.\",\n * schema: z.object({\n * location: z.string().describe(\"Location to get the weather for.\"),\n * }),\n * });\n *\n * const tools = [getWeather];\n * const toolNode = new ToolNode(tools);\n *\n * const messageWithSingleToolCall = new AIMessage({\n * content: \"\",\n * tool_calls: [\n * {\n * name: \"get_weather\",\n * args: { location: \"sf\" },\n * id: \"tool_call_id\",\n * type: \"tool_call\",\n * }\n * ]\n * })\n *\n * await toolNode.invoke({ messages: [messageWithSingleToolCall] });\n * // Returns tool invocation responses as:\n * // { messages: ToolMessage[] }\n * ```\n */\nexport class ToolNode<\n StateSchema extends StateDefinitionInit = any,\n ContextSchema extends InteropZodObject = any,\n> extends RunnableCallable<StateSchema, ContextSchema> {\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[];\n\n trace = false;\n\n signal?: AbortSignal;\n\n handleToolErrors:\n | boolean\n | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined) =\n defaultHandleToolErrors;\n\n wrapToolCall: WrapToolCallHook | undefined;\n\n constructor(\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[],\n public options?: ToolNodeOptions\n ) {\n const { name, tags, handleToolErrors, signal, wrapToolCall } =\n options ?? {};\n super({\n name,\n tags,\n func: (state, config) =>\n this.run(\n state as ToAnnotationRoot<StateDefinitionInit>[\"State\"] &\n AgentBuiltInState,\n config as RunnableConfig\n ),\n });\n this.tools = tools;\n this.handleToolErrors = handleToolErrors ?? this.handleToolErrors;\n this.signal = signal;\n this.wrapToolCall = wrapToolCall;\n }\n\n /**\n * Handle errors from tool execution or middleware.\n * @param error - The error to handle\n * @param call - The tool call that caused the error\n * @param isMiddlewareError - Whether the error came from wrapToolCall middleware\n * @returns ToolMessage if error is handled, otherwise re-throws\n */\n #handleError(\n error: unknown,\n call: ToolCall,\n isMiddlewareError: boolean\n ): ToolMessage {\n /**\n * {@link NodeInterrupt} errors are a breakpoint to bring a human into the loop.\n * As such, they are not recoverable by the agent and shouldn't be fed\n * back. Instead, re-throw these errors even when `handleToolErrors = true`.\n */\n if (isGraphInterrupt(error)) {\n throw error;\n }\n\n /**\n * If the signal is aborted, we want to bubble up the error to the invoke caller.\n */\n if (this.signal?.aborted) {\n throw error;\n }\n\n /**\n * A recoverable tool error (e.g. tool-input schema validation) can be\n * rewrapped as a {@link MiddlewareError} with the original error on `.cause`\n * — once per `wrapToolCall` middleware, so it may be nested several layers\n * deep. Walk the cause chain to the root; if it's a {@link ToolInvocationError},\n * unwrap it so the intended `handleToolErrors` self-correction path still\n * applies. Genuine middleware errors stay fatal by default.\n */\n let effectiveError = error;\n let errorFromMiddleware = isMiddlewareError;\n if (isMiddlewareError) {\n let unwrapped: unknown = error;\n while (MiddlewareError.isInstance(unwrapped)) {\n unwrapped = unwrapped.cause;\n }\n if (ToolInvocationError.isInstance(unwrapped)) {\n effectiveError = unwrapped;\n errorFromMiddleware = false;\n }\n }\n\n /**\n * If error is from middleware and handleToolErrors is not true, bubble up\n * (default handler and false both re-raise middleware errors)\n */\n if (errorFromMiddleware && this.handleToolErrors !== true) {\n throw effectiveError;\n }\n\n /**\n * If handleToolErrors is false, throw all errors\n */\n if (!this.handleToolErrors) {\n throw effectiveError;\n }\n\n /**\n * Apply handleToolErrors to the error\n */\n if (typeof this.handleToolErrors === \"function\") {\n const result = this.handleToolErrors(effectiveError, call);\n if (result && ToolMessage.isInstance(result)) {\n return result;\n }\n\n /**\n * `handleToolErrors` returned undefined - re-raise\n */\n throw effectiveError;\n } else if (this.handleToolErrors) {\n return new ToolMessage({\n name: call.name,\n content: `${effectiveError}\\n Please fix your mistakes.`,\n tool_call_id: call.id!,\n });\n }\n\n /**\n * Shouldn't reach here, but throw as fallback\n */\n throw effectiveError;\n }\n\n protected async runTool(\n call: ToolCall,\n config: RunnableConfig,\n state: AgentBuiltInState\n ): Promise<ToolMessage | Command> {\n /**\n * Build runtime from LangGraph config\n */\n const lgConfig = config as LangGraphRunnableConfig;\n const runtime = {\n context: lgConfig?.context,\n store: lgConfig?.store,\n configurable: lgConfig?.configurable,\n writer: lgConfig?.writer,\n interrupt: lgConfig?.interrupt,\n signal: lgConfig?.signal,\n };\n\n /**\n * Find the tool instance to include in the request.\n * For dynamically registered tools, this may be undefined.\n */\n const registeredTool = this.tools.find((t) => t.name === call.name);\n\n /**\n * Define the base handler that executes the tool.\n * When wrapToolCall middleware is present, this handler does NOT catch errors\n * so the middleware can handle them.\n * When no middleware, errors are caught and handled here.\n *\n * The handler now accepts an overridden tool from the request, allowing\n * middleware to provide tool implementations for dynamically registered tools.\n */\n const baseHandler = async (\n request: ToolCallRequest\n ): Promise<ToolMessage | Command> => {\n const { toolCall, tool: requestTool } = request;\n\n /**\n * Use the tool from the request (which may be overridden via spread syntax)\n * or fall back to finding it in registered tools.\n * This allows middleware to provide dynamic tool implementations.\n */\n const tool =\n requestTool ?? this.tools.find((t) => t.name === toolCall.name);\n\n if (tool === undefined) {\n /**\n * Tool not found - return a graceful error message rather than throwing.\n * This allows the LLM to see the error and potentially retry.\n */\n const availableTools = this.tools.map((t) => t.name);\n return new ToolMessage({\n content: getInvalidToolError(toolCall.name, availableTools),\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\n });\n }\n\n /**\n * Cast tool to a common invokable type.\n * The tool can be from registered tools (StructuredToolInterface | DynamicTool | RunnableToolLike)\n * or from middleware override (ClientTool | ServerTool).\n */\n const invokableTool = tool as\n | StructuredToolInterface\n | DynamicTool\n | RunnableToolLike;\n\n try {\n const output = await invokableTool.invoke(\n { ...toolCall, type: \"tool_call\" },\n {\n ...config,\n /**\n * extend to match ToolRuntime\n */\n config,\n toolCallId: toolCall.id!,\n state: config.configurable?.__pregel_scratchpad?.currentTaskInput,\n signal: mergeAbortSignals(this.signal, config.signal),\n }\n );\n\n if (ToolMessage.isInstance(output) || isCommand(output)) {\n return output as ToolMessage | Command;\n }\n\n return new ToolMessage({\n name: invokableTool.name,\n content: typeof output === \"string\" ? output : JSON.stringify(output),\n tool_call_id: toolCall.id!,\n });\n } catch (e: unknown) {\n /**\n * Handle errors from tool execution (not from wrapToolCall)\n * If tool invocation fails due to input parsing error, throw a {@link ToolInvocationError}\n */\n if (e instanceof ToolInputParsingException) {\n throw new ToolInvocationError(e, toolCall);\n }\n /**\n * Re-throw to be handled by caller\n */\n throw e;\n }\n };\n\n /**\n * Create request object for middleware\n * Cast to ToolCallRequest<AgentBuiltInState> to satisfy type constraints\n * of wrapToolCall which expects AgentBuiltInState\n */\n const request: ToolCallRequest<AgentBuiltInState> = {\n toolCall: call,\n tool: registeredTool,\n state,\n runtime,\n };\n\n /**\n * If wrapToolCall is provided, use it to wrap the tool execution\n */\n if (this.wrapToolCall) {\n try {\n return await this.wrapToolCall(request, baseHandler);\n } catch (e: unknown) {\n /**\n * Handle middleware errors\n */\n return this.#handleError(e, call, true);\n }\n }\n\n /**\n * No wrapToolCall - if tool wasn't found, return graceful error\n */\n if (!registeredTool) {\n const availableTools = this.tools.map((t) => t.name);\n return new ToolMessage({\n content: getInvalidToolError(call.name, availableTools),\n tool_call_id: call.id!,\n name: call.name,\n status: \"error\",\n });\n }\n\n /**\n * No wrapToolCall - execute tool directly and handle errors here\n */\n try {\n return await baseHandler(request);\n } catch (e: unknown) {\n /**\n * Handle tool errors when no middleware provided\n */\n return this.#handleError(e, call, false);\n }\n }\n\n protected async run(\n state: ToAnnotationRoot<StateSchema>[\"State\"] & AgentBuiltInState,\n config: RunnableConfig\n ): Promise<ContextSchema> {\n let outputs: (ToolMessage | Command)[];\n\n if (isSendInput(state)) {\n const { lg_tool_call: _, jumpTo: __, ...newState } = state;\n outputs = [await this.runTool(state.lg_tool_call, config, newState)];\n } else {\n let messages: BaseMessage[];\n if (isBaseMessageArray(state)) {\n messages = state;\n } else if (isMessagesState(state)) {\n messages = state.messages;\n } else {\n throw new Error(\n \"ToolNode only accepts BaseMessage[] or { messages: BaseMessage[] } as input.\"\n );\n }\n\n const toolMessageIds: Set<string> = new Set(\n messages\n .filter((msg) => msg.getType() === \"tool\")\n .map((msg) => (msg as ToolMessage).tool_call_id)\n );\n\n let aiMessage: AIMessage | undefined;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (AIMessage.isInstance(message)) {\n aiMessage = message;\n break;\n }\n }\n\n if (!AIMessage.isInstance(aiMessage)) {\n throw new Error(\"ToolNode only accepts AIMessages as input.\");\n }\n\n outputs = await Promise.all(\n aiMessage.tool_calls\n ?.filter((call) => call.id == null || !toolMessageIds.has(call.id))\n .map((call) => this.runTool(call, config, state)) ?? []\n );\n }\n\n // Preserve existing behavior for non-command tool outputs for backwards compatibility\n if (!outputs.some(isCommand)) {\n return (Array.isArray(state)\n ? outputs\n : { messages: outputs }) as unknown as ContextSchema;\n }\n\n // Handle mixed Command and non-Command outputs\n const combinedOutputs: (\n | { messages: BaseMessage[] }\n | BaseMessage[]\n | Command\n )[] = [];\n let parentCommand: Command | null = null;\n\n for (const output of outputs) {\n if (isCommand(output)) {\n if (\n output.graph === Command.PARENT &&\n Array.isArray(output.goto) &&\n output.goto.every((send) => isSend(send))\n ) {\n if (parentCommand) {\n (parentCommand.goto as Send[]).push(...(output.goto as Send[]));\n } else {\n parentCommand = new Command({\n graph: Command.PARENT,\n goto: output.goto,\n });\n }\n } else {\n combinedOutputs.push(output);\n }\n } else {\n combinedOutputs.push(\n Array.isArray(state) ? [output] : { messages: [output] }\n );\n }\n }\n\n if (parentCommand) {\n combinedOutputs.push(parentCommand);\n }\n\n return combinedOutputs as unknown as ContextSchema;\n }\n}\n\nexport function isSend(x: unknown): x is Send {\n return x instanceof Send;\n}\n"],"mappings":"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"}
|
|
@@ -88,6 +88,7 @@ function defaultHandleToolErrors(error, toolCall) {
|
|
|
88
88
|
* ```
|
|
89
89
|
*/
|
|
90
90
|
var ToolNode = class extends RunnableCallable {
|
|
91
|
+
options;
|
|
91
92
|
tools;
|
|
92
93
|
trace = false;
|
|
93
94
|
signal;
|
|
@@ -343,6 +344,6 @@ function isSend(x) {
|
|
|
343
344
|
return x instanceof Send;
|
|
344
345
|
}
|
|
345
346
|
//#endregion
|
|
346
|
-
export { TOOLS_NODE_NAME, ToolNode };
|
|
347
|
+
export { TOOLS_NODE_NAME, ToolNode, isSend };
|
|
347
348
|
|
|
348
349
|
//# sourceMappingURL=ToolNode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolNode.js","names":["#handleError"],"sources":["../../../src/agents/nodes/ToolNode.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\n/* oxlint-disable no-instanceof/no-instanceof */\nimport { BaseMessage, ToolMessage, AIMessage } from \"@langchain/core/messages\";\nimport { RunnableConfig, RunnableToolLike } from \"@langchain/core/runnables\";\nimport {\n DynamicTool,\n StructuredToolInterface,\n ToolInputParsingException,\n} from \"@langchain/core/tools\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport type { InteropZodObject } from \"@langchain/core/utils/types\";\nimport {\n isCommand,\n Command,\n Send,\n isGraphInterrupt,\n type LangGraphRunnableConfig,\n StateDefinitionInit,\n} from \"@langchain/langgraph\";\n\nimport { RunnableCallable } from \"../RunnableCallable.js\";\nimport { mergeAbortSignals } from \"./utils.js\";\nimport { MiddlewareError, ToolInvocationError } from \"../errors.js\";\nimport type {\n WrapToolCallHook,\n ToolCallRequest,\n ToAnnotationRoot,\n} from \"../middleware/types.js\";\nimport type { AgentBuiltInState } from \"../runtime.js\";\n\n/**\n * Error message template for when middleware adds tools that can't be executed.\n * This happens when middleware modifies tools in wrapModelCall but doesn't provide\n * a wrapToolCall handler to execute them.\n */\nconst getInvalidToolError = (\n toolName: string,\n availableTools: string[]\n): string =>\n `Error: ${toolName} is not a valid tool, try one of [${availableTools.join(\", \")}].`;\n\n/**\n * The name of the tool node in the state graph.\n */\nexport const TOOLS_NODE_NAME = \"tools\";\n\nexport interface ToolNodeOptions {\n /**\n * The name of the tool node.\n */\n name?: string;\n /**\n * The tags to add to the tool call.\n */\n tags?: string[];\n /**\n * The abort signal to cancel the tool call.\n */\n signal?: AbortSignal;\n /**\n * Whether to throw the error immediately if the tool fails or handle it by the `onToolError` function or via ToolMessage.\n *\n * **Default behavior** (matches Python):\n * - Catches only `ToolInvocationError` (invalid arguments from model) and converts to ToolMessage\n * - Re-raises all other errors including errors from `wrapToolCall` middleware\n *\n * If `true`:\n * - Catches all errors and returns a ToolMessage with the error\n *\n * If `false`:\n * - All errors are thrown immediately\n *\n * If a function is provided:\n * - If function returns a `ToolMessage`, use it as the result\n * - If function returns `undefined`, re-raise the error\n *\n * @default A function that only catches ToolInvocationError\n */\n handleToolErrors?:\n | boolean\n | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined);\n /**\n * Optional wrapper function for tool execution.\n * Allows middleware to intercept and modify tool calls before execution.\n * The wrapper receives the tool call request and a handler function to execute the tool.\n */\n wrapToolCall?: WrapToolCallHook;\n}\n\nconst isBaseMessageArray = (input: unknown): input is BaseMessage[] =>\n Array.isArray(input) && input.every(BaseMessage.isInstance);\n\nconst isMessagesState = (\n input: unknown\n): input is { messages: BaseMessage[] } =>\n typeof input === \"object\" &&\n input != null &&\n \"messages\" in input &&\n isBaseMessageArray(input.messages);\n\nconst isSendInput = (\n input: unknown\n): input is { lg_tool_call: ToolCall; jumpTo?: string } =>\n typeof input === \"object\" && input != null && \"lg_tool_call\" in input;\n\n/**\n * Default error handler for tool errors.\n *\n * This is applied to errors from baseHandler (tool execution).\n * For errors from wrapToolCall middleware, those are handled separately\n * and will bubble up by default.\n *\n * Catches all tool execution errors and converts them to ToolMessage.\n * This allows the LLM to see the error and potentially retry with different arguments.\n */\nfunction defaultHandleToolErrors(\n error: unknown,\n toolCall: ToolCall\n): ToolMessage | undefined {\n if (ToolInvocationError.isInstance(error)) {\n return new ToolMessage({\n content: error.message,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n });\n }\n /**\n * Catch all other tool errors and convert to ToolMessage\n */\n return new ToolMessage({\n content: `${error}\\n Please fix your mistakes.`,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n });\n}\n\n/**\n * `ToolNode` is a built-in LangGraph component that handles tool calls within an agent's workflow.\n * It works seamlessly with `createAgent`, offering advanced tool execution control, built\n * in parallelism, and error handling.\n *\n * @example\n * ```ts\n * import { ToolNode, tool, AIMessage } from \"langchain\";\n * import { z } from \"zod/v3\";\n *\n * const getWeather = tool((input) => {\n * if ([\"sf\", \"san francisco\"].includes(input.location.toLowerCase())) {\n * return \"It's 60 degrees and foggy.\";\n * } else {\n * return \"It's 90 degrees and sunny.\";\n * }\n * }, {\n * name: \"get_weather\",\n * description: \"Call to get the current weather.\",\n * schema: z.object({\n * location: z.string().describe(\"Location to get the weather for.\"),\n * }),\n * });\n *\n * const tools = [getWeather];\n * const toolNode = new ToolNode(tools);\n *\n * const messageWithSingleToolCall = new AIMessage({\n * content: \"\",\n * tool_calls: [\n * {\n * name: \"get_weather\",\n * args: { location: \"sf\" },\n * id: \"tool_call_id\",\n * type: \"tool_call\",\n * }\n * ]\n * })\n *\n * await toolNode.invoke({ messages: [messageWithSingleToolCall] });\n * // Returns tool invocation responses as:\n * // { messages: ToolMessage[] }\n * ```\n */\nexport class ToolNode<\n StateSchema extends StateDefinitionInit = any,\n ContextSchema extends InteropZodObject = any,\n> extends RunnableCallable<StateSchema, ContextSchema> {\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[];\n\n trace = false;\n\n signal?: AbortSignal;\n\n handleToolErrors:\n | boolean\n | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined) =\n defaultHandleToolErrors;\n\n wrapToolCall: WrapToolCallHook | undefined;\n\n constructor(\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[],\n public options?: ToolNodeOptions\n ) {\n const { name, tags, handleToolErrors, signal, wrapToolCall } =\n options ?? {};\n super({\n name,\n tags,\n func: (state, config) =>\n this.run(\n state as ToAnnotationRoot<StateDefinitionInit>[\"State\"] &\n AgentBuiltInState,\n config as RunnableConfig\n ),\n });\n this.tools = tools;\n this.handleToolErrors = handleToolErrors ?? this.handleToolErrors;\n this.signal = signal;\n this.wrapToolCall = wrapToolCall;\n }\n\n /**\n * Handle errors from tool execution or middleware.\n * @param error - The error to handle\n * @param call - The tool call that caused the error\n * @param isMiddlewareError - Whether the error came from wrapToolCall middleware\n * @returns ToolMessage if error is handled, otherwise re-throws\n */\n #handleError(\n error: unknown,\n call: ToolCall,\n isMiddlewareError: boolean\n ): ToolMessage {\n /**\n * {@link NodeInterrupt} errors are a breakpoint to bring a human into the loop.\n * As such, they are not recoverable by the agent and shouldn't be fed\n * back. Instead, re-throw these errors even when `handleToolErrors = true`.\n */\n if (isGraphInterrupt(error)) {\n throw error;\n }\n\n /**\n * If the signal is aborted, we want to bubble up the error to the invoke caller.\n */\n if (this.signal?.aborted) {\n throw error;\n }\n\n /**\n * A recoverable tool error (e.g. tool-input schema validation) can be\n * rewrapped as a {@link MiddlewareError} with the original error on `.cause`\n * — once per `wrapToolCall` middleware, so it may be nested several layers\n * deep. Walk the cause chain to the root; if it's a {@link ToolInvocationError},\n * unwrap it so the intended `handleToolErrors` self-correction path still\n * applies. Genuine middleware errors stay fatal by default.\n */\n let effectiveError = error;\n let errorFromMiddleware = isMiddlewareError;\n if (isMiddlewareError) {\n let unwrapped: unknown = error;\n while (MiddlewareError.isInstance(unwrapped)) {\n unwrapped = unwrapped.cause;\n }\n if (ToolInvocationError.isInstance(unwrapped)) {\n effectiveError = unwrapped;\n errorFromMiddleware = false;\n }\n }\n\n /**\n * If error is from middleware and handleToolErrors is not true, bubble up\n * (default handler and false both re-raise middleware errors)\n */\n if (errorFromMiddleware && this.handleToolErrors !== true) {\n throw effectiveError;\n }\n\n /**\n * If handleToolErrors is false, throw all errors\n */\n if (!this.handleToolErrors) {\n throw effectiveError;\n }\n\n /**\n * Apply handleToolErrors to the error\n */\n if (typeof this.handleToolErrors === \"function\") {\n const result = this.handleToolErrors(effectiveError, call);\n if (result && ToolMessage.isInstance(result)) {\n return result;\n }\n\n /**\n * `handleToolErrors` returned undefined - re-raise\n */\n throw effectiveError;\n } else if (this.handleToolErrors) {\n return new ToolMessage({\n name: call.name,\n content: `${effectiveError}\\n Please fix your mistakes.`,\n tool_call_id: call.id!,\n });\n }\n\n /**\n * Shouldn't reach here, but throw as fallback\n */\n throw effectiveError;\n }\n\n protected async runTool(\n call: ToolCall,\n config: RunnableConfig,\n state: AgentBuiltInState\n ): Promise<ToolMessage | Command> {\n /**\n * Build runtime from LangGraph config\n */\n const lgConfig = config as LangGraphRunnableConfig;\n const runtime = {\n context: lgConfig?.context,\n store: lgConfig?.store,\n configurable: lgConfig?.configurable,\n writer: lgConfig?.writer,\n interrupt: lgConfig?.interrupt,\n signal: lgConfig?.signal,\n };\n\n /**\n * Find the tool instance to include in the request.\n * For dynamically registered tools, this may be undefined.\n */\n const registeredTool = this.tools.find((t) => t.name === call.name);\n\n /**\n * Define the base handler that executes the tool.\n * When wrapToolCall middleware is present, this handler does NOT catch errors\n * so the middleware can handle them.\n * When no middleware, errors are caught and handled here.\n *\n * The handler now accepts an overridden tool from the request, allowing\n * middleware to provide tool implementations for dynamically registered tools.\n */\n const baseHandler = async (\n request: ToolCallRequest\n ): Promise<ToolMessage | Command> => {\n const { toolCall, tool: requestTool } = request;\n\n /**\n * Use the tool from the request (which may be overridden via spread syntax)\n * or fall back to finding it in registered tools.\n * This allows middleware to provide dynamic tool implementations.\n */\n const tool =\n requestTool ?? this.tools.find((t) => t.name === toolCall.name);\n\n if (tool === undefined) {\n /**\n * Tool not found - return a graceful error message rather than throwing.\n * This allows the LLM to see the error and potentially retry.\n */\n const availableTools = this.tools.map((t) => t.name);\n return new ToolMessage({\n content: getInvalidToolError(toolCall.name, availableTools),\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\n });\n }\n\n /**\n * Cast tool to a common invokable type.\n * The tool can be from registered tools (StructuredToolInterface | DynamicTool | RunnableToolLike)\n * or from middleware override (ClientTool | ServerTool).\n */\n const invokableTool = tool as\n | StructuredToolInterface\n | DynamicTool\n | RunnableToolLike;\n\n try {\n const output = await invokableTool.invoke(\n { ...toolCall, type: \"tool_call\" },\n {\n ...config,\n /**\n * extend to match ToolRuntime\n */\n config,\n toolCallId: toolCall.id!,\n state: config.configurable?.__pregel_scratchpad?.currentTaskInput,\n signal: mergeAbortSignals(this.signal, config.signal),\n }\n );\n\n if (ToolMessage.isInstance(output) || isCommand(output)) {\n return output as ToolMessage | Command;\n }\n\n return new ToolMessage({\n name: invokableTool.name,\n content: typeof output === \"string\" ? output : JSON.stringify(output),\n tool_call_id: toolCall.id!,\n });\n } catch (e: unknown) {\n /**\n * Handle errors from tool execution (not from wrapToolCall)\n * If tool invocation fails due to input parsing error, throw a {@link ToolInvocationError}\n */\n if (e instanceof ToolInputParsingException) {\n throw new ToolInvocationError(e, toolCall);\n }\n /**\n * Re-throw to be handled by caller\n */\n throw e;\n }\n };\n\n /**\n * Create request object for middleware\n * Cast to ToolCallRequest<AgentBuiltInState> to satisfy type constraints\n * of wrapToolCall which expects AgentBuiltInState\n */\n const request: ToolCallRequest<AgentBuiltInState> = {\n toolCall: call,\n tool: registeredTool,\n state,\n runtime,\n };\n\n /**\n * If wrapToolCall is provided, use it to wrap the tool execution\n */\n if (this.wrapToolCall) {\n try {\n return await this.wrapToolCall(request, baseHandler);\n } catch (e: unknown) {\n /**\n * Handle middleware errors\n */\n return this.#handleError(e, call, true);\n }\n }\n\n /**\n * No wrapToolCall - if tool wasn't found, return graceful error\n */\n if (!registeredTool) {\n const availableTools = this.tools.map((t) => t.name);\n return new ToolMessage({\n content: getInvalidToolError(call.name, availableTools),\n tool_call_id: call.id!,\n name: call.name,\n status: \"error\",\n });\n }\n\n /**\n * No wrapToolCall - execute tool directly and handle errors here\n */\n try {\n return await baseHandler(request);\n } catch (e: unknown) {\n /**\n * Handle tool errors when no middleware provided\n */\n return this.#handleError(e, call, false);\n }\n }\n\n protected async run(\n state: ToAnnotationRoot<StateSchema>[\"State\"] & AgentBuiltInState,\n config: RunnableConfig\n ): Promise<ContextSchema> {\n let outputs: (ToolMessage | Command)[];\n\n if (isSendInput(state)) {\n const { lg_tool_call: _, jumpTo: __, ...newState } = state;\n outputs = [await this.runTool(state.lg_tool_call, config, newState)];\n } else {\n let messages: BaseMessage[];\n if (isBaseMessageArray(state)) {\n messages = state;\n } else if (isMessagesState(state)) {\n messages = state.messages;\n } else {\n throw new Error(\n \"ToolNode only accepts BaseMessage[] or { messages: BaseMessage[] } as input.\"\n );\n }\n\n const toolMessageIds: Set<string> = new Set(\n messages\n .filter((msg) => msg.getType() === \"tool\")\n .map((msg) => (msg as ToolMessage).tool_call_id)\n );\n\n let aiMessage: AIMessage | undefined;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (AIMessage.isInstance(message)) {\n aiMessage = message;\n break;\n }\n }\n\n if (!AIMessage.isInstance(aiMessage)) {\n throw new Error(\"ToolNode only accepts AIMessages as input.\");\n }\n\n outputs = await Promise.all(\n aiMessage.tool_calls\n ?.filter((call) => call.id == null || !toolMessageIds.has(call.id))\n .map((call) => this.runTool(call, config, state)) ?? []\n );\n }\n\n // Preserve existing behavior for non-command tool outputs for backwards compatibility\n if (!outputs.some(isCommand)) {\n return (Array.isArray(state)\n ? outputs\n : { messages: outputs }) as unknown as ContextSchema;\n }\n\n // Handle mixed Command and non-Command outputs\n const combinedOutputs: (\n | { messages: BaseMessage[] }\n | BaseMessage[]\n | Command\n )[] = [];\n let parentCommand: Command | null = null;\n\n for (const output of outputs) {\n if (isCommand(output)) {\n if (\n output.graph === Command.PARENT &&\n Array.isArray(output.goto) &&\n output.goto.every((send) => isSend(send))\n ) {\n if (parentCommand) {\n (parentCommand.goto as Send[]).push(...(output.goto as Send[]));\n } else {\n parentCommand = new Command({\n graph: Command.PARENT,\n goto: output.goto,\n });\n }\n } else {\n combinedOutputs.push(output);\n }\n } else {\n combinedOutputs.push(\n Array.isArray(state) ? [output] : { messages: [output] }\n );\n }\n }\n\n if (parentCommand) {\n combinedOutputs.push(parentCommand);\n }\n\n return combinedOutputs as unknown as ContextSchema;\n }\n}\n\nexport function isSend(x: unknown): x is Send {\n return x instanceof Send;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ToolNode.js","names":["#handleError"],"sources":["../../../src/agents/nodes/ToolNode.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\n/* oxlint-disable no-instanceof/no-instanceof */\nimport { BaseMessage, ToolMessage, AIMessage } from \"@langchain/core/messages\";\nimport { RunnableConfig, RunnableToolLike } from \"@langchain/core/runnables\";\nimport {\n DynamicTool,\n StructuredToolInterface,\n ToolInputParsingException,\n} from \"@langchain/core/tools\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport type { InteropZodObject } from \"@langchain/core/utils/types\";\nimport {\n isCommand,\n Command,\n Send,\n isGraphInterrupt,\n type LangGraphRunnableConfig,\n StateDefinitionInit,\n} from \"@langchain/langgraph\";\n\nimport { RunnableCallable } from \"../RunnableCallable.js\";\nimport { mergeAbortSignals } from \"./utils.js\";\nimport { MiddlewareError, ToolInvocationError } from \"../errors.js\";\nimport type {\n WrapToolCallHook,\n ToolCallRequest,\n ToAnnotationRoot,\n} from \"../middleware/types.js\";\nimport type { AgentBuiltInState } from \"../runtime.js\";\n\n/**\n * Error message template for when middleware adds tools that can't be executed.\n * This happens when middleware modifies tools in wrapModelCall but doesn't provide\n * a wrapToolCall handler to execute them.\n */\nconst getInvalidToolError = (\n toolName: string,\n availableTools: string[]\n): string =>\n `Error: ${toolName} is not a valid tool, try one of [${availableTools.join(\", \")}].`;\n\n/**\n * The name of the tool node in the state graph.\n */\nexport const TOOLS_NODE_NAME = \"tools\";\n\nexport interface ToolNodeOptions {\n /**\n * The name of the tool node.\n */\n name?: string;\n /**\n * The tags to add to the tool call.\n */\n tags?: string[];\n /**\n * The abort signal to cancel the tool call.\n */\n signal?: AbortSignal;\n /**\n * Whether to throw the error immediately if the tool fails or handle it by the `onToolError` function or via ToolMessage.\n *\n * **Default behavior** (matches Python):\n * - Catches only `ToolInvocationError` (invalid arguments from model) and converts to ToolMessage\n * - Re-raises all other errors including errors from `wrapToolCall` middleware\n *\n * If `true`:\n * - Catches all errors and returns a ToolMessage with the error\n *\n * If `false`:\n * - All errors are thrown immediately\n *\n * If a function is provided:\n * - If function returns a `ToolMessage`, use it as the result\n * - If function returns `undefined`, re-raise the error\n *\n * @default A function that only catches ToolInvocationError\n */\n handleToolErrors?:\n | boolean\n | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined);\n /**\n * Optional wrapper function for tool execution.\n * Allows middleware to intercept and modify tool calls before execution.\n * The wrapper receives the tool call request and a handler function to execute the tool.\n */\n wrapToolCall?: WrapToolCallHook;\n}\n\nconst isBaseMessageArray = (input: unknown): input is BaseMessage[] =>\n Array.isArray(input) && input.every(BaseMessage.isInstance);\n\nconst isMessagesState = (\n input: unknown\n): input is { messages: BaseMessage[] } =>\n typeof input === \"object\" &&\n input != null &&\n \"messages\" in input &&\n isBaseMessageArray(input.messages);\n\nconst isSendInput = (\n input: unknown\n): input is { lg_tool_call: ToolCall; jumpTo?: string } =>\n typeof input === \"object\" && input != null && \"lg_tool_call\" in input;\n\n/**\n * Default error handler for tool errors.\n *\n * This is applied to errors from baseHandler (tool execution).\n * For errors from wrapToolCall middleware, those are handled separately\n * and will bubble up by default.\n *\n * Catches all tool execution errors and converts them to ToolMessage.\n * This allows the LLM to see the error and potentially retry with different arguments.\n */\nfunction defaultHandleToolErrors(\n error: unknown,\n toolCall: ToolCall\n): ToolMessage | undefined {\n if (ToolInvocationError.isInstance(error)) {\n return new ToolMessage({\n content: error.message,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n });\n }\n /**\n * Catch all other tool errors and convert to ToolMessage\n */\n return new ToolMessage({\n content: `${error}\\n Please fix your mistakes.`,\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n });\n}\n\n/**\n * `ToolNode` is a built-in LangGraph component that handles tool calls within an agent's workflow.\n * It works seamlessly with `createAgent`, offering advanced tool execution control, built\n * in parallelism, and error handling.\n *\n * @example\n * ```ts\n * import { ToolNode, tool, AIMessage } from \"langchain\";\n * import { z } from \"zod/v3\";\n *\n * const getWeather = tool((input) => {\n * if ([\"sf\", \"san francisco\"].includes(input.location.toLowerCase())) {\n * return \"It's 60 degrees and foggy.\";\n * } else {\n * return \"It's 90 degrees and sunny.\";\n * }\n * }, {\n * name: \"get_weather\",\n * description: \"Call to get the current weather.\",\n * schema: z.object({\n * location: z.string().describe(\"Location to get the weather for.\"),\n * }),\n * });\n *\n * const tools = [getWeather];\n * const toolNode = new ToolNode(tools);\n *\n * const messageWithSingleToolCall = new AIMessage({\n * content: \"\",\n * tool_calls: [\n * {\n * name: \"get_weather\",\n * args: { location: \"sf\" },\n * id: \"tool_call_id\",\n * type: \"tool_call\",\n * }\n * ]\n * })\n *\n * await toolNode.invoke({ messages: [messageWithSingleToolCall] });\n * // Returns tool invocation responses as:\n * // { messages: ToolMessage[] }\n * ```\n */\nexport class ToolNode<\n StateSchema extends StateDefinitionInit = any,\n ContextSchema extends InteropZodObject = any,\n> extends RunnableCallable<StateSchema, ContextSchema> {\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[];\n\n trace = false;\n\n signal?: AbortSignal;\n\n handleToolErrors:\n | boolean\n | ((error: unknown, toolCall: ToolCall) => ToolMessage | undefined) =\n defaultHandleToolErrors;\n\n wrapToolCall: WrapToolCallHook | undefined;\n\n constructor(\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[],\n public options?: ToolNodeOptions\n ) {\n const { name, tags, handleToolErrors, signal, wrapToolCall } =\n options ?? {};\n super({\n name,\n tags,\n func: (state, config) =>\n this.run(\n state as ToAnnotationRoot<StateDefinitionInit>[\"State\"] &\n AgentBuiltInState,\n config as RunnableConfig\n ),\n });\n this.tools = tools;\n this.handleToolErrors = handleToolErrors ?? this.handleToolErrors;\n this.signal = signal;\n this.wrapToolCall = wrapToolCall;\n }\n\n /**\n * Handle errors from tool execution or middleware.\n * @param error - The error to handle\n * @param call - The tool call that caused the error\n * @param isMiddlewareError - Whether the error came from wrapToolCall middleware\n * @returns ToolMessage if error is handled, otherwise re-throws\n */\n #handleError(\n error: unknown,\n call: ToolCall,\n isMiddlewareError: boolean\n ): ToolMessage {\n /**\n * {@link NodeInterrupt} errors are a breakpoint to bring a human into the loop.\n * As such, they are not recoverable by the agent and shouldn't be fed\n * back. Instead, re-throw these errors even when `handleToolErrors = true`.\n */\n if (isGraphInterrupt(error)) {\n throw error;\n }\n\n /**\n * If the signal is aborted, we want to bubble up the error to the invoke caller.\n */\n if (this.signal?.aborted) {\n throw error;\n }\n\n /**\n * A recoverable tool error (e.g. tool-input schema validation) can be\n * rewrapped as a {@link MiddlewareError} with the original error on `.cause`\n * — once per `wrapToolCall` middleware, so it may be nested several layers\n * deep. Walk the cause chain to the root; if it's a {@link ToolInvocationError},\n * unwrap it so the intended `handleToolErrors` self-correction path still\n * applies. Genuine middleware errors stay fatal by default.\n */\n let effectiveError = error;\n let errorFromMiddleware = isMiddlewareError;\n if (isMiddlewareError) {\n let unwrapped: unknown = error;\n while (MiddlewareError.isInstance(unwrapped)) {\n unwrapped = unwrapped.cause;\n }\n if (ToolInvocationError.isInstance(unwrapped)) {\n effectiveError = unwrapped;\n errorFromMiddleware = false;\n }\n }\n\n /**\n * If error is from middleware and handleToolErrors is not true, bubble up\n * (default handler and false both re-raise middleware errors)\n */\n if (errorFromMiddleware && this.handleToolErrors !== true) {\n throw effectiveError;\n }\n\n /**\n * If handleToolErrors is false, throw all errors\n */\n if (!this.handleToolErrors) {\n throw effectiveError;\n }\n\n /**\n * Apply handleToolErrors to the error\n */\n if (typeof this.handleToolErrors === \"function\") {\n const result = this.handleToolErrors(effectiveError, call);\n if (result && ToolMessage.isInstance(result)) {\n return result;\n }\n\n /**\n * `handleToolErrors` returned undefined - re-raise\n */\n throw effectiveError;\n } else if (this.handleToolErrors) {\n return new ToolMessage({\n name: call.name,\n content: `${effectiveError}\\n Please fix your mistakes.`,\n tool_call_id: call.id!,\n });\n }\n\n /**\n * Shouldn't reach here, but throw as fallback\n */\n throw effectiveError;\n }\n\n protected async runTool(\n call: ToolCall,\n config: RunnableConfig,\n state: AgentBuiltInState\n ): Promise<ToolMessage | Command> {\n /**\n * Build runtime from LangGraph config\n */\n const lgConfig = config as LangGraphRunnableConfig;\n const runtime = {\n context: lgConfig?.context,\n store: lgConfig?.store,\n configurable: lgConfig?.configurable,\n writer: lgConfig?.writer,\n interrupt: lgConfig?.interrupt,\n signal: lgConfig?.signal,\n };\n\n /**\n * Find the tool instance to include in the request.\n * For dynamically registered tools, this may be undefined.\n */\n const registeredTool = this.tools.find((t) => t.name === call.name);\n\n /**\n * Define the base handler that executes the tool.\n * When wrapToolCall middleware is present, this handler does NOT catch errors\n * so the middleware can handle them.\n * When no middleware, errors are caught and handled here.\n *\n * The handler now accepts an overridden tool from the request, allowing\n * middleware to provide tool implementations for dynamically registered tools.\n */\n const baseHandler = async (\n request: ToolCallRequest\n ): Promise<ToolMessage | Command> => {\n const { toolCall, tool: requestTool } = request;\n\n /**\n * Use the tool from the request (which may be overridden via spread syntax)\n * or fall back to finding it in registered tools.\n * This allows middleware to provide dynamic tool implementations.\n */\n const tool =\n requestTool ?? this.tools.find((t) => t.name === toolCall.name);\n\n if (tool === undefined) {\n /**\n * Tool not found - return a graceful error message rather than throwing.\n * This allows the LLM to see the error and potentially retry.\n */\n const availableTools = this.tools.map((t) => t.name);\n return new ToolMessage({\n content: getInvalidToolError(toolCall.name, availableTools),\n tool_call_id: toolCall.id!,\n name: toolCall.name,\n status: \"error\",\n });\n }\n\n /**\n * Cast tool to a common invokable type.\n * The tool can be from registered tools (StructuredToolInterface | DynamicTool | RunnableToolLike)\n * or from middleware override (ClientTool | ServerTool).\n */\n const invokableTool = tool as\n | StructuredToolInterface\n | DynamicTool\n | RunnableToolLike;\n\n try {\n const output = await invokableTool.invoke(\n { ...toolCall, type: \"tool_call\" },\n {\n ...config,\n /**\n * extend to match ToolRuntime\n */\n config,\n toolCallId: toolCall.id!,\n state: config.configurable?.__pregel_scratchpad?.currentTaskInput,\n signal: mergeAbortSignals(this.signal, config.signal),\n }\n );\n\n if (ToolMessage.isInstance(output) || isCommand(output)) {\n return output as ToolMessage | Command;\n }\n\n return new ToolMessage({\n name: invokableTool.name,\n content: typeof output === \"string\" ? output : JSON.stringify(output),\n tool_call_id: toolCall.id!,\n });\n } catch (e: unknown) {\n /**\n * Handle errors from tool execution (not from wrapToolCall)\n * If tool invocation fails due to input parsing error, throw a {@link ToolInvocationError}\n */\n if (e instanceof ToolInputParsingException) {\n throw new ToolInvocationError(e, toolCall);\n }\n /**\n * Re-throw to be handled by caller\n */\n throw e;\n }\n };\n\n /**\n * Create request object for middleware\n * Cast to ToolCallRequest<AgentBuiltInState> to satisfy type constraints\n * of wrapToolCall which expects AgentBuiltInState\n */\n const request: ToolCallRequest<AgentBuiltInState> = {\n toolCall: call,\n tool: registeredTool,\n state,\n runtime,\n };\n\n /**\n * If wrapToolCall is provided, use it to wrap the tool execution\n */\n if (this.wrapToolCall) {\n try {\n return await this.wrapToolCall(request, baseHandler);\n } catch (e: unknown) {\n /**\n * Handle middleware errors\n */\n return this.#handleError(e, call, true);\n }\n }\n\n /**\n * No wrapToolCall - if tool wasn't found, return graceful error\n */\n if (!registeredTool) {\n const availableTools = this.tools.map((t) => t.name);\n return new ToolMessage({\n content: getInvalidToolError(call.name, availableTools),\n tool_call_id: call.id!,\n name: call.name,\n status: \"error\",\n });\n }\n\n /**\n * No wrapToolCall - execute tool directly and handle errors here\n */\n try {\n return await baseHandler(request);\n } catch (e: unknown) {\n /**\n * Handle tool errors when no middleware provided\n */\n return this.#handleError(e, call, false);\n }\n }\n\n protected async run(\n state: ToAnnotationRoot<StateSchema>[\"State\"] & AgentBuiltInState,\n config: RunnableConfig\n ): Promise<ContextSchema> {\n let outputs: (ToolMessage | Command)[];\n\n if (isSendInput(state)) {\n const { lg_tool_call: _, jumpTo: __, ...newState } = state;\n outputs = [await this.runTool(state.lg_tool_call, config, newState)];\n } else {\n let messages: BaseMessage[];\n if (isBaseMessageArray(state)) {\n messages = state;\n } else if (isMessagesState(state)) {\n messages = state.messages;\n } else {\n throw new Error(\n \"ToolNode only accepts BaseMessage[] or { messages: BaseMessage[] } as input.\"\n );\n }\n\n const toolMessageIds: Set<string> = new Set(\n messages\n .filter((msg) => msg.getType() === \"tool\")\n .map((msg) => (msg as ToolMessage).tool_call_id)\n );\n\n let aiMessage: AIMessage | undefined;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (AIMessage.isInstance(message)) {\n aiMessage = message;\n break;\n }\n }\n\n if (!AIMessage.isInstance(aiMessage)) {\n throw new Error(\"ToolNode only accepts AIMessages as input.\");\n }\n\n outputs = await Promise.all(\n aiMessage.tool_calls\n ?.filter((call) => call.id == null || !toolMessageIds.has(call.id))\n .map((call) => this.runTool(call, config, state)) ?? []\n );\n }\n\n // Preserve existing behavior for non-command tool outputs for backwards compatibility\n if (!outputs.some(isCommand)) {\n return (Array.isArray(state)\n ? outputs\n : { messages: outputs }) as unknown as ContextSchema;\n }\n\n // Handle mixed Command and non-Command outputs\n const combinedOutputs: (\n | { messages: BaseMessage[] }\n | BaseMessage[]\n | Command\n )[] = [];\n let parentCommand: Command | null = null;\n\n for (const output of outputs) {\n if (isCommand(output)) {\n if (\n output.graph === Command.PARENT &&\n Array.isArray(output.goto) &&\n output.goto.every((send) => isSend(send))\n ) {\n if (parentCommand) {\n (parentCommand.goto as Send[]).push(...(output.goto as Send[]));\n } else {\n parentCommand = new Command({\n graph: Command.PARENT,\n goto: output.goto,\n });\n }\n } else {\n combinedOutputs.push(output);\n }\n } else {\n combinedOutputs.push(\n Array.isArray(state) ? [output] : { messages: [output] }\n );\n }\n }\n\n if (parentCommand) {\n combinedOutputs.push(parentCommand);\n }\n\n return combinedOutputs as unknown as ContextSchema;\n }\n}\n\nexport function isSend(x: unknown): x is Send {\n return x instanceof Send;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.cjs","names":["RunnableCallable","getHookConstraint","derivePrivateState"],"sources":["../../../src/agents/nodes/middleware.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { LangGraphRunnableConfig, Command } from \"@langchain/langgraph\";\nimport {\n getInteropZodObjectShape,\n interopParse,\n isInteropZodObject,\n} from \"@langchain/core/utils/types\";\n\nimport { RunnableCallable, RunnableCallableArgs } from \"../RunnableCallable.js\";\nimport type { JumpToTarget } from \"../constants.js\";\nimport type { Runtime } from \"../runtime.js\";\nimport type {\n AnyAgentMiddleware,\n MiddlewareResult,\n} from \"../middleware/types.js\";\nimport { derivePrivateState } from \"./utils.js\";\nimport { getHookConstraint } from \"../middleware/utils.js\";\n\n/**\n * Named class for context objects to provide better error messages\n */\nclass AgentContext {}\nclass AgentRuntime {}\n\ntype NodeOutput<TStateSchema extends Record<string, any>> =\n | TStateSchema\n | Command<any, TStateSchema, string>\n | { jumpTo?: JumpToTarget };\n\nexport abstract class MiddlewareNode<\n TStateSchema extends Record<string, any>,\n TContextSchema extends Record<string, any>,\n> extends RunnableCallable<TStateSchema, NodeOutput<TStateSchema>> {\n abstract middleware: AnyAgentMiddleware;\n\n constructor(\n fields: RunnableCallableArgs<TStateSchema, NodeOutput<TStateSchema>>\n ) {\n super(fields);\n }\n\n abstract runHook(\n state: TStateSchema,\n config?: Runtime<TContextSchema>\n ): Promise<MiddlewareResult<TStateSchema>> | MiddlewareResult<TStateSchema>;\n\n async invokeMiddleware(\n invokeState: TStateSchema,\n config?: LangGraphRunnableConfig\n ): Promise<NodeOutput<TStateSchema>> {\n /**\n * Filter context based on middleware's contextSchema\n */\n let filteredContext = {} as TContextSchema;\n /**\n * Parse context using middleware's contextSchema to apply defaults and validation\n */\n if (\n this.middleware.contextSchema &&\n isInteropZodObject(this.middleware.contextSchema)\n ) {\n /**\n * Extract only the fields relevant to this middleware's schema\n */\n const schemaShape = getInteropZodObjectShape(\n this.middleware.contextSchema\n );\n if (schemaShape) {\n const relevantContext: Record<string, unknown> = {};\n const invokeContext = config?.context || {};\n for (const key of Object.keys(schemaShape)) {\n if (key in invokeContext) {\n relevantContext[key] = invokeContext[key];\n }\n }\n /**\n * Parse to apply defaults and validation, even if relevantContext is empty\n * This will throw if required fields are missing and no defaults exist\n */\n filteredContext = interopParse(\n this.middleware.contextSchema,\n relevantContext\n ) as TContextSchema;\n }\n }\n\n const state: TStateSchema = {\n ...invokeState,\n /**\n * don't overwrite possible outdated messages from other middleware nodes\n */\n messages: invokeState.messages,\n };\n\n const runtime: Runtime<TContextSchema> = {\n context: filteredContext,\n store: config?.store,\n configurable: config?.configurable,\n writer: config?.writer,\n interrupt: config?.interrupt,\n signal: config?.signal,\n };\n\n const result = await this.runHook(\n state,\n /**\n * assign runtime and context values into empty named class\n * instances to create a better error message.\n */\n Object.freeze(\n Object.assign(new AgentRuntime(), {\n ...runtime,\n context: Object.freeze(\n Object.assign(new AgentContext(), filteredContext)\n ),\n })\n )\n );\n\n /**\n * If result is undefined, the hook made no state changes — return\n * only the jumpTo sentinel so we don't re-emit every input key as\n * a state update.\n */\n if (!result) {\n return { jumpTo: undefined };\n }\n\n /**\n * Verify that the jump target is allowed for the middleware\n */\n let jumpToConstraint: JumpToTarget[] | undefined;\n let constraint: string | undefined;\n\n if (this.name?.startsWith(\"BeforeAgentNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.beforeAgent);\n constraint = \"beforeAgent.canJumpTo\";\n } else if (this.name?.startsWith(\"BeforeModelNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.beforeModel);\n constraint = \"beforeModel.canJumpTo\";\n } else if (this.name?.startsWith(\"AfterAgentNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.afterAgent);\n constraint = \"afterAgent.canJumpTo\";\n } else if (this.name?.startsWith(\"AfterModelNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.afterModel);\n constraint = \"afterModel.canJumpTo\";\n }\n\n if (\n typeof result.jumpTo === \"string\" &&\n !jumpToConstraint?.includes(result.jumpTo as JumpToTarget)\n ) {\n const suggestion =\n jumpToConstraint && jumpToConstraint.length > 0\n ? `must be one of: ${jumpToConstraint?.join(\", \")}.`\n : constraint\n ? `no ${constraint} defined in middleware ${this.middleware.name}`\n : \"\";\n throw new Error(`Invalid jump target: ${result.jumpTo}, ${suggestion}.`);\n }\n\n /**\n * If result is a control action, handle it\n */\n if (typeof result === \"object\" && \"type\" in result) {\n // Handle control actions\n if (result.type === \"terminate\") {\n if (result.error) {\n throw result.error;\n }\n return {\n ...state,\n ...(result.result || {}),\n jumpTo: result.jumpTo,\n };\n }\n\n throw new Error(`Invalid control action: ${JSON.stringify(result)}`);\n }\n\n /**\n * If result is a state update, merge it with current state\n */\n return { ...state, ...result, jumpTo: result.jumpTo };\n }\n\n get nodeOptions() {\n return {\n input: derivePrivateState(this.middleware.stateSchema),\n };\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"middleware.cjs","names":["RunnableCallable","getHookConstraint","derivePrivateState"],"sources":["../../../src/agents/nodes/middleware.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { LangGraphRunnableConfig, Command } from \"@langchain/langgraph\";\nimport {\n getInteropZodObjectShape,\n interopParse,\n isInteropZodObject,\n} from \"@langchain/core/utils/types\";\n\nimport { RunnableCallable, RunnableCallableArgs } from \"../RunnableCallable.js\";\nimport type { JumpToTarget } from \"../constants.js\";\nimport type { Runtime } from \"../runtime.js\";\nimport type {\n AnyAgentMiddleware,\n MiddlewareResult,\n} from \"../middleware/types.js\";\nimport { derivePrivateState } from \"./utils.js\";\nimport { getHookConstraint } from \"../middleware/utils.js\";\n\n/**\n * Named class for context objects to provide better error messages\n */\nclass AgentContext {}\nclass AgentRuntime {}\n\ntype NodeOutput<TStateSchema extends Record<string, any>> =\n | TStateSchema\n | Command<any, TStateSchema, string>\n | { jumpTo?: JumpToTarget };\n\nexport abstract class MiddlewareNode<\n TStateSchema extends Record<string, any>,\n TContextSchema extends Record<string, any>,\n> extends RunnableCallable<TStateSchema, NodeOutput<TStateSchema>> {\n abstract middleware: AnyAgentMiddleware;\n\n constructor(\n fields: RunnableCallableArgs<TStateSchema, NodeOutput<TStateSchema>>\n ) {\n super(fields);\n }\n\n abstract runHook(\n state: TStateSchema,\n config?: Runtime<TContextSchema>\n ): Promise<MiddlewareResult<TStateSchema>> | MiddlewareResult<TStateSchema>;\n\n async invokeMiddleware(\n invokeState: TStateSchema,\n config?: LangGraphRunnableConfig\n ): Promise<NodeOutput<TStateSchema>> {\n /**\n * Filter context based on middleware's contextSchema\n */\n let filteredContext = {} as TContextSchema;\n /**\n * Parse context using middleware's contextSchema to apply defaults and validation\n */\n if (\n this.middleware.contextSchema &&\n isInteropZodObject(this.middleware.contextSchema)\n ) {\n /**\n * Extract only the fields relevant to this middleware's schema\n */\n const schemaShape = getInteropZodObjectShape(\n this.middleware.contextSchema\n );\n if (schemaShape) {\n const relevantContext: Record<string, unknown> = {};\n const invokeContext = config?.context || {};\n for (const key of Object.keys(schemaShape)) {\n if (key in invokeContext) {\n relevantContext[key] = invokeContext[key];\n }\n }\n /**\n * Parse to apply defaults and validation, even if relevantContext is empty\n * This will throw if required fields are missing and no defaults exist\n */\n filteredContext = interopParse(\n this.middleware.contextSchema,\n relevantContext\n ) as TContextSchema;\n }\n }\n\n const state: TStateSchema = {\n ...invokeState,\n /**\n * don't overwrite possible outdated messages from other middleware nodes\n */\n messages: invokeState.messages,\n };\n\n const runtime: Runtime<TContextSchema> = {\n context: filteredContext,\n store: config?.store,\n configurable: config?.configurable,\n writer: config?.writer,\n interrupt: config?.interrupt,\n signal: config?.signal,\n };\n\n const result = await this.runHook(\n state,\n /**\n * assign runtime and context values into empty named class\n * instances to create a better error message.\n */\n Object.freeze(\n Object.assign(new AgentRuntime(), {\n ...runtime,\n context: Object.freeze(\n Object.assign(new AgentContext(), filteredContext)\n ),\n })\n )\n );\n\n /**\n * If result is undefined, the hook made no state changes — return\n * only the jumpTo sentinel so we don't re-emit every input key as\n * a state update.\n */\n if (!result) {\n return { jumpTo: undefined };\n }\n\n /**\n * Verify that the jump target is allowed for the middleware\n */\n let jumpToConstraint: JumpToTarget[] | undefined;\n let constraint: string | undefined;\n\n if (this.name?.startsWith(\"BeforeAgentNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.beforeAgent);\n constraint = \"beforeAgent.canJumpTo\";\n } else if (this.name?.startsWith(\"BeforeModelNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.beforeModel);\n constraint = \"beforeModel.canJumpTo\";\n } else if (this.name?.startsWith(\"AfterAgentNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.afterAgent);\n constraint = \"afterAgent.canJumpTo\";\n } else if (this.name?.startsWith(\"AfterModelNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.afterModel);\n constraint = \"afterModel.canJumpTo\";\n }\n\n if (\n typeof result.jumpTo === \"string\" &&\n !jumpToConstraint?.includes(result.jumpTo as JumpToTarget)\n ) {\n const suggestion =\n jumpToConstraint && jumpToConstraint.length > 0\n ? `must be one of: ${jumpToConstraint?.join(\", \")}.`\n : constraint\n ? `no ${constraint} defined in middleware ${this.middleware.name}`\n : \"\";\n throw new Error(`Invalid jump target: ${result.jumpTo}, ${suggestion}.`);\n }\n\n /**\n * If result is a control action, handle it\n */\n if (typeof result === \"object\" && \"type\" in result) {\n // Handle control actions\n if (result.type === \"terminate\") {\n if (result.error) {\n throw result.error;\n }\n return {\n ...state,\n ...(result.result || {}),\n jumpTo: result.jumpTo,\n };\n }\n\n throw new Error(`Invalid control action: ${JSON.stringify(result)}`);\n }\n\n /**\n * If result is a state update, merge it with current state\n */\n return { ...state, ...result, jumpTo: result.jumpTo };\n }\n\n get nodeOptions() {\n return {\n input: derivePrivateState(this.middleware.stateSchema),\n };\n }\n}\n"],"mappings":";;;;;;;;AAqBA,IAAM,eAAN,MAAmB,CAAC;AACpB,IAAM,eAAN,MAAmB,CAAC;AAOpB,IAAsB,iBAAtB,cAGUA,yBAAAA,iBAAyD;CAGjE,YACE,QACA;EACA,MAAM,MAAM;CACd;CAOA,MAAM,iBACJ,aACA,QACmC;;;;EAInC,IAAI,kBAAkB,CAAC;;;;EAIvB,IACE,KAAK,WAAW,kBAAA,GAAA,4BAAA,mBAAA,CACG,KAAK,WAAW,aAAa,GAChD;;;;GAIA,MAAM,eAAA,GAAA,4BAAA,yBAAA,CACJ,KAAK,WAAW,aAClB;GACA,IAAI,aAAa;IACf,MAAM,kBAA2C,CAAC;IAClD,MAAM,gBAAgB,QAAQ,WAAW,CAAC;IAC1C,KAAK,MAAM,OAAO,OAAO,KAAK,WAAW,GACvC,IAAI,OAAO,eACT,gBAAgB,OAAO,cAAc;;;;;IAOzC,mBAAA,GAAA,4BAAA,aAAA,CACE,KAAK,WAAW,eAChB,eACF;GACF;EACF;EAEA,MAAM,QAAsB;GAC1B,GAAG;;;;GAIH,UAAU,YAAY;EACxB;EAEA,MAAM,UAAmC;GACvC,SAAS;GACT,OAAO,QAAQ;GACf,cAAc,QAAQ;GACtB,QAAQ,QAAQ;GAChB,WAAW,QAAQ;GACnB,QAAQ,QAAQ;EAClB;EAEA,MAAM,SAAS,MAAM,KAAK;GACxB;;;;;GAKA,OAAO,OACL,OAAO,OAAO,IAAI,aAAa,GAAG;IAChC,GAAG;IACH,SAAS,OAAO,OACd,OAAO,OAAO,IAAI,aAAa,GAAG,eAAe,CACnD;GACF,CAAC,CACH;EACF;;;;;;EAOA,IAAI,CAAC,QACH,OAAO,EAAE,QAAQ,KAAA,EAAU;;;;EAM7B,IAAI;EACJ,IAAI;EAEJ,IAAI,KAAK,MAAM,WAAW,kBAAkB,GAAG;GAC7C,mBAAmBC,gBAAAA,kBAAkB,KAAK,WAAW,WAAW;GAChE,aAAa;EACf,OAAO,IAAI,KAAK,MAAM,WAAW,kBAAkB,GAAG;GACpD,mBAAmBA,gBAAAA,kBAAkB,KAAK,WAAW,WAAW;GAChE,aAAa;EACf,OAAO,IAAI,KAAK,MAAM,WAAW,iBAAiB,GAAG;GACnD,mBAAmBA,gBAAAA,kBAAkB,KAAK,WAAW,UAAU;GAC/D,aAAa;EACf,OAAO,IAAI,KAAK,MAAM,WAAW,iBAAiB,GAAG;GACnD,mBAAmBA,gBAAAA,kBAAkB,KAAK,WAAW,UAAU;GAC/D,aAAa;EACf;EAEA,IACE,OAAO,OAAO,WAAW,YACzB,CAAC,kBAAkB,SAAS,OAAO,MAAsB,GACzD;GACA,MAAM,aACJ,oBAAoB,iBAAiB,SAAS,IAC1C,mBAAmB,kBAAkB,KAAK,IAAI,EAAE,KAChD,aACE,MAAM,WAAW,yBAAyB,KAAK,WAAW,SAC1D;GACR,MAAM,IAAI,MAAM,wBAAwB,OAAO,OAAO,IAAI,WAAW,EAAE;EACzE;;;;EAKA,IAAI,OAAO,WAAW,YAAY,UAAU,QAAQ;GAElD,IAAI,OAAO,SAAS,aAAa;IAC/B,IAAI,OAAO,OACT,MAAM,OAAO;IAEf,OAAO;KACL,GAAG;KACH,GAAI,OAAO,UAAU,CAAC;KACtB,QAAQ,OAAO;IACjB;GACF;GAEA,MAAM,IAAI,MAAM,2BAA2B,KAAK,UAAU,MAAM,GAAG;EACrE;;;;EAKA,OAAO;GAAE,GAAG;GAAO,GAAG;GAAQ,QAAQ,OAAO;EAAO;CACtD;CAEA,IAAI,cAAc;EAChB,OAAO,EACL,OAAOC,cAAAA,mBAAmB,KAAK,WAAW,WAAW,EACvD;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","names":[],"sources":["../../../src/agents/nodes/middleware.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { LangGraphRunnableConfig, Command } from \"@langchain/langgraph\";\nimport {\n getInteropZodObjectShape,\n interopParse,\n isInteropZodObject,\n} from \"@langchain/core/utils/types\";\n\nimport { RunnableCallable, RunnableCallableArgs } from \"../RunnableCallable.js\";\nimport type { JumpToTarget } from \"../constants.js\";\nimport type { Runtime } from \"../runtime.js\";\nimport type {\n AnyAgentMiddleware,\n MiddlewareResult,\n} from \"../middleware/types.js\";\nimport { derivePrivateState } from \"./utils.js\";\nimport { getHookConstraint } from \"../middleware/utils.js\";\n\n/**\n * Named class for context objects to provide better error messages\n */\nclass AgentContext {}\nclass AgentRuntime {}\n\ntype NodeOutput<TStateSchema extends Record<string, any>> =\n | TStateSchema\n | Command<any, TStateSchema, string>\n | { jumpTo?: JumpToTarget };\n\nexport abstract class MiddlewareNode<\n TStateSchema extends Record<string, any>,\n TContextSchema extends Record<string, any>,\n> extends RunnableCallable<TStateSchema, NodeOutput<TStateSchema>> {\n abstract middleware: AnyAgentMiddleware;\n\n constructor(\n fields: RunnableCallableArgs<TStateSchema, NodeOutput<TStateSchema>>\n ) {\n super(fields);\n }\n\n abstract runHook(\n state: TStateSchema,\n config?: Runtime<TContextSchema>\n ): Promise<MiddlewareResult<TStateSchema>> | MiddlewareResult<TStateSchema>;\n\n async invokeMiddleware(\n invokeState: TStateSchema,\n config?: LangGraphRunnableConfig\n ): Promise<NodeOutput<TStateSchema>> {\n /**\n * Filter context based on middleware's contextSchema\n */\n let filteredContext = {} as TContextSchema;\n /**\n * Parse context using middleware's contextSchema to apply defaults and validation\n */\n if (\n this.middleware.contextSchema &&\n isInteropZodObject(this.middleware.contextSchema)\n ) {\n /**\n * Extract only the fields relevant to this middleware's schema\n */\n const schemaShape = getInteropZodObjectShape(\n this.middleware.contextSchema\n );\n if (schemaShape) {\n const relevantContext: Record<string, unknown> = {};\n const invokeContext = config?.context || {};\n for (const key of Object.keys(schemaShape)) {\n if (key in invokeContext) {\n relevantContext[key] = invokeContext[key];\n }\n }\n /**\n * Parse to apply defaults and validation, even if relevantContext is empty\n * This will throw if required fields are missing and no defaults exist\n */\n filteredContext = interopParse(\n this.middleware.contextSchema,\n relevantContext\n ) as TContextSchema;\n }\n }\n\n const state: TStateSchema = {\n ...invokeState,\n /**\n * don't overwrite possible outdated messages from other middleware nodes\n */\n messages: invokeState.messages,\n };\n\n const runtime: Runtime<TContextSchema> = {\n context: filteredContext,\n store: config?.store,\n configurable: config?.configurable,\n writer: config?.writer,\n interrupt: config?.interrupt,\n signal: config?.signal,\n };\n\n const result = await this.runHook(\n state,\n /**\n * assign runtime and context values into empty named class\n * instances to create a better error message.\n */\n Object.freeze(\n Object.assign(new AgentRuntime(), {\n ...runtime,\n context: Object.freeze(\n Object.assign(new AgentContext(), filteredContext)\n ),\n })\n )\n );\n\n /**\n * If result is undefined, the hook made no state changes — return\n * only the jumpTo sentinel so we don't re-emit every input key as\n * a state update.\n */\n if (!result) {\n return { jumpTo: undefined };\n }\n\n /**\n * Verify that the jump target is allowed for the middleware\n */\n let jumpToConstraint: JumpToTarget[] | undefined;\n let constraint: string | undefined;\n\n if (this.name?.startsWith(\"BeforeAgentNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.beforeAgent);\n constraint = \"beforeAgent.canJumpTo\";\n } else if (this.name?.startsWith(\"BeforeModelNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.beforeModel);\n constraint = \"beforeModel.canJumpTo\";\n } else if (this.name?.startsWith(\"AfterAgentNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.afterAgent);\n constraint = \"afterAgent.canJumpTo\";\n } else if (this.name?.startsWith(\"AfterModelNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.afterModel);\n constraint = \"afterModel.canJumpTo\";\n }\n\n if (\n typeof result.jumpTo === \"string\" &&\n !jumpToConstraint?.includes(result.jumpTo as JumpToTarget)\n ) {\n const suggestion =\n jumpToConstraint && jumpToConstraint.length > 0\n ? `must be one of: ${jumpToConstraint?.join(\", \")}.`\n : constraint\n ? `no ${constraint} defined in middleware ${this.middleware.name}`\n : \"\";\n throw new Error(`Invalid jump target: ${result.jumpTo}, ${suggestion}.`);\n }\n\n /**\n * If result is a control action, handle it\n */\n if (typeof result === \"object\" && \"type\" in result) {\n // Handle control actions\n if (result.type === \"terminate\") {\n if (result.error) {\n throw result.error;\n }\n return {\n ...state,\n ...(result.result || {}),\n jumpTo: result.jumpTo,\n };\n }\n\n throw new Error(`Invalid control action: ${JSON.stringify(result)}`);\n }\n\n /**\n * If result is a state update, merge it with current state\n */\n return { ...state, ...result, jumpTo: result.jumpTo };\n }\n\n get nodeOptions() {\n return {\n input: derivePrivateState(this.middleware.stateSchema),\n };\n }\n}\n"],"mappings":";;;;;;;;AAqBA,IAAM,eAAN,MAAmB;
|
|
1
|
+
{"version":3,"file":"middleware.js","names":[],"sources":["../../../src/agents/nodes/middleware.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { LangGraphRunnableConfig, Command } from \"@langchain/langgraph\";\nimport {\n getInteropZodObjectShape,\n interopParse,\n isInteropZodObject,\n} from \"@langchain/core/utils/types\";\n\nimport { RunnableCallable, RunnableCallableArgs } from \"../RunnableCallable.js\";\nimport type { JumpToTarget } from \"../constants.js\";\nimport type { Runtime } from \"../runtime.js\";\nimport type {\n AnyAgentMiddleware,\n MiddlewareResult,\n} from \"../middleware/types.js\";\nimport { derivePrivateState } from \"./utils.js\";\nimport { getHookConstraint } from \"../middleware/utils.js\";\n\n/**\n * Named class for context objects to provide better error messages\n */\nclass AgentContext {}\nclass AgentRuntime {}\n\ntype NodeOutput<TStateSchema extends Record<string, any>> =\n | TStateSchema\n | Command<any, TStateSchema, string>\n | { jumpTo?: JumpToTarget };\n\nexport abstract class MiddlewareNode<\n TStateSchema extends Record<string, any>,\n TContextSchema extends Record<string, any>,\n> extends RunnableCallable<TStateSchema, NodeOutput<TStateSchema>> {\n abstract middleware: AnyAgentMiddleware;\n\n constructor(\n fields: RunnableCallableArgs<TStateSchema, NodeOutput<TStateSchema>>\n ) {\n super(fields);\n }\n\n abstract runHook(\n state: TStateSchema,\n config?: Runtime<TContextSchema>\n ): Promise<MiddlewareResult<TStateSchema>> | MiddlewareResult<TStateSchema>;\n\n async invokeMiddleware(\n invokeState: TStateSchema,\n config?: LangGraphRunnableConfig\n ): Promise<NodeOutput<TStateSchema>> {\n /**\n * Filter context based on middleware's contextSchema\n */\n let filteredContext = {} as TContextSchema;\n /**\n * Parse context using middleware's contextSchema to apply defaults and validation\n */\n if (\n this.middleware.contextSchema &&\n isInteropZodObject(this.middleware.contextSchema)\n ) {\n /**\n * Extract only the fields relevant to this middleware's schema\n */\n const schemaShape = getInteropZodObjectShape(\n this.middleware.contextSchema\n );\n if (schemaShape) {\n const relevantContext: Record<string, unknown> = {};\n const invokeContext = config?.context || {};\n for (const key of Object.keys(schemaShape)) {\n if (key in invokeContext) {\n relevantContext[key] = invokeContext[key];\n }\n }\n /**\n * Parse to apply defaults and validation, even if relevantContext is empty\n * This will throw if required fields are missing and no defaults exist\n */\n filteredContext = interopParse(\n this.middleware.contextSchema,\n relevantContext\n ) as TContextSchema;\n }\n }\n\n const state: TStateSchema = {\n ...invokeState,\n /**\n * don't overwrite possible outdated messages from other middleware nodes\n */\n messages: invokeState.messages,\n };\n\n const runtime: Runtime<TContextSchema> = {\n context: filteredContext,\n store: config?.store,\n configurable: config?.configurable,\n writer: config?.writer,\n interrupt: config?.interrupt,\n signal: config?.signal,\n };\n\n const result = await this.runHook(\n state,\n /**\n * assign runtime and context values into empty named class\n * instances to create a better error message.\n */\n Object.freeze(\n Object.assign(new AgentRuntime(), {\n ...runtime,\n context: Object.freeze(\n Object.assign(new AgentContext(), filteredContext)\n ),\n })\n )\n );\n\n /**\n * If result is undefined, the hook made no state changes — return\n * only the jumpTo sentinel so we don't re-emit every input key as\n * a state update.\n */\n if (!result) {\n return { jumpTo: undefined };\n }\n\n /**\n * Verify that the jump target is allowed for the middleware\n */\n let jumpToConstraint: JumpToTarget[] | undefined;\n let constraint: string | undefined;\n\n if (this.name?.startsWith(\"BeforeAgentNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.beforeAgent);\n constraint = \"beforeAgent.canJumpTo\";\n } else if (this.name?.startsWith(\"BeforeModelNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.beforeModel);\n constraint = \"beforeModel.canJumpTo\";\n } else if (this.name?.startsWith(\"AfterAgentNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.afterAgent);\n constraint = \"afterAgent.canJumpTo\";\n } else if (this.name?.startsWith(\"AfterModelNode_\")) {\n jumpToConstraint = getHookConstraint(this.middleware.afterModel);\n constraint = \"afterModel.canJumpTo\";\n }\n\n if (\n typeof result.jumpTo === \"string\" &&\n !jumpToConstraint?.includes(result.jumpTo as JumpToTarget)\n ) {\n const suggestion =\n jumpToConstraint && jumpToConstraint.length > 0\n ? `must be one of: ${jumpToConstraint?.join(\", \")}.`\n : constraint\n ? `no ${constraint} defined in middleware ${this.middleware.name}`\n : \"\";\n throw new Error(`Invalid jump target: ${result.jumpTo}, ${suggestion}.`);\n }\n\n /**\n * If result is a control action, handle it\n */\n if (typeof result === \"object\" && \"type\" in result) {\n // Handle control actions\n if (result.type === \"terminate\") {\n if (result.error) {\n throw result.error;\n }\n return {\n ...state,\n ...(result.result || {}),\n jumpTo: result.jumpTo,\n };\n }\n\n throw new Error(`Invalid control action: ${JSON.stringify(result)}`);\n }\n\n /**\n * If result is a state update, merge it with current state\n */\n return { ...state, ...result, jumpTo: result.jumpTo };\n }\n\n get nodeOptions() {\n return {\n input: derivePrivateState(this.middleware.stateSchema),\n };\n }\n}\n"],"mappings":";;;;;;;;AAqBA,IAAM,eAAN,MAAmB,CAAC;AACpB,IAAM,eAAN,MAAmB,CAAC;AAOpB,IAAsB,iBAAtB,cAGU,iBAAyD;CAGjE,YACE,QACA;EACA,MAAM,MAAM;CACd;CAOA,MAAM,iBACJ,aACA,QACmC;;;;EAInC,IAAI,kBAAkB,CAAC;;;;EAIvB,IACE,KAAK,WAAW,iBAChB,mBAAmB,KAAK,WAAW,aAAa,GAChD;;;;GAIA,MAAM,cAAc,yBAClB,KAAK,WAAW,aAClB;GACA,IAAI,aAAa;IACf,MAAM,kBAA2C,CAAC;IAClD,MAAM,gBAAgB,QAAQ,WAAW,CAAC;IAC1C,KAAK,MAAM,OAAO,OAAO,KAAK,WAAW,GACvC,IAAI,OAAO,eACT,gBAAgB,OAAO,cAAc;;;;;IAOzC,kBAAkB,aAChB,KAAK,WAAW,eAChB,eACF;GACF;EACF;EAEA,MAAM,QAAsB;GAC1B,GAAG;;;;GAIH,UAAU,YAAY;EACxB;EAEA,MAAM,UAAmC;GACvC,SAAS;GACT,OAAO,QAAQ;GACf,cAAc,QAAQ;GACtB,QAAQ,QAAQ;GAChB,WAAW,QAAQ;GACnB,QAAQ,QAAQ;EAClB;EAEA,MAAM,SAAS,MAAM,KAAK;GACxB;;;;;GAKA,OAAO,OACL,OAAO,OAAO,IAAI,aAAa,GAAG;IAChC,GAAG;IACH,SAAS,OAAO,OACd,OAAO,OAAO,IAAI,aAAa,GAAG,eAAe,CACnD;GACF,CAAC,CACH;EACF;;;;;;EAOA,IAAI,CAAC,QACH,OAAO,EAAE,QAAQ,KAAA,EAAU;;;;EAM7B,IAAI;EACJ,IAAI;EAEJ,IAAI,KAAK,MAAM,WAAW,kBAAkB,GAAG;GAC7C,mBAAmB,kBAAkB,KAAK,WAAW,WAAW;GAChE,aAAa;EACf,OAAO,IAAI,KAAK,MAAM,WAAW,kBAAkB,GAAG;GACpD,mBAAmB,kBAAkB,KAAK,WAAW,WAAW;GAChE,aAAa;EACf,OAAO,IAAI,KAAK,MAAM,WAAW,iBAAiB,GAAG;GACnD,mBAAmB,kBAAkB,KAAK,WAAW,UAAU;GAC/D,aAAa;EACf,OAAO,IAAI,KAAK,MAAM,WAAW,iBAAiB,GAAG;GACnD,mBAAmB,kBAAkB,KAAK,WAAW,UAAU;GAC/D,aAAa;EACf;EAEA,IACE,OAAO,OAAO,WAAW,YACzB,CAAC,kBAAkB,SAAS,OAAO,MAAsB,GACzD;GACA,MAAM,aACJ,oBAAoB,iBAAiB,SAAS,IAC1C,mBAAmB,kBAAkB,KAAK,IAAI,EAAE,KAChD,aACE,MAAM,WAAW,yBAAyB,KAAK,WAAW,SAC1D;GACR,MAAM,IAAI,MAAM,wBAAwB,OAAO,OAAO,IAAI,WAAW,EAAE;EACzE;;;;EAKA,IAAI,OAAO,WAAW,YAAY,UAAU,QAAQ;GAElD,IAAI,OAAO,SAAS,aAAa;IAC/B,IAAI,OAAO,OACT,MAAM,OAAO;IAEf,OAAO;KACL,GAAG;KACH,GAAI,OAAO,UAAU,CAAC;KACtB,QAAQ,OAAO;IACjB;GACF;GAEA,MAAM,IAAI,MAAM,2BAA2B,KAAK,UAAU,MAAM,GAAG;EACrE;;;;EAKA,OAAO;GAAE,GAAG;GAAO,GAAG;GAAQ,QAAQ,OAAO;EAAO;CACtD;CAEA,IAAI,cAAc;EAChB,OAAO,EACL,OAAO,mBAAmB,KAAK,WAAW,WAAW,EACvD;CACF;AACF"}
|
|
@@ -3,7 +3,6 @@ import { ResponseFormatInput } from "../responses.cjs";
|
|
|
3
3
|
import { AgentBuiltInState, Runtime } from "../runtime.cjs";
|
|
4
4
|
import { BaseMessage, SystemMessage } from "@langchain/core/messages";
|
|
5
5
|
import { ClientTool, ServerTool } from "@langchain/core/tools";
|
|
6
|
-
|
|
7
6
|
//#region src/agents/nodes/types.d.ts
|
|
8
7
|
/**
|
|
9
8
|
* Configuration for modifying a model call at runtime.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","names":[],"sources":["../../../src/agents/nodes/types.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.cts","names":[],"sources":["../../../src/agents/nodes/types.ts"],"mappings":";;;;;;;;;;;;;UAciB,aACf,eAAe,0BAA0B,yBACzC,oBACA,wBAAwB,sBAAsB;;;;EAK9C,OAAO;;;;EAIP,UAAU;;;;;;;EAOV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCA,eAAe;;;;;;;;;EASf;IAIM;IAAkB;MAAY;;;;;;EAKpC,QAAQ,aAAa;;;;EAKrB,OAAO,SAAS;;;;;EAMhB,iBAAiB;;;;EAKjB,SAAS,QAAQ;;;;;;;;;;;;;;;EAgBjB,gBAAgB"}
|
|
@@ -3,7 +3,6 @@ import { ResponseFormatInput } from "../responses.js";
|
|
|
3
3
|
import { AgentBuiltInState, Runtime } from "../runtime.js";
|
|
4
4
|
import { BaseMessage, SystemMessage } from "@langchain/core/messages";
|
|
5
5
|
import { ClientTool, ServerTool } from "@langchain/core/tools";
|
|
6
|
-
|
|
7
6
|
//#region src/agents/nodes/types.d.ts
|
|
8
7
|
/**
|
|
9
8
|
* Configuration for modifying a model call at runtime.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/agents/nodes/types.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/agents/nodes/types.ts"],"mappings":";;;;;;;;;;;;;UAciB,aACf,eAAe,0BAA0B,yBACzC,oBACA,wBAAwB,sBAAsB;;;;EAK9C,OAAO;;;;EAIP,UAAU;;;;;;;EAOV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCA,eAAe;;;;;;;;;EASf;IAIM;IAAkB;MAAY;;;;;;EAKpC,QAAQ,aAAa;;;;EAKrB,OAAO,SAAS;;;;;EAMhB,iBAAiB;;;;EAKjB,SAAS,QAAQ;;;;;;;;;;;;;;;EAgBjB,gBAAgB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","names":["StateSchema","ReducedValue","z","END"],"sources":["../../../src/agents/nodes/utils.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { z } from \"zod/v4\";\nimport { type BaseMessage } from \"@langchain/core/messages\";\nimport {\n getInteropZodObjectShape,\n interopSafeParseAsync,\n interopZodObjectMakeFieldsOptional,\n interopZodObjectPartial,\n isInteropZodObject,\n isZodSchemaV4,\n type InteropZodObject,\n} from \"@langchain/core/utils/types\";\nimport type { StateDefinitionInit } from \"@langchain/langgraph\";\nimport { END, StateSchema, ReducedValue } from \"@langchain/langgraph\";\n\nimport type { JumpTo } from \"../types.js\";\nimport type { AnyAgentMiddleware } from \"../middleware/types.js\";\n\n/**\n * Helper function to initialize middleware state defaults.\n * This is used to ensure all middleware state properties are initialized.\n *\n * Private properties (starting with _) are automatically made optional since\n * users cannot provide them when invoking the agent.\n */\nexport async function initializeMiddlewareStates(\n middlewareList: readonly AnyAgentMiddleware[],\n state: unknown\n): Promise<Record<string, any>> {\n const middlewareStates: Record<string, any> = {};\n\n for (const middleware of middlewareList) {\n /**\n * skip middleware if it doesn't have a state schema\n */\n if (!middleware.stateSchema) {\n continue;\n }\n\n // Convert StateSchema to Zod object if needed\n let zodSchema: InteropZodObject;\n if (StateSchema.isInstance(middleware.stateSchema)) {\n const zodShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(\n middleware.stateSchema.fields\n )) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n zodShape[key] = field.inputSchema || field.valueSchema;\n } else {\n zodShape[key] = field;\n }\n }\n zodSchema = z.object(zodShape);\n } else if (isInteropZodObject(middleware.stateSchema)) {\n zodSchema = middleware.stateSchema;\n } else {\n continue;\n }\n\n // Create a modified schema where private properties are optional\n const modifiedSchema = interopZodObjectMakeFieldsOptional(\n zodSchema,\n (key) => key.startsWith(\"_\")\n );\n\n // Use safeParse with the modified schema\n const parseResult = await interopSafeParseAsync(modifiedSchema, state);\n if (parseResult.success) {\n Object.assign(middlewareStates, parseResult.data);\n continue;\n }\n\n /**\n * If safeParse fails, there are required public fields missing.\n * Note: Zod v3 uses message \"Required\", Zod v4 uses \"Invalid input: expected X, received undefined\"\n */\n const requiredFields = parseResult.error.issues\n .filter((issue) => issue.code === \"invalid_type\")\n .map((issue) => ` - ${issue.path.join(\".\")}: Required`)\n .join(\"\\n\");\n\n throw new Error(\n `Middleware \"${middleware.name}\" has required state fields that must be initialized:\\n` +\n `${requiredFields}\\n\\n` +\n `To fix this, either:\\n` +\n `1. Provide default values in your middleware's state schema using .default():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().default(\"default value\")\\n` +\n ` })\\n\\n` +\n `2. Or make the fields optional using .optional():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().optional()\\n` +\n ` })\\n\\n` +\n `3. Or ensure you pass these values when invoking the agent:\\n` +\n ` agent.invoke({\\n` +\n ` messages: [...],\\n` +\n ` ${parseResult.error.issues[0]?.path.join(\".\")}: \"value\"\\n` +\n ` })`\n );\n }\n\n return middlewareStates;\n}\n\n/**\n * Users can define private and public state for a middleware. Private state properties start with an underscore.\n * This function will return the private state properties from the state schema, making all of them optional.\n * @param stateSchema - The middleware state schema\n * @returns A new schema containing only the private properties (underscore-prefixed), all made optional\n */\nexport function derivePrivateState(\n stateSchema?: StateDefinitionInit\n): InteropZodObject {\n const builtInStateSchema = {\n messages: z.custom<BaseMessage[]>(() => []),\n // Include optional structuredResponse so after_agent hooks can access/modify it\n structuredResponse: z.any().optional(),\n };\n\n if (!stateSchema) {\n return z.object(builtInStateSchema);\n }\n\n // Extract shape from either StateSchema or Zod object\n let shape: Record<string, any>;\n if (StateSchema.isInstance(stateSchema)) {\n // For StateSchema, extract Zod schemas from fields\n shape = {};\n for (const [key, field] of Object.entries(stateSchema.fields)) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n shape[key] = field.inputSchema || field.valueSchema;\n } else {\n shape[key] = field;\n }\n }\n } else if (isInteropZodObject(stateSchema)) {\n shape = getInteropZodObjectShape(stateSchema);\n } else {\n return z.object(builtInStateSchema);\n }\n\n const privateShape: Record<string, any> = { ...builtInStateSchema };\n\n // Filter properties that start with underscore and make them optional\n for (const [key, value] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) {\n // Make the private property optional\n privateShape[key] = value.optional();\n } else {\n privateShape[key] = value;\n }\n }\n\n // Return a new schema with only private properties (all optional)\n return z.object(privateShape);\n}\n\n/**\n * Converts any supported schema type (ZodObject, StateSchema, AnnotationRoot) to a partial Zod object.\n * This is useful for parsing state loosely where all fields are optional.\n *\n * @param schema - The schema to convert (InteropZodObject, StateSchema, or AnnotationRoot)\n * @returns A partial Zod object schema where all fields are optional\n */\nexport function toPartialZodObject(\n schema: StateDefinitionInit\n): InteropZodObject {\n // Handle ZodObject directly\n if (isInteropZodObject(schema)) {\n return interopZodObjectPartial(schema);\n }\n\n // Handle StateSchema: convert fields to Zod shape, then make partial\n if (StateSchema.isInstance(schema)) {\n const partialShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(schema.fields)) {\n let fieldSchema: unknown;\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n fieldSchema = field.inputSchema || field.valueSchema;\n } else {\n fieldSchema = field;\n }\n // Only call .optional() on Zod v4 schemas, otherwise use z.any()\n partialShape[key] = isZodSchemaV4(fieldSchema)\n ? (fieldSchema as any).optional()\n : z.any().optional();\n }\n return z.object(partialShape);\n }\n\n // Fallback: return empty object schema\n return z.object({});\n}\n\n/**\n * Parse `jumpTo` target from user facing labels to a LangGraph node names\n */\nexport function parseJumpToTarget(target: string): JumpTo;\nexport function parseJumpToTarget(target?: string): JumpTo | undefined {\n if (!target) {\n return undefined;\n }\n\n /**\n * if target is already a valid jump target, return it\n */\n if ([\"model_request\", \"tools\", END].includes(target)) {\n return target as JumpTo;\n }\n\n if (target === \"model\") {\n return \"model_request\";\n }\n if (target === \"tools\") {\n return \"tools\";\n }\n if (target === \"end\") {\n return END;\n }\n\n throw new Error(\n `Invalid jump target: ${target}, must be \"model\", \"tools\" or \"end\".`\n );\n}\n\n/**\n * TypeScript currently doesn't support types for `AbortSignal.any`\n * @see https://github.com/microsoft/TypeScript/issues/60695\n */\ndeclare const AbortSignal: {\n any(signals: AbortSignal[]): AbortSignal;\n};\n\n/**\n * `config` always contains a signal from LangGraphs Pregel class.\n * To ensure we acknowledge the abort signal from the user, we merge it\n * with the signal from the ToolNode.\n *\n * @param signals - The signals to merge.\n * @returns The merged signal.\n */\nexport function mergeAbortSignals(\n ...signals: (AbortSignal | undefined)[]\n): AbortSignal {\n return AbortSignal.any(\n signals.filter(\n (maybeSignal): maybeSignal is AbortSignal =>\n maybeSignal !== null &&\n maybeSignal !== undefined &&\n typeof maybeSignal === \"object\" &&\n \"aborted\" in maybeSignal &&\n typeof maybeSignal.aborted === \"boolean\"\n )\n );\n}\n"],"mappings":";;;;;;;;;;;;AAyBA,eAAsB,2BACpB,gBACA,OAC8B;CAC9B,MAAM,mBAAwC,EAAE;AAEhD,MAAK,MAAM,cAAc,gBAAgB;;;;AAIvC,MAAI,CAAC,WAAW,YACd;EAIF,IAAI;AACJ,MAAIA,qBAAAA,YAAY,WAAW,WAAW,YAAY,EAAE;GAClD,MAAM,WAAgC,EAAE;AACxC,QAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAChC,WAAW,YAAY,OACxB,CACC,KAAIC,qBAAAA,aAAa,WAAW,MAAM,CAEhC,UAAS,OAAO,MAAM,eAAe,MAAM;OAE3C,UAAS,OAAO;AAGpB,eAAYC,OAAAA,EAAE,OAAO,SAAS;iEACF,WAAW,YAAY,CACnD,aAAY,WAAW;MAEvB;EAUF,MAAM,cAAc,OAAA,GAAA,4BAAA,wBAAA,GAAA,4BAAA,oCALlB,YACC,QAAQ,IAAI,WAAW,IAAI,CAIgC,EAAE,MAAM;AACtE,MAAI,YAAY,SAAS;AACvB,UAAO,OAAO,kBAAkB,YAAY,KAAK;AACjD;;;;;;EAOF,MAAM,iBAAiB,YAAY,MAAM,OACtC,QAAQ,UAAU,MAAM,SAAS,eAAe,CAChD,KAAK,UAAU,OAAO,MAAM,KAAK,KAAK,IAAI,CAAC,YAAY,CACvD,KAAK,KAAK;AAEb,QAAM,IAAI,MACR,eAAe,WAAW,KAAK,yDAC1B,eAAe,4aAaV,YAAY,MAAM,OAAO,IAAI,KAAK,KAAK,IAAI,CAAC,kBAEvD;;AAGH,QAAO;;;;;;;;AAST,SAAgB,mBACd,aACkB;CAClB,MAAM,qBAAqB;EACzB,UAAUA,OAAAA,EAAE,aAA4B,EAAE,CAAC;EAE3C,oBAAoBA,OAAAA,EAAE,KAAK,CAAC,UAAU;EACvC;AAED,KAAI,CAAC,YACH,QAAOA,OAAAA,EAAE,OAAO,mBAAmB;CAIrC,IAAI;AACJ,KAAIF,qBAAAA,YAAY,WAAW,YAAY,EAAE;AAEvC,UAAQ,EAAE;AACV,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,YAAY,OAAO,CAC3D,KAAIC,qBAAAA,aAAa,WAAW,MAAM,CAEhC,OAAM,OAAO,MAAM,eAAe,MAAM;MAExC,OAAM,OAAO;gEAGW,YAAY,CACxC,UAAA,GAAA,4BAAA,0BAAiC,YAAY;KAE7C,QAAOC,OAAAA,EAAE,OAAO,mBAAmB;CAGrC,MAAM,eAAoC,EAAE,GAAG,oBAAoB;AAGnE,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,CAC9C,KAAI,IAAI,WAAW,IAAI,CAErB,cAAa,OAAO,MAAM,UAAU;KAEpC,cAAa,OAAO;AAKxB,QAAOA,OAAAA,EAAE,OAAO,aAAa;;;;;;;;;AAU/B,SAAgB,mBACd,QACkB;AAElB,MAAA,GAAA,4BAAA,oBAAuB,OAAO,CAC5B,SAAA,GAAA,4BAAA,yBAA+B,OAAO;AAIxC,KAAIF,qBAAAA,YAAY,WAAW,OAAO,EAAE;EAClC,MAAM,eAAoC,EAAE;AAC5C,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,OAAO,EAAE;GACxD,IAAI;AACJ,OAAIC,qBAAAA,aAAa,WAAW,MAAM,CAEhC,eAAc,MAAM,eAAe,MAAM;OAEzC,eAAc;AAGhB,gBAAa,QAAA,GAAA,4BAAA,eAAqB,YAAY,GACzC,YAAoB,UAAU,GAC/BC,OAAAA,EAAE,KAAK,CAAC,UAAU;;AAExB,SAAOA,OAAAA,EAAE,OAAO,aAAa;;AAI/B,QAAOA,OAAAA,EAAE,OAAO,EAAE,CAAC;;AAOrB,SAAgB,kBAAkB,QAAqC;AACrE,KAAI,CAAC,OACH;;;;AAMF,KAAI;EAAC;EAAiB;EAASC,qBAAAA;EAAI,CAAC,SAAS,OAAO,CAClD,QAAO;AAGT,KAAI,WAAW,QACb,QAAO;AAET,KAAI,WAAW,QACb,QAAO;AAET,KAAI,WAAW,MACb,QAAOA,qBAAAA;AAGT,OAAM,IAAI,MACR,wBAAwB,OAAO,sCAChC;;;;;;;;;;AAmBH,SAAgB,kBACd,GAAG,SACU;AACb,QAAO,YAAY,IACjB,QAAQ,QACL,gBACC,gBAAgB,QAChB,gBAAgB,KAAA,KAChB,OAAO,gBAAgB,YACvB,aAAa,eACb,OAAO,YAAY,YAAY,UAClC,CACF"}
|
|
1
|
+
{"version":3,"file":"utils.cjs","names":["StateSchema","ReducedValue","z","END"],"sources":["../../../src/agents/nodes/utils.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { z } from \"zod/v4\";\nimport { type BaseMessage } from \"@langchain/core/messages\";\nimport {\n getInteropZodObjectShape,\n interopSafeParseAsync,\n interopZodObjectMakeFieldsOptional,\n interopZodObjectPartial,\n isInteropZodObject,\n isZodSchemaV4,\n type InteropZodObject,\n} from \"@langchain/core/utils/types\";\nimport type { StateDefinitionInit } from \"@langchain/langgraph\";\nimport { END, StateSchema, ReducedValue } from \"@langchain/langgraph\";\n\nimport type { JumpTo } from \"../types.js\";\nimport type { AnyAgentMiddleware } from \"../middleware/types.js\";\n\n/**\n * Helper function to initialize middleware state defaults.\n * This is used to ensure all middleware state properties are initialized.\n *\n * Private properties (starting with _) are automatically made optional since\n * users cannot provide them when invoking the agent.\n */\nexport async function initializeMiddlewareStates(\n middlewareList: readonly AnyAgentMiddleware[],\n state: unknown\n): Promise<Record<string, any>> {\n const middlewareStates: Record<string, any> = {};\n\n for (const middleware of middlewareList) {\n /**\n * skip middleware if it doesn't have a state schema\n */\n if (!middleware.stateSchema) {\n continue;\n }\n\n // Convert StateSchema to Zod object if needed\n let zodSchema: InteropZodObject;\n if (StateSchema.isInstance(middleware.stateSchema)) {\n const zodShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(\n middleware.stateSchema.fields\n )) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n zodShape[key] = field.inputSchema || field.valueSchema;\n } else {\n zodShape[key] = field;\n }\n }\n zodSchema = z.object(zodShape);\n } else if (isInteropZodObject(middleware.stateSchema)) {\n zodSchema = middleware.stateSchema;\n } else {\n continue;\n }\n\n // Create a modified schema where private properties are optional\n const modifiedSchema = interopZodObjectMakeFieldsOptional(\n zodSchema,\n (key) => key.startsWith(\"_\")\n );\n\n // Use safeParse with the modified schema\n const parseResult = await interopSafeParseAsync(modifiedSchema, state);\n if (parseResult.success) {\n Object.assign(middlewareStates, parseResult.data);\n continue;\n }\n\n /**\n * If safeParse fails, there are required public fields missing.\n * Note: Zod v3 uses message \"Required\", Zod v4 uses \"Invalid input: expected X, received undefined\"\n */\n const requiredFields = parseResult.error.issues\n .filter((issue) => issue.code === \"invalid_type\")\n .map((issue) => ` - ${issue.path.join(\".\")}: Required`)\n .join(\"\\n\");\n\n throw new Error(\n `Middleware \"${middleware.name}\" has required state fields that must be initialized:\\n` +\n `${requiredFields}\\n\\n` +\n `To fix this, either:\\n` +\n `1. Provide default values in your middleware's state schema using .default():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().default(\"default value\")\\n` +\n ` })\\n\\n` +\n `2. Or make the fields optional using .optional():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().optional()\\n` +\n ` })\\n\\n` +\n `3. Or ensure you pass these values when invoking the agent:\\n` +\n ` agent.invoke({\\n` +\n ` messages: [...],\\n` +\n ` ${parseResult.error.issues[0]?.path.join(\".\")}: \"value\"\\n` +\n ` })`\n );\n }\n\n return middlewareStates;\n}\n\n/**\n * Users can define private and public state for a middleware. Private state properties start with an underscore.\n * This function will return the private state properties from the state schema, making all of them optional.\n * @param stateSchema - The middleware state schema\n * @returns A new schema containing only the private properties (underscore-prefixed), all made optional\n */\nexport function derivePrivateState(\n stateSchema?: StateDefinitionInit\n): InteropZodObject {\n const builtInStateSchema = {\n messages: z.custom<BaseMessage[]>(() => []),\n // Include optional structuredResponse so after_agent hooks can access/modify it\n structuredResponse: z.any().optional(),\n };\n\n if (!stateSchema) {\n return z.object(builtInStateSchema);\n }\n\n // Extract shape from either StateSchema or Zod object\n let shape: Record<string, any>;\n if (StateSchema.isInstance(stateSchema)) {\n // For StateSchema, extract Zod schemas from fields\n shape = {};\n for (const [key, field] of Object.entries(stateSchema.fields)) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n shape[key] = field.inputSchema || field.valueSchema;\n } else {\n shape[key] = field;\n }\n }\n } else if (isInteropZodObject(stateSchema)) {\n shape = getInteropZodObjectShape(stateSchema);\n } else {\n return z.object(builtInStateSchema);\n }\n\n const privateShape: Record<string, any> = { ...builtInStateSchema };\n\n // Filter properties that start with underscore and make them optional\n for (const [key, value] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) {\n // Make the private property optional\n privateShape[key] = value.optional();\n } else {\n privateShape[key] = value;\n }\n }\n\n // Return a new schema with only private properties (all optional)\n return z.object(privateShape);\n}\n\n/**\n * Converts any supported schema type (ZodObject, StateSchema, AnnotationRoot) to a partial Zod object.\n * This is useful for parsing state loosely where all fields are optional.\n *\n * @param schema - The schema to convert (InteropZodObject, StateSchema, or AnnotationRoot)\n * @returns A partial Zod object schema where all fields are optional\n */\nexport function toPartialZodObject(\n schema: StateDefinitionInit\n): InteropZodObject {\n // Handle ZodObject directly\n if (isInteropZodObject(schema)) {\n return interopZodObjectPartial(schema);\n }\n\n // Handle StateSchema: convert fields to Zod shape, then make partial\n if (StateSchema.isInstance(schema)) {\n const partialShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(schema.fields)) {\n let fieldSchema: unknown;\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n fieldSchema = field.inputSchema || field.valueSchema;\n } else {\n fieldSchema = field;\n }\n // Only call .optional() on Zod v4 schemas, otherwise use z.any()\n partialShape[key] = isZodSchemaV4(fieldSchema)\n ? (fieldSchema as any).optional()\n : z.any().optional();\n }\n return z.object(partialShape);\n }\n\n // Fallback: return empty object schema\n return z.object({});\n}\n\n/**\n * Parse `jumpTo` target from user facing labels to a LangGraph node names\n */\nexport function parseJumpToTarget(target: string): JumpTo;\nexport function parseJumpToTarget(target?: string): JumpTo | undefined {\n if (!target) {\n return undefined;\n }\n\n /**\n * if target is already a valid jump target, return it\n */\n if ([\"model_request\", \"tools\", END].includes(target)) {\n return target as JumpTo;\n }\n\n if (target === \"model\") {\n return \"model_request\";\n }\n if (target === \"tools\") {\n return \"tools\";\n }\n if (target === \"end\") {\n return END;\n }\n\n throw new Error(\n `Invalid jump target: ${target}, must be \"model\", \"tools\" or \"end\".`\n );\n}\n\n/**\n * TypeScript currently doesn't support types for `AbortSignal.any`\n * @see https://github.com/microsoft/TypeScript/issues/60695\n */\ndeclare const AbortSignal: {\n any(signals: AbortSignal[]): AbortSignal;\n};\n\n/**\n * `config` always contains a signal from LangGraphs Pregel class.\n * To ensure we acknowledge the abort signal from the user, we merge it\n * with the signal from the ToolNode.\n *\n * @param signals - The signals to merge.\n * @returns The merged signal.\n */\nexport function mergeAbortSignals(\n ...signals: (AbortSignal | undefined)[]\n): AbortSignal {\n return AbortSignal.any(\n signals.filter(\n (maybeSignal): maybeSignal is AbortSignal =>\n maybeSignal !== null &&\n maybeSignal !== undefined &&\n typeof maybeSignal === \"object\" &&\n \"aborted\" in maybeSignal &&\n typeof maybeSignal.aborted === \"boolean\"\n )\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/agents/nodes/utils.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { z } from \"zod/v4\";\nimport { type BaseMessage } from \"@langchain/core/messages\";\nimport {\n getInteropZodObjectShape,\n interopSafeParseAsync,\n interopZodObjectMakeFieldsOptional,\n interopZodObjectPartial,\n isInteropZodObject,\n isZodSchemaV4,\n type InteropZodObject,\n} from \"@langchain/core/utils/types\";\nimport type { StateDefinitionInit } from \"@langchain/langgraph\";\nimport { END, StateSchema, ReducedValue } from \"@langchain/langgraph\";\n\nimport type { JumpTo } from \"../types.js\";\nimport type { AnyAgentMiddleware } from \"../middleware/types.js\";\n\n/**\n * Helper function to initialize middleware state defaults.\n * This is used to ensure all middleware state properties are initialized.\n *\n * Private properties (starting with _) are automatically made optional since\n * users cannot provide them when invoking the agent.\n */\nexport async function initializeMiddlewareStates(\n middlewareList: readonly AnyAgentMiddleware[],\n state: unknown\n): Promise<Record<string, any>> {\n const middlewareStates: Record<string, any> = {};\n\n for (const middleware of middlewareList) {\n /**\n * skip middleware if it doesn't have a state schema\n */\n if (!middleware.stateSchema) {\n continue;\n }\n\n // Convert StateSchema to Zod object if needed\n let zodSchema: InteropZodObject;\n if (StateSchema.isInstance(middleware.stateSchema)) {\n const zodShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(\n middleware.stateSchema.fields\n )) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n zodShape[key] = field.inputSchema || field.valueSchema;\n } else {\n zodShape[key] = field;\n }\n }\n zodSchema = z.object(zodShape);\n } else if (isInteropZodObject(middleware.stateSchema)) {\n zodSchema = middleware.stateSchema;\n } else {\n continue;\n }\n\n // Create a modified schema where private properties are optional\n const modifiedSchema = interopZodObjectMakeFieldsOptional(\n zodSchema,\n (key) => key.startsWith(\"_\")\n );\n\n // Use safeParse with the modified schema\n const parseResult = await interopSafeParseAsync(modifiedSchema, state);\n if (parseResult.success) {\n Object.assign(middlewareStates, parseResult.data);\n continue;\n }\n\n /**\n * If safeParse fails, there are required public fields missing.\n * Note: Zod v3 uses message \"Required\", Zod v4 uses \"Invalid input: expected X, received undefined\"\n */\n const requiredFields = parseResult.error.issues\n .filter((issue) => issue.code === \"invalid_type\")\n .map((issue) => ` - ${issue.path.join(\".\")}: Required`)\n .join(\"\\n\");\n\n throw new Error(\n `Middleware \"${middleware.name}\" has required state fields that must be initialized:\\n` +\n `${requiredFields}\\n\\n` +\n `To fix this, either:\\n` +\n `1. Provide default values in your middleware's state schema using .default():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().default(\"default value\")\\n` +\n ` })\\n\\n` +\n `2. Or make the fields optional using .optional():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().optional()\\n` +\n ` })\\n\\n` +\n `3. Or ensure you pass these values when invoking the agent:\\n` +\n ` agent.invoke({\\n` +\n ` messages: [...],\\n` +\n ` ${parseResult.error.issues[0]?.path.join(\".\")}: \"value\"\\n` +\n ` })`\n );\n }\n\n return middlewareStates;\n}\n\n/**\n * Users can define private and public state for a middleware. Private state properties start with an underscore.\n * This function will return the private state properties from the state schema, making all of them optional.\n * @param stateSchema - The middleware state schema\n * @returns A new schema containing only the private properties (underscore-prefixed), all made optional\n */\nexport function derivePrivateState(\n stateSchema?: StateDefinitionInit\n): InteropZodObject {\n const builtInStateSchema = {\n messages: z.custom<BaseMessage[]>(() => []),\n // Include optional structuredResponse so after_agent hooks can access/modify it\n structuredResponse: z.any().optional(),\n };\n\n if (!stateSchema) {\n return z.object(builtInStateSchema);\n }\n\n // Extract shape from either StateSchema or Zod object\n let shape: Record<string, any>;\n if (StateSchema.isInstance(stateSchema)) {\n // For StateSchema, extract Zod schemas from fields\n shape = {};\n for (const [key, field] of Object.entries(stateSchema.fields)) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n shape[key] = field.inputSchema || field.valueSchema;\n } else {\n shape[key] = field;\n }\n }\n } else if (isInteropZodObject(stateSchema)) {\n shape = getInteropZodObjectShape(stateSchema);\n } else {\n return z.object(builtInStateSchema);\n }\n\n const privateShape: Record<string, any> = { ...builtInStateSchema };\n\n // Filter properties that start with underscore and make them optional\n for (const [key, value] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) {\n // Make the private property optional\n privateShape[key] = value.optional();\n } else {\n privateShape[key] = value;\n }\n }\n\n // Return a new schema with only private properties (all optional)\n return z.object(privateShape);\n}\n\n/**\n * Converts any supported schema type (ZodObject, StateSchema, AnnotationRoot) to a partial Zod object.\n * This is useful for parsing state loosely where all fields are optional.\n *\n * @param schema - The schema to convert (InteropZodObject, StateSchema, or AnnotationRoot)\n * @returns A partial Zod object schema where all fields are optional\n */\nexport function toPartialZodObject(\n schema: StateDefinitionInit\n): InteropZodObject {\n // Handle ZodObject directly\n if (isInteropZodObject(schema)) {\n return interopZodObjectPartial(schema);\n }\n\n // Handle StateSchema: convert fields to Zod shape, then make partial\n if (StateSchema.isInstance(schema)) {\n const partialShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(schema.fields)) {\n let fieldSchema: unknown;\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n fieldSchema = field.inputSchema || field.valueSchema;\n } else {\n fieldSchema = field;\n }\n // Only call .optional() on Zod v4 schemas, otherwise use z.any()\n partialShape[key] = isZodSchemaV4(fieldSchema)\n ? (fieldSchema as any).optional()\n : z.any().optional();\n }\n return z.object(partialShape);\n }\n\n // Fallback: return empty object schema\n return z.object({});\n}\n\n/**\n * Parse `jumpTo` target from user facing labels to a LangGraph node names\n */\nexport function parseJumpToTarget(target: string): JumpTo;\nexport function parseJumpToTarget(target?: string): JumpTo | undefined {\n if (!target) {\n return undefined;\n }\n\n /**\n * if target is already a valid jump target, return it\n */\n if ([\"model_request\", \"tools\", END].includes(target)) {\n return target as JumpTo;\n }\n\n if (target === \"model\") {\n return \"model_request\";\n }\n if (target === \"tools\") {\n return \"tools\";\n }\n if (target === \"end\") {\n return END;\n }\n\n throw new Error(\n `Invalid jump target: ${target}, must be \"model\", \"tools\" or \"end\".`\n );\n}\n\n/**\n * TypeScript currently doesn't support types for `AbortSignal.any`\n * @see https://github.com/microsoft/TypeScript/issues/60695\n */\ndeclare const AbortSignal: {\n any(signals: AbortSignal[]): AbortSignal;\n};\n\n/**\n * `config` always contains a signal from LangGraphs Pregel class.\n * To ensure we acknowledge the abort signal from the user, we merge it\n * with the signal from the ToolNode.\n *\n * @param signals - The signals to merge.\n * @returns The merged signal.\n */\nexport function mergeAbortSignals(\n ...signals: (AbortSignal | undefined)[]\n): AbortSignal {\n return AbortSignal.any(\n signals.filter(\n (maybeSignal): maybeSignal is AbortSignal =>\n maybeSignal !== null &&\n maybeSignal !== undefined &&\n typeof maybeSignal === \"object\" &&\n \"aborted\" in maybeSignal &&\n typeof maybeSignal.aborted === \"boolean\"\n )\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/agents/nodes/utils.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { z } from \"zod/v4\";\nimport { type BaseMessage } from \"@langchain/core/messages\";\nimport {\n getInteropZodObjectShape,\n interopSafeParseAsync,\n interopZodObjectMakeFieldsOptional,\n interopZodObjectPartial,\n isInteropZodObject,\n isZodSchemaV4,\n type InteropZodObject,\n} from \"@langchain/core/utils/types\";\nimport type { StateDefinitionInit } from \"@langchain/langgraph\";\nimport { END, StateSchema, ReducedValue } from \"@langchain/langgraph\";\n\nimport type { JumpTo } from \"../types.js\";\nimport type { AnyAgentMiddleware } from \"../middleware/types.js\";\n\n/**\n * Helper function to initialize middleware state defaults.\n * This is used to ensure all middleware state properties are initialized.\n *\n * Private properties (starting with _) are automatically made optional since\n * users cannot provide them when invoking the agent.\n */\nexport async function initializeMiddlewareStates(\n middlewareList: readonly AnyAgentMiddleware[],\n state: unknown\n): Promise<Record<string, any>> {\n const middlewareStates: Record<string, any> = {};\n\n for (const middleware of middlewareList) {\n /**\n * skip middleware if it doesn't have a state schema\n */\n if (!middleware.stateSchema) {\n continue;\n }\n\n // Convert StateSchema to Zod object if needed\n let zodSchema: InteropZodObject;\n if (StateSchema.isInstance(middleware.stateSchema)) {\n const zodShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(\n middleware.stateSchema.fields\n )) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n zodShape[key] = field.inputSchema || field.valueSchema;\n } else {\n zodShape[key] = field;\n }\n }\n zodSchema = z.object(zodShape);\n } else if (isInteropZodObject(middleware.stateSchema)) {\n zodSchema = middleware.stateSchema;\n } else {\n continue;\n }\n\n // Create a modified schema where private properties are optional\n const modifiedSchema = interopZodObjectMakeFieldsOptional(\n zodSchema,\n (key) => key.startsWith(\"_\")\n );\n\n // Use safeParse with the modified schema\n const parseResult = await interopSafeParseAsync(modifiedSchema, state);\n if (parseResult.success) {\n Object.assign(middlewareStates, parseResult.data);\n continue;\n }\n\n /**\n * If safeParse fails, there are required public fields missing.\n * Note: Zod v3 uses message \"Required\", Zod v4 uses \"Invalid input: expected X, received undefined\"\n */\n const requiredFields = parseResult.error.issues\n .filter((issue) => issue.code === \"invalid_type\")\n .map((issue) => ` - ${issue.path.join(\".\")}: Required`)\n .join(\"\\n\");\n\n throw new Error(\n `Middleware \"${middleware.name}\" has required state fields that must be initialized:\\n` +\n `${requiredFields}\\n\\n` +\n `To fix this, either:\\n` +\n `1. Provide default values in your middleware's state schema using .default():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().default(\"default value\")\\n` +\n ` })\\n\\n` +\n `2. Or make the fields optional using .optional():\\n` +\n ` stateSchema: z.object({\\n` +\n ` myField: z.string().optional()\\n` +\n ` })\\n\\n` +\n `3. Or ensure you pass these values when invoking the agent:\\n` +\n ` agent.invoke({\\n` +\n ` messages: [...],\\n` +\n ` ${parseResult.error.issues[0]?.path.join(\".\")}: \"value\"\\n` +\n ` })`\n );\n }\n\n return middlewareStates;\n}\n\n/**\n * Users can define private and public state for a middleware. Private state properties start with an underscore.\n * This function will return the private state properties from the state schema, making all of them optional.\n * @param stateSchema - The middleware state schema\n * @returns A new schema containing only the private properties (underscore-prefixed), all made optional\n */\nexport function derivePrivateState(\n stateSchema?: StateDefinitionInit\n): InteropZodObject {\n const builtInStateSchema = {\n messages: z.custom<BaseMessage[]>(() => []),\n // Include optional structuredResponse so after_agent hooks can access/modify it\n structuredResponse: z.any().optional(),\n };\n\n if (!stateSchema) {\n return z.object(builtInStateSchema);\n }\n\n // Extract shape from either StateSchema or Zod object\n let shape: Record<string, any>;\n if (StateSchema.isInstance(stateSchema)) {\n // For StateSchema, extract Zod schemas from fields\n shape = {};\n for (const [key, field] of Object.entries(stateSchema.fields)) {\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n shape[key] = field.inputSchema || field.valueSchema;\n } else {\n shape[key] = field;\n }\n }\n } else if (isInteropZodObject(stateSchema)) {\n shape = getInteropZodObjectShape(stateSchema);\n } else {\n return z.object(builtInStateSchema);\n }\n\n const privateShape: Record<string, any> = { ...builtInStateSchema };\n\n // Filter properties that start with underscore and make them optional\n for (const [key, value] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) {\n // Make the private property optional\n privateShape[key] = value.optional();\n } else {\n privateShape[key] = value;\n }\n }\n\n // Return a new schema with only private properties (all optional)\n return z.object(privateShape);\n}\n\n/**\n * Converts any supported schema type (ZodObject, StateSchema, AnnotationRoot) to a partial Zod object.\n * This is useful for parsing state loosely where all fields are optional.\n *\n * @param schema - The schema to convert (InteropZodObject, StateSchema, or AnnotationRoot)\n * @returns A partial Zod object schema where all fields are optional\n */\nexport function toPartialZodObject(\n schema: StateDefinitionInit\n): InteropZodObject {\n // Handle ZodObject directly\n if (isInteropZodObject(schema)) {\n return interopZodObjectPartial(schema);\n }\n\n // Handle StateSchema: convert fields to Zod shape, then make partial\n if (StateSchema.isInstance(schema)) {\n const partialShape: Record<string, any> = {};\n for (const [key, field] of Object.entries(schema.fields)) {\n let fieldSchema: unknown;\n if (ReducedValue.isInstance(field)) {\n // For ReducedValue, use inputSchema if available, otherwise valueSchema\n fieldSchema = field.inputSchema || field.valueSchema;\n } else {\n fieldSchema = field;\n }\n // Only call .optional() on Zod v4 schemas, otherwise use z.any()\n partialShape[key] = isZodSchemaV4(fieldSchema)\n ? (fieldSchema as any).optional()\n : z.any().optional();\n }\n return z.object(partialShape);\n }\n\n // Fallback: return empty object schema\n return z.object({});\n}\n\n/**\n * Parse `jumpTo` target from user facing labels to a LangGraph node names\n */\nexport function parseJumpToTarget(target: string): JumpTo;\nexport function parseJumpToTarget(target?: string): JumpTo | undefined {\n if (!target) {\n return undefined;\n }\n\n /**\n * if target is already a valid jump target, return it\n */\n if ([\"model_request\", \"tools\", END].includes(target)) {\n return target as JumpTo;\n }\n\n if (target === \"model\") {\n return \"model_request\";\n }\n if (target === \"tools\") {\n return \"tools\";\n }\n if (target === \"end\") {\n return END;\n }\n\n throw new Error(\n `Invalid jump target: ${target}, must be \"model\", \"tools\" or \"end\".`\n );\n}\n\n/**\n * TypeScript currently doesn't support types for `AbortSignal.any`\n * @see https://github.com/microsoft/TypeScript/issues/60695\n */\ndeclare const AbortSignal: {\n any(signals: AbortSignal[]): AbortSignal;\n};\n\n/**\n * `config` always contains a signal from LangGraphs Pregel class.\n * To ensure we acknowledge the abort signal from the user, we merge it\n * with the signal from the ToolNode.\n *\n * @param signals - The signals to merge.\n * @returns The merged signal.\n */\nexport function mergeAbortSignals(\n ...signals: (AbortSignal | undefined)[]\n): AbortSignal {\n return AbortSignal.any(\n signals.filter(\n (maybeSignal): maybeSignal is AbortSignal =>\n maybeSignal !== null &&\n maybeSignal !== undefined &&\n typeof maybeSignal === \"object\" &&\n \"aborted\" in maybeSignal &&\n typeof maybeSignal.aborted === \"boolean\"\n )\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
1
|
const require_model = require("./model.cjs");
|
|
3
2
|
const require_errors = require("./errors.cjs");
|
|
4
3
|
let _langchain_core_utils_types = require("@langchain/core/utils/types");
|
|
@@ -26,6 +25,9 @@ let bindingIdentifier = 0;
|
|
|
26
25
|
* corresponding tool implementation used by the tools strategy.
|
|
27
26
|
*/
|
|
28
27
|
var ToolStrategy = class ToolStrategy {
|
|
28
|
+
schema;
|
|
29
|
+
tool;
|
|
30
|
+
options;
|
|
29
31
|
constructor(schema, tool, options) {
|
|
30
32
|
this.schema = schema;
|
|
31
33
|
this.tool = tool;
|
|
@@ -44,7 +46,7 @@ var ToolStrategy = class ToolStrategy {
|
|
|
44
46
|
}
|
|
45
47
|
if ((0, _langchain_core_utils_standard_schema.isSerializableSchema)(schema) || (0, _langchain_core_utils_types.isInteropZodSchema)(schema)) {
|
|
46
48
|
const asJsonSchema = (0, _langchain_core_utils_json_schema.toJsonSchema)(schema);
|
|
47
|
-
|
|
49
|
+
const tool = {
|
|
48
50
|
type: "function",
|
|
49
51
|
function: {
|
|
50
52
|
name: getFunctionName(asJsonSchema.title),
|
|
@@ -52,7 +54,8 @@ var ToolStrategy = class ToolStrategy {
|
|
|
52
54
|
description: asJsonSchema.description ?? "Tool for extracting structured output from the model's response.",
|
|
53
55
|
parameters: asJsonSchema
|
|
54
56
|
}
|
|
55
|
-
}
|
|
57
|
+
};
|
|
58
|
+
return new ToolStrategy(asJsonSchema, tool, outputOptions);
|
|
56
59
|
}
|
|
57
60
|
let functionDefinition;
|
|
58
61
|
if (typeof schema.name === "string" && typeof schema.parameters === "object" && schema.parameters != null) functionDefinition = schema;
|
|
@@ -61,7 +64,8 @@ var ToolStrategy = class ToolStrategy {
|
|
|
61
64
|
description: schema.description ?? "",
|
|
62
65
|
parameters: schema.schema || schema
|
|
63
66
|
};
|
|
64
|
-
|
|
67
|
+
const asJsonSchema = (0, _langchain_core_utils_json_schema.toJsonSchema)(schema);
|
|
68
|
+
return new ToolStrategy(asJsonSchema, {
|
|
65
69
|
type: "function",
|
|
66
70
|
function: functionDefinition
|
|
67
71
|
}, outputOptions);
|
|
@@ -100,7 +104,8 @@ var ProviderStrategy = class ProviderStrategy {
|
|
|
100
104
|
}
|
|
101
105
|
}
|
|
102
106
|
static fromSchema(schema, strict) {
|
|
103
|
-
|
|
107
|
+
const asJsonSchema = (0, _langchain_core_utils_json_schema.toJsonSchema)(schema);
|
|
108
|
+
return new ProviderStrategy(asJsonSchema, strict);
|
|
104
109
|
}
|
|
105
110
|
/**
|
|
106
111
|
* Parse tool arguments according to the schema. If the response is not valid, return undefined.
|
|
@@ -269,6 +274,7 @@ function hasSupportForJsonSchemaOutput(model) {
|
|
|
269
274
|
//#endregion
|
|
270
275
|
exports.ProviderStrategy = ProviderStrategy;
|
|
271
276
|
exports.ToolStrategy = ToolStrategy;
|
|
277
|
+
exports.hasSupportForJsonSchemaOutput = hasSupportForJsonSchemaOutput;
|
|
272
278
|
exports.providerStrategy = providerStrategy;
|
|
273
279
|
exports.toolStrategy = toolStrategy;
|
|
274
280
|
exports.transformResponseFormat = transformResponseFormat;
|