Skip to content

fix(toolbox-core): Prevent rebinding of parameters in ToolboxTool #186

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 12, 2025
Merged
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
5 changes: 5 additions & 0 deletions packages/toolbox-core/src/toolbox_core/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}")

Expand Down
30 changes: 27 additions & 3 deletions packages/toolbox-core/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down