diff --git a/aider/coders/navigator_coder.py b/aider/coders/navigator_coder.py
index 8f8dcb616..9893929ba 100644
--- a/aider/coders/navigator_coder.py
+++ b/aider/coders/navigator_coder.py
@@ -522,31 +522,31 @@ class NavigatorCoder(Coder):
# Normalize tool name for case-insensitive matching
norm_tool_name = tool_name.lower()
- if norm_tool_name == 'glob':
+ if norm_tool_name == 'viewfilesatglob':
pattern = params.get('pattern')
if pattern is not None:
- result_message = self._execute_glob(pattern)
+ result_message = self._execute_view_files_at_glob(pattern)
else:
- result_message = "Error: Missing 'pattern' parameter for Glob"
- elif norm_tool_name == 'grep':
+ result_message = "Error: Missing 'pattern' parameter for ViewFilesAtGlob"
+ elif norm_tool_name == 'viewfilesmatching':
pattern = params.get('pattern')
file_pattern = params.get('file_pattern') # Optional
if pattern is not None:
- result_message = self._execute_grep(pattern, file_pattern)
+ result_message = self._execute_view_files_matching(pattern, file_pattern)
else:
- result_message = "Error: Missing 'pattern' parameter for Grep"
+ result_message = "Error: Missing 'pattern' parameter for ViewFilesMatching"
elif norm_tool_name == 'ls':
directory = params.get('directory')
if directory is not None:
result_message = self._execute_ls(directory)
else:
result_message = "Error: Missing 'directory' parameter for Ls"
- elif norm_tool_name == 'add':
+ elif norm_tool_name == 'view':
file_path = params.get('file_path')
if file_path is not None:
- result_message = self._execute_add(file_path)
+ result_message = self._execute_view(file_path)
else:
- result_message = "Error: Missing 'file_path' parameter for Add"
+ result_message = "Error: Missing 'file_path' parameter for View"
elif norm_tool_name == 'remove':
file_path = params.get('file_path')
if file_path is not None:
@@ -565,12 +565,12 @@ class NavigatorCoder(Coder):
result_message = self._execute_make_readonly(file_path)
else:
result_message = "Error: Missing 'file_path' parameter for MakeReadonly"
- elif norm_tool_name == 'find':
+ elif norm_tool_name == 'viewfileswithsymbol':
symbol = params.get('symbol')
if symbol is not None:
- result_message = self._execute_find(symbol)
+ result_message = self._execute_view_files_with_symbol(symbol)
else:
- result_message = "Error: Missing 'symbol' parameter for Find"
+ result_message = "Error: Missing 'symbol' parameter for ViewFilesWithSymbol"
elif norm_tool_name == 'command':
command_string = params.get('command_string')
if command_string is not None:
@@ -916,10 +916,10 @@ Just reply with fixed versions of the {blocks} above that failed to match.
return edited_files
- def _execute_glob(self, pattern):
+ def _execute_view_files_at_glob(self, pattern):
"""
- Execute a glob pattern and add matching files to context.
-
+ Execute a glob pattern and add matching files to context as read-only.
+
This tool helps the LLM find files by pattern matching, similar to
how a developer would use glob patterns to find files.
"""
@@ -965,13 +965,13 @@ Just reply with fixed versions of the {blocks} above that failed to match.
self.io.tool_output(f"⚠️ No files found matching '{pattern}'")
return f"No files found matching '{pattern}'"
except Exception as e:
- self.io.tool_error(f"Error in glob: {str(e)}")
+ self.io.tool_error(f"Error in ViewFilesAtGlob: {str(e)}")
return f"Error: {str(e)}"
-
- def _execute_grep(self, search_pattern, file_pattern=None):
+
+ def _execute_view_files_matching(self, search_pattern, file_pattern=None):
"""
- Search for pattern in files and add matching files to context.
-
+ Search for pattern in files and add matching files to context as read-only.
+
This tool lets the LLM search for content within files, mimicking
how a developer would use grep to find relevant code.
"""
@@ -1034,9 +1034,9 @@ Just reply with fixed versions of the {blocks} above that failed to match.
self.io.tool_output(f"⚠️ Pattern '{search_pattern}' not found in any files")
return f"Pattern not found in any files"
except Exception as e:
- self.io.tool_error(f"Error in grep: {str(e)}")
+ self.io.tool_error(f"Error in ViewFilesMatching: {str(e)}")
return f"Error: {str(e)}"
-
+
def _execute_ls(self, dir_path):
"""
List files in directory and optionally add some to context.
@@ -1083,27 +1083,28 @@ Just reply with fixed versions of the {blocks} above that failed to match.
except Exception as e:
self.io.tool_error(f"Error in ls: {str(e)}")
return f"Error: {str(e)}"
-
- def _execute_add(self, file_path):
+
+ def _execute_view(self, file_path):
"""
Explicitly add a file to context as read-only.
-
- This gives the LLM explicit control over what files to add,
+
+ This gives the LLM explicit control over what files to view,
rather than relying on indirect mentions.
"""
try:
- return self._add_file_to_context(file_path, True)
+ # Use the helper, marking it as an explicit view request
+ return self._add_file_to_context(file_path, explicit=True)
except Exception as e:
- self.io.tool_error(f"Error adding file: {str(e)}")
+ self.io.tool_error(f"Error viewing file: {str(e)}")
return f"Error: {str(e)}"
-
+
def _add_file_to_context(self, file_path, explicit=False):
"""
Helper method to add a file to context as read-only.
-
+
Parameters:
- file_path: Path to the file to add
- - explicit: Whether this was an explicit add command (vs. implicit through glob/grep)
+ - explicit: Whether this was an explicit view command (vs. implicit through ViewFilesAtGlob/ViewFilesMatching)
"""
# Check if file exists
abs_path = self.abs_root_path(file_path)
@@ -1144,22 +1145,22 @@ Just reply with fixed versions of the {blocks} above that failed to match.
# Add to read-only files
self.abs_read_only_fnames.add(abs_path)
-
+
# Track in exploration set
self.files_added_in_exploration.add(rel_path)
-
+
# Inform user
if explicit:
- self.io.tool_output(f"📎 Added '{file_path}' to context as read-only")
- return f"Added file to context as read-only"
+ self.io.tool_output(f"📎 Viewed '{file_path}' (added to context as read-only)")
+ return f"Viewed file (added to context as read-only)"
else:
- # For implicit adds (from glob/grep), just return success
+ # For implicit adds (from ViewFilesAtGlob/ViewFilesMatching), just return success
return f"Added file to context as read-only"
-
+
except Exception as e:
- self.io.tool_error(f"Error adding file '{file_path}': {str(e)}")
- return f"Error adding file: {str(e)}"
-
+ self.io.tool_error(f"Error adding file '{file_path}' for viewing: {str(e)}")
+ return f"Error adding file for viewing: {str(e)}"
+
def _execute_make_editable(self, file_path):
"""
Convert a read-only file to an editable file.
@@ -1266,17 +1267,17 @@ Just reply with fixed versions of the {blocks} above that failed to match.
self.io.tool_error(f"Error removing file: {str(e)}")
return f"Error: {str(e)}"
- def _execute_find(self, symbol):
+ def _execute_view_files_with_symbol(self, symbol):
"""
Find files containing a specific symbol and add them to context as read-only.
"""
try:
if not self.repo_map:
- self.io.tool_output("⚠️ Repo map not available, cannot use Find tool.")
+ self.io.tool_output("⚠️ Repo map not available, cannot use ViewFilesWithSymbol tool.")
return "Repo map not available"
if not symbol:
- return "Error: Missing 'symbol' parameter for Find"
+ return "Error: Missing 'symbol' parameter for ViewFilesWithSymbol"
self.io.tool_output(f"🔎 Searching for symbol '{symbol}'...")
found_files = set()
@@ -1337,7 +1338,7 @@ Just reply with fixed versions of the {blocks} above that failed to match.
return f"Symbol '{symbol}' not found in searchable files."
except Exception as e:
- self.io.tool_error(f"Error in find: {str(e)}")
+ self.io.tool_error(f"Error in ViewFilesWithSymbol: {str(e)}")
return f"Error: {str(e)}"
def _execute_command(self, command_string):
@@ -1407,19 +1408,17 @@ Just reply with fixed versions of the {blocks} above that failed to match.
# Get new files to add (not already in context)
new_files = mentioned_files - current_files
- # In navigator mode, we *only* add files via explicit tool commands.
+ # In navigator mode, we *only* add files via explicit tool commands (`View`, `ViewFilesAtGlob`, etc.).
# Do nothing here for implicit mentions.
pass
-
-
-
-
+
+
def check_for_file_mentions(self, content):
"""
Override parent's method to use our own file processing logic.
-
+
Override parent's method to disable implicit file mention handling in navigator mode.
- Files should only be added via explicit tool commands (`Add`, `Glob`, `Grep`).
+ Files should only be added via explicit tool commands (`View`, `ViewFilesAtGlob`, `ViewFilesMatching`, `ViewFilesWithSymbol`).
"""
# Do nothing - disable implicit file adds in navigator mode.
pass
diff --git a/aider/coders/navigator_prompts.py b/aider/coders/navigator_prompts.py
index 997dd49a4..9f2f8fd1d 100644
--- a/aider/coders/navigator_prompts.py
+++ b/aider/coders/navigator_prompts.py
@@ -31,23 +31,23 @@ Act as an expert software engineer with the ability to autonomously navigate and
## Available Tools
### File Discovery Tools
-- **Glob**: `[tool_call(Glob, pattern="**/*.py")]`
+- **ViewFilesAtGlob**: `[tool_call(ViewFilesAtGlob, pattern="**/*.py")]`
Find files matching a glob pattern and add them to context as read-only.
Supports patterns like "src/**/*.ts" or "*.json".
-- **Grep**: `[tool_call(Grep, pattern="class User", file_pattern="*.py")]`
+- **ViewFilesMatching**: `[tool_call(ViewFilesMatching, pattern="class User", file_pattern="*.py")]`
Search for text in files and add matching files to context as read-only.
Files with more matches are prioritized. `file_pattern` is optional.
- **Ls**: `[tool_call(Ls, directory="src/components")]`
List files in a directory. Useful for exploring the project structure.
-- **Find**: `[tool_call(Find, symbol="my_function")]`
+- **ViewFilesWithSymbol**: `[tool_call(ViewFilesWithSymbol, symbol="my_function")]`
Find files containing a specific symbol (function, class, variable) and add them to context as read-only.
Leverages the repo map for accurate symbol lookup.
### Context Management Tools
-- **Add**: `[tool_call(Add, file_path="src/main.py")]`
+- **View**: `[tool_call(View, file_path="src/main.py")]`
Explicitly add a specific file to context as read-only.
- **Remove**: `[tool_call(Remove, file_path="tests/old_test.py")]`
@@ -104,8 +104,8 @@ When you include any tool call, the system will automatically continue to the ne
## Navigation Workflow
### Exploration Strategy
-1. **Initial Discovery**: Use `Glob`, `Grep`, `Ls`, or `Find` to identify relevant files
-2. **Focused Investigation**: Add promising files to context with `Add`
+1. **Initial Discovery**: Use `ViewFilesAtGlob`, `ViewFilesMatching`, `Ls`, or `ViewFilesWithSymbol` to identify relevant files
+2. **Focused Investigation**: Add promising files to context with `View`
3. **Context Management**: Remove irrelevant files with `Remove` to maintain focus
4. **Preparation for Editing**: Convert files to editable with `MakeEditable` when needed
5. **Continued Exploration**: Include any tool call to automatically continue to the next round
@@ -114,16 +114,16 @@ When you include any tool call, the system will automatically continue to the ne
### Tool Usage Best Practices
- Use the exact syntax `[tool_call(ToolName, param1=value1, param2="value2")]` for execution
- Tool names are case-insensitive; parameters can be unquoted or quoted
-- Verify files aren't already in context before adding them
-- Use precise grep patterns with file_pattern to narrow search scope
+- Verify files aren't already in context before adding them with `View`
+- Use precise search patterns with `ViewFilesMatching` and `file_pattern` to narrow scope
- Target specific patterns rather than overly broad searches
-- Remember the `Find` tool is optimized for locating symbols across the codebase
+- Remember the `ViewFilesWithSymbol` tool is optimized for locating symbols across the codebase
## Granular Editing Workflow
**Note on Sequential Edits:** Tool calls within a single message execute sequentially. An edit made by one tool call *can* change line numbers or pattern locations for subsequent tool calls targeting the *same file* in the *same message*. Always check the result message and diff snippet after each edit.
-1. **Discover and Add Files**: Use Glob, Grep, Find to locate relevant files.
+1. **Discover and View Files**: Use `ViewFilesAtGlob`, `ViewFilesMatching`, `ViewFilesWithSymbol` to locate relevant files. Use `View` to add specific files.
2. **Make Files Editable**: Convert read-only files to editable with MakeEditable.
3. **Apply Edits (Default: Direct Edit)**:
* For most edits where you are confident in the parameters (file path, patterns, line numbers), apply the change directly using the tool with `dry_run=False` (or omitting the parameter).
@@ -255,19 +255,19 @@ Always reply to the user in {language}.
role="assistant",
content="""I'll help you understand the authentication system in this project. Let me explore the codebase first to find all relevant files.
-[tool_call(Grep, pattern="login|auth|password|session", file_pattern="*.py")]""",
+[tool_call(ViewFilesMatching, pattern="login|auth|password|session", file_pattern="*.py")]""",
),
dict(
role="user",
- content="[Result (Grep): Found in 3 files: auth/models.py (12 matches), auth/views.py (8 matches), users/authentication.py (5 matches)]",
+ content="[Result (ViewFilesMatching): Found in 3 files: auth/models.py (12 matches), auth/views.py (8 matches), users/authentication.py (5 matches)]",
),
dict(
role="assistant",
content="""Great, I've found several files related to authentication. Let me examine them to understand the login flow.
-[tool_call(Add, file_path="auth/models.py")]
-[tool_call(Add, file_path="auth/views.py")]
-[tool_call(Add, file_path="users/authentication.py")]""",
+[tool_call(View, file_path="auth/models.py")]
+[tool_call(View, file_path="auth/views.py")]
+[tool_call(View, file_path="users/authentication.py")]""",
),
dict(
role="user",
@@ -306,11 +306,11 @@ Trust this message as the true contents of the files!
files_no_full_files_with_repo_map = """
I have access to a map of the repository with summary information about files, but I don't have the complete content of any files yet.
-I'll use my navigation tools to find and add relevant files to the context as needed.
+I'll use my navigation tools (`ViewFilesAtGlob`, `ViewFilesMatching`, `ViewFilesWithSymbol`, `View`) to find and add relevant files to the context as needed.
"""
- files_no_full_files_with_repo_map_reply = """I understand. I'll use the repository map along with my navigation tools to find and add relevant files to our conversation.
+ files_no_full_files_with_repo_map_reply = """I understand. I'll use the repository map along with my navigation tools (`ViewFilesAtGlob`, `ViewFilesMatching`, `ViewFilesWithSymbol`, `View`) to find and add relevant files to our conversation.
"""
repo_content_prefix = """