Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 10 additions & 15 deletions libs/langchain_v1/langchain/tools/tool_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -623,17 +623,9 @@ def _func(
)
tool_runtimes.append(tool_runtime)

# Inject tool arguments (including runtime)

injected_tool_calls = []
input_types = [input_type] * len(tool_calls)
for call, tool_runtime in zip(tool_calls, tool_runtimes, strict=False):
injected_call = self._inject_tool_args(call, tool_runtime) # type: ignore[arg-type]
injected_tool_calls.append(injected_call)
with get_executor_for_config(config) as executor:
outputs = list(
executor.map(self._run_one, injected_tool_calls, input_types, tool_runtimes)
)
outputs = list(executor.map(self._run_one, tool_calls, input_types, tool_runtimes))

return self._combine_tool_outputs(outputs, input_type)

Expand All @@ -660,12 +652,9 @@ async def _afunc(
)
tool_runtimes.append(tool_runtime)

injected_tool_calls = []
coros = []
for call, tool_runtime in zip(tool_calls, tool_runtimes, strict=False):
injected_call = self._inject_tool_args(call, tool_runtime) # type: ignore[arg-type]
injected_tool_calls.append(injected_call)
coros.append(self._arun_one(injected_call, input_type, tool_runtime)) # type: ignore[arg-type]
coros.append(self._arun_one(call, input_type, tool_runtime)) # type: ignore[arg-type]
outputs = await asyncio.gather(*coros)

return self._combine_tool_outputs(outputs, input_type)
Expand Down Expand Up @@ -742,12 +731,15 @@ def _execute_tool_sync(
msg = f"Tool {call['name']} is not registered with ToolNode"
raise TypeError(msg)

call_args = {**call, "type": "tool_call"}
# Inject state, store, and runtime right before invocation
injected_call = self._inject_tool_args(call, request.runtime)
call_args = {**injected_call, "type": "tool_call"}

try:
try:
response = tool.invoke(call_args, config)
except ValidationError as exc:
# Use original call["args"] without injected values for error reporting
raise ToolInvocationError(call["name"], exc, call["args"]) from exc

# GraphInterrupt is a special exception that will always be raised.
Expand Down Expand Up @@ -887,12 +879,15 @@ async def _execute_tool_async(
msg = f"Tool {call['name']} is not registered with ToolNode"
raise TypeError(msg)

call_args = {**call, "type": "tool_call"}
# Inject state, store, and runtime right before invocation
injected_call = self._inject_tool_args(call, request.runtime)
call_args = {**injected_call, "type": "tool_call"}

try:
try:
response = await tool.ainvoke(call_args, config)
except ValidationError as exc:
# Use original call["args"] without injected values for error reporting
raise ToolInvocationError(call["name"], exc, call["args"]) from exc

# GraphInterrupt is a special exception that will always be raised.
Expand Down
Loading
Loading