Skip to content

Commit f42cb2d

Browse files
joaomdmouraclaude
andcommitted
fix(tools): tell the LLM about the path sandbox in tool descriptions
Addresses the low-confidence notes from the Copilot review on #6692. Both tools' descriptions were pre-sandbox wording, so the model learned about containment only by attempting a path and reading the error back. Both now state that access is confined to the tool's allowed directory and that a path resolving outside it is rejected. The wording deliberately says "the tool's allowed directory" rather than "the working directory", because the root is base_dir when one is set, and naming the absolute root would leak it into the prompt — the same reason paths are redacted in errors. Not changed: the notes also suggested advertising `encoding`. That is a constructor-only field the model cannot set, so describing it to the LLM would be misleading. Also fixes a test docstring that contradicted its own assertion — the public run() path does raise on schema validation failure, which is what the test asserts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 7f35b76 commit f42cb2d

4 files changed

Lines changed: 6 additions & 6 deletions

File tree

lib/crewai-tools/src/crewai_tools/tools/file_read_tool/file_read_tool.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class FileReadTool(BaseTool):
9191
"""
9292

9393
name: str = "Read a file's content"
94-
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."
94+
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. Reads are confined to the tool's allowed directory; a path that resolves outside it is rejected. Optionally, provide 'start_line' to start reading from a specific line and 'line_count' to limit the number of lines read."
9595
args_schema: type[BaseModel] = FileReadToolSchema
9696
file_path: str | None = None
9797
base_dir: str | None = None
@@ -124,7 +124,7 @@ def __init__(
124124
if file_path is not None:
125125
display_path = format_path_for_display(file_path, base_dir)
126126
kwargs["description"] = (
127-
f"A tool that reads file content. The default file is {display_path}, which is read when 'file_path' is omitted. You can also provide a different 'file_path' parameter to read another file, and specify 'start_line' and 'line_count' to read specific parts of the file."
127+
f"A tool that reads file content. The default file is {display_path}, which is read when 'file_path' is omitted. You can also provide a different 'file_path' parameter to read another file, though reads are confined to the tool's allowed directory and a path that resolves outside it is rejected. Specify 'start_line' and 'line_count' to read specific parts of the file."
128128
)
129129

130130
super().__init__(**kwargs)

lib/crewai-tools/src/crewai_tools/tools/file_writer_tool/file_writer_tool.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class FileWriterTool(BaseTool):
8181
"""
8282

8383
name: str = "File Writer Tool"
84-
description: str = "A tool to write content to a specified file. Accepts filename, content, and optionally a directory path and overwrite flag as input."
84+
description: str = "A tool to write content to a specified file. Accepts filename, content, and optionally a directory path and overwrite flag as input. Writes are confined to the tool's allowed directory; a filename or directory that resolves outside it is rejected."
8585
args_schema: type[BaseModel] = FileWriterToolInput
8686
base_dir: str | None = None
8787
encoding: str = "utf-8"

lib/crewai-tools/tests/tools/test_file_writer_tool.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def test_missing_required_fields(tool, temp_env):
110110

111111

112112
def test_missing_required_fields_via_run(tool, temp_env):
113-
"""The public entry point reports schema violations instead of raising."""
113+
"""The public entry point fails schema validation before reaching _run."""
114114
with pytest.raises(ValueError, match="validation failed"):
115115
tool.run(
116116
directory=temp_env["temp_dir"],

lib/crewai-tools/tool.specs.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9931,7 +9931,7 @@
99319931
}
99329932
},
99339933
{
9934-
"description": "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.",
9934+
"description": "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. Reads are confined to the tool's allowed directory; a path that resolves outside it is rejected. Optionally, provide 'start_line' to start reading from a specific line and 'line_count' to limit the number of lines read.",
99359935
"env_vars": [],
99369936
"humanized_name": "Read a file's content",
99379937
"init_params_schema": {
@@ -10058,7 +10058,7 @@
1005810058
}
1005910059
},
1006010060
{
10061-
"description": "A tool to write content to a specified file. Accepts filename, content, and optionally a directory path and overwrite flag as input.",
10061+
"description": "A tool to write content to a specified file. Accepts filename, content, and optionally a directory path and overwrite flag as input. Writes are confined to the tool's allowed directory; a filename or directory that resolves outside it is rejected.",
1006210062
"env_vars": [],
1006310063
"humanized_name": "File Writer Tool",
1006410064
"init_params_schema": {

0 commit comments

Comments
 (0)