diff --git a/lib/crewai-tools/src/crewai_tools/tools/docx_search_tool/docx_search_tool.py b/lib/crewai-tools/src/crewai_tools/tools/docx_search_tool/docx_search_tool.py index 77fecf473..b6bf94431 100644 --- a/lib/crewai-tools/src/crewai_tools/tools/docx_search_tool/docx_search_tool.py +++ b/lib/crewai-tools/src/crewai_tools/tools/docx_search_tool/docx_search_tool.py @@ -9,9 +9,6 @@ from crewai_tools.tools.rag.rag_tool import RagTool class FixedDOCXSearchToolSchema(BaseModel): """Input for DOCXSearchTool.""" - docx: str | None = Field( - ..., description="File path or URL of a DOCX file to be searched" - ) search_query: str = Field( ..., description="Mandatory search query you want to use to search the DOCX's content", @@ -21,10 +18,7 @@ class FixedDOCXSearchToolSchema(BaseModel): class DOCXSearchToolSchema(FixedDOCXSearchToolSchema): """Input for DOCXSearchTool.""" - search_query: str = Field( - ..., - description="Mandatory search query you want to use to search the DOCX's content", - ) + docx: str = Field(..., description="File path or URL of a DOCX file to be searched") class DOCXSearchTool(RagTool): diff --git a/lib/crewai-tools/tests/tools/test_docx_search_tool.py b/lib/crewai-tools/tests/tools/test_docx_search_tool.py new file mode 100644 index 000000000..d1a6705bf --- /dev/null +++ b/lib/crewai-tools/tests/tools/test_docx_search_tool.py @@ -0,0 +1,55 @@ +from typing import Any +from unittest.mock import patch +import pytest +from pydantic import ValidationError + +from crewai_tools.tools.docx_search_tool.docx_search_tool import ( + DOCXSearchTool, + DOCXSearchToolSchema, + FixedDOCXSearchToolSchema, +) + + +def test_fixed_docx_search_tool_schema() -> None: + """FixedDOCXSearchToolSchema should only require search_query.""" + data = FixedDOCXSearchToolSchema.model_validate({"search_query": "quarterly revenue"}) + assert data.search_query == "quarterly revenue" + + # Missing search_query should fail + with pytest.raises(ValidationError): + FixedDOCXSearchToolSchema.model_validate({}) + + +def test_docx_search_tool_schema() -> None: + """DOCXSearchToolSchema should require both docx and search_query.""" + data = DOCXSearchToolSchema.model_validate({ + "docx": "path/to/report.docx", + "search_query": "quarterly revenue", + }) + assert data.docx == "path/to/report.docx" + assert data.search_query == "quarterly revenue" + + # Missing docx should fail + with pytest.raises(ValidationError): + DOCXSearchToolSchema.model_validate({"search_query": "quarterly revenue"}) + + # Missing search_query should fail + with pytest.raises(ValidationError): + DOCXSearchToolSchema.model_validate({"docx": "path/to/report.docx"}) + + +def test_docx_search_tool_initialization_schemas() -> None: + """Verify tool args_schema matches initialization mode without requiring docx in fixed mode.""" + with patch.object(DOCXSearchTool, "add"): + # When initialized with a docx file (fixed mode), args_schema should be FixedDOCXSearchToolSchema + fixed_tool = DOCXSearchTool(docx="sample.docx") + assert fixed_tool.args_schema == FixedDOCXSearchToolSchema + + # Validating args without docx must succeed for fixed tool + validated: Any = fixed_tool.args_schema.model_validate({"search_query": "find revenue"}) + assert validated.search_query == "find revenue" + assert not hasattr(validated, "docx") + + # When initialized without a docx file, args_schema should be DOCXSearchToolSchema + dynamic_tool = DOCXSearchTool() + assert dynamic_tool.args_schema == DOCXSearchToolSchema