Skip to content

Commit

Permalink
Validate to_replace in edit_file_by_replace AgentSkill (All-Hands-AI#…
Browse files Browse the repository at this point in the history
…3073)

* Validate to_replace in edit_file_by_replace AgentSkill

* Remove redundant replace reminder prompt

* Add unit tests

* Fix prompt
  • Loading branch information
li-boxuan authored Jul 23, 2024
1 parent 41a8bb3 commit 445f290
Show file tree
Hide file tree
Showing 34 changed files with 84 additions and 92 deletions.
9 changes: 8 additions & 1 deletion opendevin/runtime/plugins/agent_skills/agentskills.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,6 @@ def edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> N
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
Expand Down Expand Up @@ -650,12 +649,20 @@ def edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> N
if to_replace.strip() == '':
raise ValueError('`to_replace` must not be empty.')

if to_replace == new_content:
raise ValueError('`to_replace` and `new_content` must be different.')

# search for `to_replace` in the file
# if found, replace it with `new_content`
# if not found, perform a fuzzy search to find the closest match and replace it with `new_content`
with open(file_name, 'r') as file:
file_content = file.read()

if file_content.count(to_replace) > 1:
raise ValueError(
'`to_replace` appears more than once, please include enough lines to make code in `to_replace` unique.'
)

start = file_content.find(to_replace)
if start != -1:
# Convert start from index to line number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
59 changes: 29 additions & 30 deletions tests/integration/mock/CodeActSWEAgent/test_edits/prompt_005.log
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down Expand Up @@ -602,13 +601,13 @@ open_file("bad.txt")
----------

OBSERVATION:
[File: /workspace/bad.txt (4 lines total)]
(this is the beginning of the file)
1|This is a stupid typoo.
2|Really?
3|No mor typos!
4|Enjoy!
(this is the end of the file)
[File: /workspace/bad.txt (4 lines total)]
(this is the beginning of the file)
1|This is a stupid typoo.
2|Really?
3|No mor typos!
4|Enjoy!
(this is the end of the file)


----------
Expand All @@ -630,12 +629,12 @@ edit_file_by_replace(
----------

OBSERVATION:
[No exact match found in bad.txt for
```
This is a stupid typoo.
No mor typos!
```
]
[No exact match found in bad.txt for
```
This is a stupid typoo.
No mor typos!
```
]


----------
Expand All @@ -657,14 +656,14 @@ edit_file_by_replace(
----------

OBSERVATION:
[File: /workspace/bad.txt (4 lines total after edit)]
(this is the beginning of the file)
1|This is a stupid typo.
2|Really?
3|No mor typos!
4|Enjoy!
(this is the end of the file)
[File updated (edited at line 1). Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.]
[File: /workspace/bad.txt (4 lines total after edit)]
(this is the beginning of the file)
1|This is a stupid typo.
2|Really?
3|No mor typos!
4|Enjoy!
(this is the end of the file)
[File updated (edited at line 1). Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.]


----------
Expand All @@ -681,14 +680,14 @@ edit_file_by_replace(
----------

OBSERVATION:
[File: /workspace/bad.txt (4 lines total after edit)]
(this is the beginning of the file)
1|This is a stupid typo.
2|Really?
3|No more typos!
4|Enjoy!
(this is the end of the file)
[File updated (edited at line 3). Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.]
[File: /workspace/bad.txt (4 lines total after edit)]
(this is the beginning of the file)
1|This is a stupid typo.
2|Really?
3|No more typos!
4|Enjoy!
(this is the end of the file)
[File updated (edited at line 3). Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.]


ENVIRONMENT REMINDER: You have 10 turns left to complete the task.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None:
Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`.
Every *to_replace* must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
Include enough lines to make code in `to_replace` unique. `to_replace` should NOT be empty.
`edit_file_by_replace` will only replace the *first* matching occurrences.
For example, given a file "/workspace/example.txt" with the following content:
```
line 1
Expand Down
Loading

0 comments on commit 445f290

Please sign in to comment.