diff --git a/packages/toolbox-core/src/toolbox_core/tool.py b/packages/toolbox-core/src/toolbox_core/tool.py index d9c0d0fe..ba006e5d 100644 --- a/packages/toolbox-core/src/toolbox_core/tool.py +++ b/packages/toolbox-core/src/toolbox_core/tool.py @@ -316,6 +316,11 @@ def bind_parameters( """ param_names = set(p.name for p in self.__params) for name in bound_params.keys(): + if name in self.__bound_parameters: + raise ValueError( + f"cannot re-bind parameter: parameter '{name}' is already bound" + ) + if name not in param_names: raise Exception(f"unable to bind parameters: no parameter named {name}") diff --git a/packages/toolbox-core/tests/test_client.py b/packages/toolbox-core/tests/test_client.py index e6d12a0c..e05445f8 100644 --- a/packages/toolbox-core/tests/test_client.py +++ b/packages/toolbox-core/tests/test_client.py @@ -431,14 +431,38 @@ async def test_bind_callable_param_success(self, tool_name, client): @pytest.mark.asyncio async def test_bind_param_fail(self, tool_name, client): - """Tests 'bind_param' with a bound parameter that doesn't exist.""" + """Tests 'bind_parameters' with a bound parameter that doesn't exist.""" tool = await client.load_tool(tool_name) assert len(tool.__signature__.parameters) == 2 assert "argA" in tool.__signature__.parameters - with pytest.raises(Exception): - tool = tool.bind_parameters({"argC": lambda: 5}) + with pytest.raises(Exception) as e: + tool.bind_parameters({"argC": lambda: 5}) + assert "unable to bind parameters: no parameter named argC" in str(e.value) + + @pytest.mark.asyncio + async def test_rebind_param_fail(self, tool_name, client): + """ + Tests that 'bind_parameters' fails when attempting to re-bind a + parameter that has already been bound. + """ + tool = await client.load_tool(tool_name) + + assert len(tool.__signature__.parameters) == 2 + assert "argA" in tool.__signature__.parameters + + tool_with_bound_param = tool.bind_parameters({"argA": lambda: 10}) + + assert len(tool_with_bound_param.__signature__.parameters) == 1 + assert "argA" not in tool_with_bound_param.__signature__.parameters + + with pytest.raises(ValueError) as e: + tool_with_bound_param.bind_parameters({"argA": lambda: 20}) + + assert "cannot re-bind parameter: parameter 'argA' is already bound" in str( + e.value + ) @pytest.mark.asyncio async def test_bind_param_static_value_success(self, tool_name, client):