Make it clearer that Add commands view, not adding

This commit is contained in:
Amar Sood (tekacs) 2025-04-12 04:32:28 -04:00
parent dea5bd54f2
commit bbc16ca60a
2 changed files with 67 additions and 68 deletions

View file

@ -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

View file

@ -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 = """<context name="repo_map_status">
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.
</context>
"""
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 = """<context name="repo_map">