mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-21 22:08:21 +00:00
Add chunk reading functionality to FileReadTool (#266)
* Add chunk reading functionality to FileReadTool - Added start_line parameter to specify which line to start reading from - Added line_count parameter to specify how many lines to read - Updated documentation with new parameters and examples * [FIX] Bugs and Disscutions Fixed: start_line negative value Improved: File Reading Operations * [IMPROVE] Simplify line selection * [REFACTOR] use mock_open while preserving essential filesystem tests
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
# FileReadTool
|
||||
|
||||
## Description
|
||||
|
||||
The FileReadTool is a versatile component of the crewai_tools package, designed to streamline the process of reading and retrieving content from files. It is particularly useful in scenarios such as batch text file processing, runtime configuration file reading, and data importation for analytics. This tool supports various text-based file formats including `.txt`, `.csv`, `.json`, and adapts its functionality based on the file type, for instance, converting JSON content into a Python dictionary for easy use.
|
||||
|
||||
The tool also supports reading specific chunks of a file by specifying a starting line and the number of lines to read, which is helpful when working with large files that don't need to be loaded entirely into memory.
|
||||
|
||||
## Installation
|
||||
|
||||
Install the crewai_tools package to use the FileReadTool in your projects:
|
||||
|
||||
```shell
|
||||
@@ -11,6 +15,7 @@ pip install 'crewai[tools]'
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
To get started with the FileReadTool:
|
||||
|
||||
```python
|
||||
@@ -23,7 +28,13 @@ file_read_tool = FileReadTool()
|
||||
|
||||
# Initialize the tool with a specific file path, so the agent can only read the content of the specified file
|
||||
file_read_tool = FileReadTool(file_path='path/to/your/file.txt')
|
||||
|
||||
# Read a specific chunk of the file (lines 100-149)
|
||||
partial_content = file_read_tool.run(file_path='path/to/your/file.txt', start_line=100, line_count=50)
|
||||
```
|
||||
|
||||
## Arguments
|
||||
- `file_path`: The path to the file you want to read. It accepts both absolute and relative paths. Ensure the file exists and you have the necessary permissions to access it.
|
||||
|
||||
- `file_path`: The path to the file you want to read. It accepts both absolute and relative paths. Ensure the file exists and you have the necessary permissions to access it.
|
||||
- `start_line`: (Optional) The line number to start reading from (1-indexed). Defaults to 1 (the first line).
|
||||
- `line_count`: (Optional) The number of lines to read. If not provided, reads from the start_line to the end of the file.
|
||||
|
||||
@@ -8,6 +8,8 @@ class FileReadToolSchema(BaseModel):
|
||||
"""Input for FileReadTool."""
|
||||
|
||||
file_path: str = Field(..., description="Mandatory file full path to read the file")
|
||||
start_line: Optional[int] = Field(1, description="Line number to start reading from (1-indexed)")
|
||||
line_count: Optional[int] = Field(None, description="Number of lines to read. If None, reads the entire file")
|
||||
|
||||
|
||||
class FileReadTool(BaseTool):
|
||||
@@ -31,10 +33,11 @@ class FileReadTool(BaseTool):
|
||||
>>> 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
|
||||
>>> content = tool.run(file_path="/path/to/file.txt", start_line=100, line_count=50) # Reads lines 100-149
|
||||
"""
|
||||
|
||||
name: str = "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."
|
||||
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. Optionally, provide 'start_line' to start reading from a specific line and 'line_count' to limit the number of lines read."
|
||||
args_schema: Type[BaseModel] = FileReadToolSchema
|
||||
file_path: Optional[str] = None
|
||||
|
||||
@@ -47,8 +50,10 @@ class FileReadTool(BaseTool):
|
||||
**kwargs: Additional keyword arguments passed to BaseTool.
|
||||
"""
|
||||
if file_path is not None:
|
||||
kwargs['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."
|
||||
|
||||
kwargs["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. You can also specify 'start_line' and 'line_count' to read specific parts of the file."
|
||||
)
|
||||
|
||||
super().__init__(**kwargs)
|
||||
self.file_path = file_path
|
||||
|
||||
@@ -57,15 +62,34 @@ class FileReadTool(BaseTool):
|
||||
**kwargs: Any,
|
||||
) -> str:
|
||||
file_path = kwargs.get("file_path", self.file_path)
|
||||
start_line = kwargs.get("start_line", 1)
|
||||
line_count = kwargs.get("line_count", None)
|
||||
|
||||
if file_path is None:
|
||||
return "Error: No file path provided. Please provide a file path either in the constructor or as an argument."
|
||||
return (
|
||||
"Error: No file path provided. Please provide a file path either in the constructor or as an argument."
|
||||
)
|
||||
|
||||
try:
|
||||
with open(file_path, "r") as file:
|
||||
return file.read()
|
||||
if start_line == 1 and line_count is None:
|
||||
return file.read()
|
||||
|
||||
start_idx = max(start_line - 1, 0)
|
||||
|
||||
selected_lines = [
|
||||
line
|
||||
for i, line in enumerate(file)
|
||||
if i >= start_idx and (line_count is None or i < start_idx + line_count)
|
||||
]
|
||||
|
||||
if not selected_lines and start_idx > 0:
|
||||
return f"Error: Start line {start_line} exceeds the number of lines in the file."
|
||||
|
||||
return "".join(selected_lines)
|
||||
except FileNotFoundError:
|
||||
return f"Error: File not found at path: {file_path}"
|
||||
except PermissionError:
|
||||
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)}"
|
||||
return f"Error: Failed to read file {file_path}. {str(e)}"
|
||||
|
||||
Reference in New Issue
Block a user