From 58dd69f7f26fa967e438857f2f687b17e3e7dbe4 Mon Sep 17 00:00:00 2001 From: ccurme Date: Thu, 25 Jul 2024 12:46:36 -0400 Subject: [PATCH] core[patch]: fix mutating tool calls (#24677) In some cases tool calls are mutated when passed through a tool. --- libs/core/langchain_core/tools.py | 6 ++++-- libs/core/tests/unit_tests/test_tools.py | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libs/core/langchain_core/tools.py b/libs/core/langchain_core/tools.py index 85db1d3b92e..633faa7b343 100644 --- a/libs/core/langchain_core/tools.py +++ b/libs/core/langchain_core/tools.py @@ -20,6 +20,7 @@ tool for the job. from __future__ import annotations import asyncio +import copy import functools import inspect import json @@ -1481,8 +1482,9 @@ def _prep_run_args( ) -> Tuple[Union[str, Dict], Dict]: config = ensure_config(config) if _is_tool_call(input): - tool_call_id: Optional[str] = cast(ToolCall, input)["id"] - tool_input: Union[str, dict] = cast(ToolCall, input)["args"] + input_copy = copy.deepcopy(input) + tool_call_id: Optional[str] = cast(ToolCall, input_copy)["id"] + tool_input: Union[str, dict] = cast(ToolCall, input_copy)["args"] else: tool_call_id = None tool_input = cast(Union[str, dict], input) diff --git a/libs/core/tests/unit_tests/test_tools.py b/libs/core/tests/unit_tests/test_tools.py index 7f0fccbd050..489feeb7dca 100644 --- a/libs/core/tests/unit_tests/test_tools.py +++ b/libs/core/tests/unit_tests/test_tools.py @@ -977,6 +977,16 @@ class AFooBase(FooBase): def test_tool_pass_config(tool: BaseTool) -> None: assert tool.invoke({"bar": "baz"}, {"configurable": {"foo": "not-bar"}}) == "baz" + # Test tool calls + tool_call = { + "name": tool.name, + "args": {"bar": "baz"}, + "id": "abc123", + "type": "tool_call", + } + _ = tool.invoke(tool_call, {"configurable": {"foo": "not-bar"}}) + assert tool_call["args"] == {"bar": "baz"} + @pytest.mark.parametrize( "tool", [foo, afoo, simple_foo, asimple_foo, FooBase(), AFooBase()]