Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Agent] Improve edits by adding back append_file #2722

Merged
merged 61 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
d3a2d10
add replace-based block edit & preliminary test case fix
xingyaoww Jun 28, 2024
b03fd2c
further fix the insert behavior
xingyaoww Jun 28, 2024
3700478
make edit only work on first occurence
xingyaoww Jun 28, 2024
8138371
bump codeact version since we now use new edit agentskills
xingyaoww Jun 28, 2024
45283e1
update prompt for new agentskills
xingyaoww Jun 28, 2024
790b94f
update integration tests
xingyaoww Jun 28, 2024
8e630c5
make run_infer.sh executable
xingyaoww Jun 28, 2024
693a53f
remove code block for edit_file
xingyaoww Jun 28, 2024
7fcba43
update integration test for prompt changes
xingyaoww Jun 28, 2024
22de134
default to not use hint for eval
xingyaoww Jun 29, 2024
4ec06f0
fix insert emptyfile bug
xingyaoww Jun 29, 2024
2c85f43
throw value error when `to_replace` is empty
xingyaoww Jun 29, 2024
621a158
make `_edit_or_insert_file` return string so we can try to fix some l…
xingyaoww Jun 29, 2024
4cb8bdb
add todo
xingyaoww Jun 29, 2024
20cdd32
update integration test
xingyaoww Jun 29, 2024
db14924
fix sandbox test for this PR
xingyaoww Jul 1, 2024
00f57e9
fix inserting with additional newline
xingyaoww Jul 1, 2024
a2f0916
rename to edit_file_by_replace
xingyaoww Jul 1, 2024
cbf2298
add back `edit_file_by_line`
xingyaoww Jul 1, 2024
fb0b9de
update prompt for new editing tool
xingyaoww Jul 1, 2024
cf9eef9
fix integration tests
xingyaoww Jul 1, 2024
a251122
bump codeact version since there are more changes
xingyaoww Jul 1, 2024
0aa476c
add back append file
xingyaoww Jul 1, 2024
ab47585
fix current line for append
xingyaoww Jul 1, 2024
eba37d5
fix append unit tests
xingyaoww Jul 1, 2024
22274be
change the location where we show edited line no to agent and fix tests
xingyaoww Jul 1, 2024
a45953d
update integration tests
xingyaoww Jul 2, 2024
f85c847
fix global window size affect by open_file bug
xingyaoww Jul 2, 2024
62480e5
fix global window size affect by open_file bug
xingyaoww Jul 2, 2024
8968e80
increase window size to 300
xingyaoww Jul 2, 2024
84b3358
add file beginning and ending marker to avoid looping
xingyaoww Jul 2, 2024
53ef016
Merge commit '41ddba84bd0d62f8a4bc48d08addde4b4269a687' into HEAD
xingyaoww Jul 2, 2024
26d9c90
expand the editor window to better display edit error for model
xingyaoww Jul 2, 2024
a4e41ed
refractor to breakdown edit to internal functions
xingyaoww Jul 2, 2024
eec2aa4
reduce window to 200
xingyaoww Jul 2, 2024
31ae269
move window to 100
xingyaoww Jul 2, 2024
53c36e1
refractor to cleanup some logic into _calculate_window_bounds
xingyaoww Jul 2, 2024
ef80308
Merge branch 'main' into xw/further-improve-edit
neubig Jul 3, 2024
e426298
fix integration tests
xingyaoww Jul 4, 2024
1d6a39e
fix sandbox test on new prompt
xingyaoww Jul 4, 2024
6bba835
update demonstration with new changes
xingyaoww Jul 4, 2024
738c657
fix integration
xingyaoww Jul 4, 2024
8fe5034
initialize llm inside process_instance to circumvent "AttributeError:…
xingyaoww Jul 5, 2024
d2a49aa
update kwargs
xingyaoww Jul 5, 2024
64938f5
retry for internal server error
xingyaoww Jul 5, 2024
21246fb
fix max iteration
xingyaoww Jul 5, 2024
f9cfecd
override max iter from config
xingyaoww Jul 5, 2024
4c6fa51
Merge commit 'adf1a0d55654d0065b615d0b4a6534cc5478b732' into xw/furth…
xingyaoww Jul 7, 2024
5247bfa
fix integration tests
xingyaoww Jul 7, 2024
949b38d
remove edit file by line
xingyaoww Jul 7, 2024
b4ac713
fix integration tests
xingyaoww Jul 7, 2024
06fd2c5
add instruction to avoid hanging
xingyaoww Jul 8, 2024
e690830
Revert "add instruction to avoid hanging"
xingyaoww Jul 9, 2024
57823b3
handle content policy violation error
xingyaoww Jul 10, 2024
5be8c05
Merge commit 'e6908307b436b07ede7ff3c093aa79db2ce6ee9c' into xw/furth…
xingyaoww Jul 10, 2024
7c67798
Merge commit '57823b3846cc297933282b181d6eed2c7511bcdc' into xw/furth…
xingyaoww Jul 10, 2024
8df6970
Merge commit '456690818c94a266935888f1e56e0afa2c4d5219' into xw/furth…
xingyaoww Jul 10, 2024
b474bbd
fix integration tests
xingyaoww Jul 10, 2024
f02c145
fix typo in prompt - the window is 100
xingyaoww Jul 11, 2024
5473bf8
update all integration tests
xingyaoww Jul 11, 2024
1204fe1
Merge branch 'main' into xw/further-improve-edit
xingyaoww Jul 11, 2024
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
Prev Previous commit
Next Next commit
fix inserting with additional newline
  • Loading branch information
xingyaoww committed Jul 1, 2024
commit 00f57e98be755788eb02920f4446dfc81dcd1c38
25 changes: 18 additions & 7 deletions opendevin/runtime/plugins/agent_skills/agentskills.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,13 +395,23 @@ def _edit_or_insert_file(
]
elif start is not None:
if len(lines) == 1 and lines[0].strip() == '':
# if the file is empty with only 1 line
lines = ['\n']
new_lines = (
lines[: start - 1]
+ [content + '\n' if not content.endswith('\n') else content]
+ lines[start - 1 :]
)
# if the file with only 1 line and that line is empty
lines = []

if len(lines) == 0:
new_lines = [
content + '\n' if not content.endswith('\n') else content
]
else:
new_lines = (
lines[: start - 1]
+ [
content + '\n'
if not content.endswith('\n')
else content
]
+ lines[start - 1 :]
)
else:
assert start is None
ret_str += (
Expand Down Expand Up @@ -522,6 +532,7 @@ def _edit_or_insert_file(
ret_str += f'[File: {os.path.abspath(file_name)} ({n_total_lines} lines total after edit)]\n'
CURRENT_FILE = file_name
ret_str += _print_window(CURRENT_FILE, CURRENT_LINE, WINDOW, return_str=True) + '\n'
ret_str += f'[File edited at line {CURRENT_LINE}.]\n'
ret_str += MSG_FILE_UPDATED
return ret_str

Expand Down
56 changes: 28 additions & 28 deletions tests/unit/test_agent_skill.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,8 @@ def test_edit_file(tmp_path):
f'[File: {temp_file_path} (3 lines total after edit)]\n'
'1|REPLACE TEXT\n'
'2|Line 4\n'
'3|Line 5\n' + MSG_FILE_UPDATED + '\n'
'3|Line 5\n'
'[File edited at line 1.]\n' + MSG_FILE_UPDATED + '\n'
)
assert result.split('\n') == expected.split('\n')

Expand Down Expand Up @@ -465,7 +466,8 @@ def test_edit_file_sameline(tmp_path):
'2|Line 2\n'
'3|REPLACE TEXT\n'
'4|Line 4\n'
'5|Line 5\n' + MSG_FILE_UPDATED + '\n'
'5|Line 5\n'
'[File edited at line 2.]\n' + MSG_FILE_UPDATED + '\n'
)
assert result.split('\n') == expected.split('\n')

Expand Down Expand Up @@ -500,7 +502,8 @@ def test_edit_file_multiline(tmp_path):
'2|REPLACE TEXT\n'
'3|Line 2\n'
'4|Line 4\n'
'5|Line 5\n' + MSG_FILE_UPDATED + '\n'
'5|Line 5\n'
'[File edited at line 2.]\n' + MSG_FILE_UPDATED + '\n'
)
assert result.split('\n') == expected.split('\n')

Expand Down Expand Up @@ -542,7 +545,8 @@ def test_insert_content_at_line(tmp_path):
'1|Line 1\n'
'2|Inserted Line\n'
'3|Line 2\n'
'4|Line 3\n' + MSG_FILE_UPDATED + '\n'
'4|Line 3\n'
'[File edited at line 2.]\n' + MSG_FILE_UPDATED + '\n'
)
assert result.split('\n') == expected.split('\n')

Expand All @@ -569,17 +573,16 @@ def test_insert_content_at_line_from_scratch(tmp_path):
)
result = buf.getvalue()
expected = (
f'[File: {temp_file_path} (2 lines total after edit)]\n'
f'[File: {temp_file_path} (1 lines total after edit)]\n'
'1|REPLACE TEXT\n'
'2|\n' + MSG_FILE_UPDATED + '\n'
'[File edited at line 1.]\n' + MSG_FILE_UPDATED + '\n'
)
assert result.split('\n') == expected.split('\n')

with open(temp_file_path, 'r') as file:
lines = file.readlines()
assert len(lines) == 2
assert len(lines) == 1
assert lines[0].rstrip() == 'REPLACE TEXT'
assert lines[1].rstrip() == ''


def test_insert_content_at_line_from_scratch_emptyfile(tmp_path):
Expand All @@ -598,7 +601,8 @@ def test_insert_content_at_line_from_scratch_emptyfile(tmp_path):
result = buf.getvalue()
expected = (
f'[File: {temp_file_path} (1 lines total after edit)]\n'
'1|REPLACE TEXT\n' + MSG_FILE_UPDATED + '\n'
'1|REPLACE TEXT\n'
'[File edited at line 1.]\n' + MSG_FILE_UPDATED + '\n'
)
assert result.split('\n') == expected.split('\n')

Expand Down Expand Up @@ -626,7 +630,8 @@ def test_insert_content_at_line_emptyline(tmp_path):
f'[File: {temp_file_path} (3 lines total after edit)]\n'
'1|Line 1\n'
'2|Inserted Line\n'
'3|\n' + MSG_FILE_UPDATED + '\n'
'3|\n'
'[File edited at line 2.]\n' + MSG_FILE_UPDATED + '\n'
)
assert result.split('\n') == expected.split('\n')

Expand All @@ -635,7 +640,6 @@ def test_insert_content_at_line_emptyline(tmp_path):
assert len(lines) == 3
assert lines[0].rstrip() == 'Line 1'
assert lines[1].rstrip() == 'Inserted Line'
assert lines[2].rstrip() == ''


def test_insert_content_at_line_from_scratch_multiline_with_backticks_and_second_edit(
Expand All @@ -654,21 +658,20 @@ def test_insert_content_at_line_from_scratch_multiline_with_backticks_and_second
)
result = buf.getvalue()
expected = (
f'[File: {temp_file_path} (4 lines total after edit)]\n'
f'[File: {temp_file_path} (3 lines total after edit)]\n'
'1|`REPLACE TEXT1`\n'
'2|`REPLACE TEXT2`\n'
'3|`REPLACE TEXT3`\n'
'4|\n' + MSG_FILE_UPDATED + '\n'
'[File edited at line 1.]\n' + MSG_FILE_UPDATED + '\n'
)
assert result.split('\n') == expected.split('\n')

with open(temp_file_path, 'r') as file:
lines = file.readlines()
assert len(lines) == 4
assert len(lines) == 3
assert lines[0].rstrip() == '`REPLACE TEXT1`'
assert lines[1].rstrip() == '`REPLACE TEXT2`'
assert lines[2].rstrip() == '`REPLACE TEXT3`'
assert lines[3].rstrip() == ''

# Check that no backticks are escaped in the edit_file call
assert '\\`' not in result
Expand All @@ -683,21 +686,20 @@ def test_insert_content_at_line_from_scratch_multiline_with_backticks_and_second
)
second_result = buf.getvalue()
second_expected = (
f'[File: {temp_file_path} (4 lines total after edit)]\n'
f'[File: {temp_file_path} (3 lines total after edit)]\n'
'1|`REPLACED TEXT1`\n'
'2|`REPLACED TEXT2`\n'
'3|`REPLACED TEXT3`\n'
'4|\n' + MSG_FILE_UPDATED + '\n'
'[File edited at line 1.]\n' + MSG_FILE_UPDATED + '\n'
)
assert second_result.split('\n') == second_expected.split('\n')

with open(temp_file_path, 'r') as file:
lines = file.readlines()
assert len(lines) == 4
assert len(lines) == 3
assert lines[0].rstrip() == '`REPLACED TEXT1`'
assert lines[1].rstrip() == '`REPLACED TEXT2`'
assert lines[2].rstrip() == '`REPLACED TEXT3`'
assert lines[3].rstrip() == ''

# Check that no backticks are escaped in the second edit_file call
assert '\\`' not in second_result
Expand All @@ -717,21 +719,20 @@ def test_insert_content_at_line_from_scratch_multiline(tmp_path):
)
result = buf.getvalue()
expected = (
f'[File: {temp_file_path} (4 lines total after edit)]\n'
f'[File: {temp_file_path} (3 lines total after edit)]\n'
'1|REPLACE TEXT1\n'
'2|REPLACE TEXT2\n'
'3|REPLACE TEXT3\n'
'4|\n' + MSG_FILE_UPDATED + '\n'
'[File edited at line 1.]\n' + MSG_FILE_UPDATED + '\n'
)
assert result.split('\n') == expected.split('\n')

with open(temp_file_path, 'r') as file:
lines = file.readlines()
assert len(lines) == 4
assert len(lines) == 3
assert lines[0].rstrip() == 'REPLACE TEXT1'
assert lines[1].rstrip() == 'REPLACE TEXT2'
assert lines[2].rstrip() == 'REPLACE TEXT3'
assert lines[3].rstrip() == ''


def test_insert_content_at_line_not_opened():
Expand Down Expand Up @@ -929,9 +930,9 @@ def test_edit_lint_file_pass(tmp_path, monkeypatch):
expected = (
f'[File: {file_path} (1 lines total)]\n'
'1|\n'
f'[File: {file_path} (2 lines total after edit)]\n'
f'[File: {file_path} (1 lines total after edit)]\n'
"1|print('hello')\n"
'2|\n' + MSG_FILE_UPDATED + '\n'
'[File edited at line 1.]\n' + MSG_FILE_UPDATED + '\n'
)
assert result.split('\n') == expected.split('\n')

Expand Down Expand Up @@ -961,7 +962,6 @@ def test_lint_file_fail_undefined_name(tmp_path, monkeypatch, capsys):
'[This is how your edit would have looked if applied]\n'
'-------------------------------------------------\n'
'1|undefined_name()\n'
'2|\n'
'-------------------------------------------------\n\n'
'[This is the original code before your edit]\n'
'-------------------------------------------------\n'
Expand Down Expand Up @@ -1038,9 +1038,9 @@ def test_lint_file_disabled_undefined_name(tmp_path, monkeypatch, capsys):
expected = (
f'[File: {file_path} (1 lines total)]\n'
'1|\n'
f'[File: {file_path} (2 lines total after edit)]\n'
f'[File: {file_path} (1 lines total after edit)]\n'
'1|undefined_name()\n'
'2|\n' + MSG_FILE_UPDATED + '\n'
'[File edited at line 1.]\n' + MSG_FILE_UPDATED + '\n'
)
assert result.split('\n') == expected.split('\n')

Expand Down