From d3391d9ba4c1b3696dbbe7188aa59e6dc6ce8761 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sat, 28 Dec 2024 23:10:51 +0000 Subject: [PATCH] Add comprehensive documentation and type hints to FileReadTool Co-Authored-By: Joe Moura --- .../tools/file_read_tool/file_read_tool.py | 49 +++++++++++++++++-- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/src/crewai_tools/tools/file_read_tool/file_read_tool.py b/src/crewai_tools/tools/file_read_tool/file_read_tool.py index 32db13f21..323a26d51 100644 --- a/src/crewai_tools/tools/file_read_tool/file_read_tool.py +++ b/src/crewai_tools/tools/file_read_tool/file_read_tool.py @@ -11,22 +11,49 @@ class FileReadToolSchema(BaseModel): class FileReadTool(BaseTool): + """A tool for reading file contents. + + This tool inherits its schema handling from BaseTool to avoid recursive schema + definition issues. The args_schema is set to FileReadToolSchema which defines + the required file_path parameter. The schema should not be overridden in the + constructor as it would break the inheritance chain and cause infinite loops. + + The tool supports two ways of specifying the file path: + 1. At construction time via the file_path parameter + 2. At runtime via the file_path parameter in the tool's input + + Args: + file_path (Optional[str]): Path to the file to be read. If provided, + this becomes the default file path for the tool. + **kwargs: Additional keyword arguments passed to BaseTool. + + Example: + >>> tool = FileReadTool(file_path="/path/to/file.txt") + >>> content = tool.run() # Reads /path/to/file.txt + >>> content = tool.run(file_path="/path/to/other.txt") # Reads other.txt + """ name: str = "Read a file's content" - description: str = "A tool that can be used to read a file's content." + description: str = "A tool that reads the content of a file. To use this tool, provide a 'file_path' parameter with the path to the file you want to read." args_schema: Type[BaseModel] = FileReadToolSchema file_path: Optional[str] = None - def __init__(self, file_path: Optional[str] = None, **kwargs): + def __init__(self, file_path: Optional[str] = None, **kwargs: Any) -> None: + """Initialize the FileReadTool. + + Args: + file_path (Optional[str]): Path to the file to be read. If provided, + this becomes the default file path for the tool. + **kwargs: Additional keyword arguments passed to BaseTool. + """ super().__init__(**kwargs) if file_path is not None: self.file_path = file_path - self.description = f"A tool that can be used to read {file_path}'s content." - self._generate_description() + self.description = f"A tool that reads file content. The default file is {file_path}, but you can provide a different 'file_path' parameter to read another file." def _run( self, **kwargs: Any, - ) -> Any: + ) -> str: file_path = kwargs.get("file_path", self.file_path) if file_path is None: return "Error: No file path provided. Please provide a file path either in the constructor or as an argument." @@ -40,3 +67,15 @@ class FileReadTool(BaseTool): return f"Error: Permission denied when trying to read file: {file_path}" except Exception as e: return f"Error: Failed to read file {file_path}. {str(e)}" + + def _generate_description(self) -> None: + """Generate the tool description based on file path. + + This method updates the tool's description to include information about + the default file path while maintaining the ability to specify a different + file at runtime. + + Returns: + None + """ + self.description = f"A tool that can be used to read {self.file_path}'s content."