mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-04-30 23:02:50 +00:00
fix: validate tool kwargs even when empty to prevent cryptic TypeError (#4611)
This commit is contained in:
@@ -18,7 +18,6 @@ from pydantic import (
|
||||
BaseModel as PydanticBaseModel,
|
||||
ConfigDict,
|
||||
Field,
|
||||
ValidationError,
|
||||
create_model,
|
||||
field_validator,
|
||||
)
|
||||
@@ -163,7 +162,7 @@ class BaseTool(BaseModel, ABC):
|
||||
Raises:
|
||||
ValueError: If validation against args_schema fails.
|
||||
"""
|
||||
if kwargs and self.args_schema is not None and self.args_schema.model_fields:
|
||||
if self.args_schema is not None and self.args_schema.model_fields:
|
||||
try:
|
||||
validated = self.args_schema.model_validate(kwargs)
|
||||
return validated.model_dump()
|
||||
@@ -178,7 +177,8 @@ class BaseTool(BaseModel, ABC):
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
) -> Any:
|
||||
kwargs = self._validate_kwargs(kwargs)
|
||||
if not args:
|
||||
kwargs = self._validate_kwargs(kwargs)
|
||||
|
||||
result = self._run(*args, **kwargs)
|
||||
|
||||
@@ -203,7 +203,8 @@ class BaseTool(BaseModel, ABC):
|
||||
Returns:
|
||||
The result of the tool execution.
|
||||
"""
|
||||
kwargs = self._validate_kwargs(kwargs)
|
||||
if not args:
|
||||
kwargs = self._validate_kwargs(kwargs)
|
||||
result = await self._arun(*args, **kwargs)
|
||||
self.current_usage_count += 1
|
||||
return result
|
||||
@@ -356,7 +357,8 @@ class Tool(BaseTool, Generic[P, R]):
|
||||
Returns:
|
||||
The result of the tool execution.
|
||||
"""
|
||||
kwargs = self._validate_kwargs(kwargs)
|
||||
if not args:
|
||||
kwargs = self._validate_kwargs(kwargs) # type: ignore[assignment]
|
||||
|
||||
result = self.func(*args, **kwargs)
|
||||
|
||||
@@ -388,7 +390,8 @@ class Tool(BaseTool, Generic[P, R]):
|
||||
Returns:
|
||||
The result of the tool execution.
|
||||
"""
|
||||
kwargs = self._validate_kwargs(kwargs)
|
||||
if not args:
|
||||
kwargs = self._validate_kwargs(kwargs) # type: ignore[assignment]
|
||||
result = await self._arun(*args, **kwargs)
|
||||
self.current_usage_count += 1
|
||||
return result
|
||||
|
||||
@@ -268,6 +268,13 @@ class TestBaseToolRunValidation:
|
||||
result = t.run(code="console.log('hi')", language="javascript")
|
||||
assert result == "Executed javascript: console.log('hi')"
|
||||
|
||||
def test_run_with_no_args_raises_validation_error(self) -> None:
|
||||
"""Calling run() with no arguments should raise a clear ValueError,
|
||||
not a cryptic TypeError about missing positional arguments (GH-4611)."""
|
||||
t = CodeExecutorTool()
|
||||
with pytest.raises(ValueError, match="validation failed"):
|
||||
t.run()
|
||||
|
||||
def test_run_with_missing_required_kwarg_raises(self) -> None:
|
||||
"""Missing required kwargs should raise ValueError from schema validation."""
|
||||
t = CodeExecutorTool()
|
||||
@@ -378,6 +385,13 @@ class TestBaseToolArunValidation:
|
||||
result = await t.arun(code="print('hello')")
|
||||
assert result == "Async executed python: print('hello')"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_arun_with_no_args_raises_validation_error(self) -> None:
|
||||
"""Calling arun() with no arguments should raise a clear ValueError (GH-4611)."""
|
||||
t = AsyncCodeExecutorTool()
|
||||
with pytest.raises(ValueError, match="validation failed"):
|
||||
await t.arun()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_arun_with_missing_required_kwarg_raises(self) -> None:
|
||||
"""Missing required kwargs should raise ValueError in arun."""
|
||||
|
||||
Reference in New Issue
Block a user