From 7f4937a99219da34c815cc1a81d12a5743448d61 Mon Sep 17 00:00:00 2001 From: Hiren Date: Sat, 4 Apr 2026 18:13:07 -0400 Subject: [PATCH] fix: accept empty dict as valid tool_args in validate_tool_request --- agent.py | 2 +- tests/test_validate_tool_request.py | 42 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 tests/test_validate_tool_request.py diff --git a/agent.py b/agent.py index db7626b0eb..c18b56ccf1 100644 --- a/agent.py +++ b/agent.py @@ -978,7 +978,7 @@ async def validate_tool_request(self, tool_request: Any): raise ValueError("Tool request must be a dictionary") if not tool_request.get("tool_name") or not isinstance(tool_request.get("tool_name"), str): raise ValueError("Tool request must have a tool_name (type string) field") - if not tool_request.get("tool_args") or not isinstance(tool_request.get("tool_args"), dict): + if not isinstance(tool_request.get("tool_args"), dict): raise ValueError("Tool request must have a tool_args (type dictionary) field") diff --git a/tests/test_validate_tool_request.py b/tests/test_validate_tool_request.py new file mode 100644 index 0000000000..8a82118b16 --- /dev/null +++ b/tests/test_validate_tool_request.py @@ -0,0 +1,42 @@ +"""Test validate_tool_request handles empty tool_args correctly.""" +import asyncio +import pytest + + +# Inline the fixed logic to avoid importing the full agent (heavy deps) +async def validate_tool_request(tool_request): + if not isinstance(tool_request, dict): + raise ValueError("Tool request must be a dictionary") + if not tool_request.get("tool_name") or not isinstance(tool_request.get("tool_name"), str): + raise ValueError("Tool request must have a tool_name (type string) field") + if not isinstance(tool_request.get("tool_args"), dict): + raise ValueError("Tool request must have a tool_args (type dictionary) field") + + +@pytest.mark.asyncio +async def test_empty_tool_args_is_valid(): + """{} is valid - tools with no args should be accepted.""" + await validate_tool_request({"tool_name": "read_file", "tool_args": {}}) + + +@pytest.mark.asyncio +async def test_missing_tool_args_is_invalid(): + with pytest.raises(ValueError): + await validate_tool_request({"tool_name": "read_file"}) + + +@pytest.mark.asyncio +async def test_tool_args_wrong_type_is_invalid(): + with pytest.raises(ValueError): + await validate_tool_request({"tool_name": "read_file", "tool_args": "not a dict"}) + + +@pytest.mark.asyncio +async def test_normal_tool_args_is_valid(): + await validate_tool_request({"tool_name": "read_file", "tool_args": {"path": "/tmp/x"}}) + + +@pytest.mark.asyncio +async def test_tool_args_none_is_invalid(): + with pytest.raises(ValueError): + await validate_tool_request({"tool_name": "read_file", "tool_args": None})