Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/codegen/extensions/langchain/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ class SearchInput(BaseModel):
description="""The search query to find in the codebase. When ripgrep is available, this will be passed as a ripgrep pattern. For regex searches, set use_regex=True.
Ripgrep is the preferred method.""",
)
target_directories: Optional[list[str]] = Field(default=None, description="Optional list of directories to search in")
file_extensions: Optional[list[str]] = Field(default=None, description="Optional list of file extensions to search (e.g. ['.py', '.ts'])")
page: int = Field(default=1, description="Page number to return (1-based, default: 1)")
files_per_page: int = Field(default=10, description="Number of files to return per page (default: 10)")
Expand All @@ -138,7 +137,7 @@ def __init__(self, codebase: Codebase) -> None:
super().__init__(codebase=codebase)

def _run(self, query: str, target_directories: Optional[list[str]] = None, file_extensions: Optional[list[str]] = None, page: int = 1, files_per_page: int = 10, use_regex: bool = False) -> str:
result = search(self.codebase, query, target_directories=target_directories, file_extensions=file_extensions, page=page, files_per_page=files_per_page, use_regex=use_regex)
result = search(self.codebase, query, file_extensions=file_extensions, page=page, files_per_page=files_per_page, use_regex=use_regex)
return result.render()


Expand Down
50 changes: 44 additions & 6 deletions src/codegen/extensions/tools/relace_edit_prompts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,31 @@

RELACE_EDIT_PROMPT = """Edit a file using the Relace Instant Apply API.

⚠️ IMPORTANT: The 'edit_snippet' parameter must be provided as a direct string, NOT as a dictionary or JSON object.
For example, use: edit_snippet="// ... code here ..." NOT edit_snippet={"code": "// ... code here ..."}
DO NOT pass the edit_snippet as a dictionary or JSON object or dictionary with a 'code' key .

The Relace Instant Apply API is a high-speed code generation engine optimized for real-time performance at 2000 tokens/second. It splits code generation into two specialized steps:

1. Hard Reasoning: Uses SOTA models like Claude for complex code understanding
2. Fast Integration: Rapidly merges edits into existing code

To use this tool, provide:
1. The path to the file you want to edit
2. An edit snippet that describes the changes you want to make
To use this tool effectively, provide:
1. The path to the file you want to edit (filepath)
2. An edit snippet that describes the changes you want to make (edit_snippet)

The edit snippet should:
The edit snippet is crucial for successful merging and should follow these guidelines:
- Include complete code blocks that will appear in the final output
- Clearly indicate which parts of the code remain unchanged with comments like "// ... rest of code ..."
- Maintain correct indentation and code structure
- Clearly indicate which parts of the code remain unchanged with descriptive comments like:
* "// ... keep existing imports ..."
* "// ... rest of the class definition ..."
* "// ... existing function implementations ..."
- Maintain correct indentation and code structure exactly as it should appear in the final code
- Use comments to indicate the purpose of your changes (e.g., "// Add new function")
- For removing sections, provide sufficient context so it's clear what should be removed
- Focus only on the modifications, not other aspects of the code
- Preserve language-specific syntax (comment style may vary by language)
- Include more context than just the minimal changes - surrounding code helps the API understand where and how to apply the edit

Example edit snippet:
```
Expand All @@ -28,7 +40,33 @@
// ... keep existing code ...
```

Another example (Python):
```
# ... existing imports ...

# Add new helper function
def validate_input(data):
'''Validates the input data structure.'''
if not isinstance(data, dict):
raise TypeError("Input must be a dictionary")
if "id" not in data:
raise ValueError("Input must contain an 'id' field")
return True

# ... rest of the file ...
```

The API will merge your edit snippet with the existing code to produce the final result.
The API key will be automatically retrieved from the RELACE_API environment variable.

Common pitfalls to avoid:
- Not providing enough context around changes
- Providing too little surrounding code (include more than just the changed lines)
- Incorrect indentation in the edit snippet
- Forgetting to indicate unchanged sections with comments
- Using inconsistent comment styles
- Being too vague about where changes should be applied
- Passing the edit_snippet as a dictionary or JSON object instead of a direct string
"""

RELACE_EDIT_SYSTEM_PROMPT = """You are an expert at creating edit snippets for the Relace Instant Apply API.
Expand Down
19 changes: 2 additions & 17 deletions src/codegen/extensions/tools/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ def render(self) -> str:
def _search_with_ripgrep(
codebase: Codebase,
query: str,
target_directories: Optional[list[str]] = None,
file_extensions: Optional[list[str]] = None,
page: int = 1,
files_per_page: int = 10,
Expand All @@ -141,9 +140,6 @@ def _search_with_ripgrep(

# Add target directories if specified
search_path = codebase.repo_path
if target_directories:
# We'll handle target directories by filtering results later
pass

# Add the query and path
cmd.append(f"{query}")
Expand Down Expand Up @@ -189,10 +185,6 @@ def _search_with_ripgrep(
# Convert to relative path within the codebase
rel_path = os.path.relpath(filepath, codebase.repo_path)

# Skip if not in target directories
if target_directories and not any(rel_path.startswith(d) for d in target_directories):
continue

try:
line_number = int(line_number_str)

Expand Down Expand Up @@ -264,7 +256,6 @@ def _search_with_ripgrep(
def _search_with_python(
codebase: Codebase,
query: str,
target_directories: Optional[list[str]] = None,
file_extensions: Optional[list[str]] = None,
page: int = 1,
files_per_page: int = 10,
Expand Down Expand Up @@ -304,10 +295,6 @@ def _search_with_python(

all_results = []
for file in codebase.files(extensions=extensions):
# Skip if file doesn't match target directories
if target_directories and not any(file.filepath.startswith(d) for d in target_directories):
continue

# Skip binary files
try:
content = file.content
Expand Down Expand Up @@ -366,7 +353,6 @@ def _search_with_python(
def search(
codebase: Codebase,
query: str,
target_directories: Optional[list[str]] = None,
file_extensions: Optional[list[str]] = None,
page: int = 1,
files_per_page: int = 10,
Expand All @@ -383,7 +369,6 @@ def search(
Args:
codebase: The codebase to operate on
query: The text to search for or regex pattern to match
target_directories: Optional list of directories to search in
file_extensions: Optional list of file extensions to search (e.g. ['.py', '.ts']).
If None, searches all files ('*')
page: Page number to return (1-based, default: 1)
Expand All @@ -395,7 +380,7 @@ def search(
"""
# Try to use ripgrep first
try:
return _search_with_ripgrep(codebase, query, target_directories, file_extensions, page, files_per_page, use_regex)
return _search_with_ripgrep(codebase, query, file_extensions, page, files_per_page, use_regex)
except (FileNotFoundError, subprocess.SubprocessError):
# Fall back to Python implementation if ripgrep fails or isn't available
return _search_with_python(codebase, query, target_directories, file_extensions, page, files_per_page, use_regex)
return _search_with_python(codebase, query, file_extensions, page, files_per_page, use_regex)
Loading