Skip to content

Commit 5ef3dcd

Browse files
authored
fix: incorrect line number in output snippet for str_replace and insert (#110)
* fix incorrect line num in output snippet for `str_replace` and `insert` * bump to 0.2.9 * fix test
1 parent a09875e commit 5ef3dcd

File tree

4 files changed

+52
-15
lines changed

4 files changed

+52
-15
lines changed

openhands_aci/editor/editor.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
'str_replace',
2929
'insert',
3030
'undo_edit',
31-
# 'jump_to_definition', TODO:
32-
# 'find_references' TODO:
3331
]
3432

3533

@@ -60,9 +58,6 @@ def __init__(
6058
workspace_root: Root directory that serves as the current working directory for relative path
6159
suggestions. Must be an absolute path. If None, no path suggestions will be
6260
provided for relative paths.
63-
workspace_root: Root directory that serves as the current working directory for relative path
64-
suggestions. Must be an absolute path. If None, no path suggestions will be
65-
provided for relative paths.
6661
"""
6762
self._linter = DefaultLinter()
6863
self._history_manager = FileHistoryManager(max_history_per_file=10)
@@ -216,7 +211,7 @@ def str_replace(
216211
end_line = replacement_line + SNIPPET_CONTEXT_WINDOW + new_str.count('\n')
217212

218213
# Read just the snippet range
219-
snippet = self.read_file(path, start_line=start_line, end_line=end_line)
214+
snippet = self.read_file(path, start_line=start_line + 1, end_line=end_line)
220215

221216
# Prepare the success message
222217
success_message = f'The file {path} has been edited. '
@@ -428,12 +423,12 @@ def insert(
428423
shutil.move(temp_file.name, path)
429424

430425
# Read just the snippet range
431-
start_line = max(1, insert_line - SNIPPET_CONTEXT_WINDOW)
426+
start_line = max(0, insert_line - SNIPPET_CONTEXT_WINDOW)
432427
end_line = min(
433428
num_lines + len(new_str_lines),
434429
insert_line + SNIPPET_CONTEXT_WINDOW + len(new_str_lines),
435430
)
436-
snippet = self.read_file(path, start_line=start_line, end_line=end_line)
431+
snippet = self.read_file(path, start_line=start_line + 1, end_line=end_line)
437432

438433
# Save history - we already have the lines in memory
439434
file_text = ''.join(history_lines)
@@ -467,10 +462,6 @@ def validate_path(self, command: Command, path: Path) -> None:
467462
"""
468463
Check that the path/command combination is valid.
469464
470-
Validates:
471-
1. Path is absolute
472-
2. Path and command are compatible
473-
474465
Validates:
475466
1. Path is absolute
476467
2. Path and command are compatible
@@ -627,7 +618,7 @@ def _make_output(
627618
snippet_content = '\n'.join(
628619
[
629620
f'{i + start_line:6}\t{line}'
630-
for i, line in enumerate(snippet_content.split('\n'))
621+
for i, line in enumerate(snippet_content.splitlines())
631622
]
632623
)
633624
return (

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "openhands-aci"
3-
version = "0.2.8"
3+
version = "0.2.9"
44
description = "An Agent-Computer Interface (ACI) designed for software development agents OpenHands."
55
authors = ["OpenHands"]
66
license = "MIT"

tests/integration/editor/test_basic_operations.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ def test_file_editor_with_xml_tag_parsing(temp_file):
102102
5\t re.DOTALL,
103103
6\t)
104104
7\t...More text here.
105-
8\t
106105
"""
107106
)
108107

tests/integration/test_oh_editor.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ def test_str_replace_no_linting(editor):
100100
2\tThis file is for testing purposes.
101101
Review the changes and make sure they are as expected. Edit the file again if necessary."""
102102
)
103+
print(result.output)
103104

104105
# Test that the file content has been updated
105106
assert 'This is a sample file.' in test_file.read_text()
@@ -605,3 +606,49 @@ def test_validate_path_suggests_absolute_path(editor, tmp_path):
605606
suggested_path = error_message.split('Maybe you meant ')[1].strip('?')
606607
assert Path(suggested_path).is_absolute()
607608
assert str(test_file.parent) in suggested_path
609+
610+
611+
def test_str_replace_and_insert_snippet_output_on_a_large_file(editor):
612+
editor, test_file = editor
613+
614+
# Replace the current content with content: Line {line_number}
615+
_ = editor(
616+
command='str_replace',
617+
path=str(test_file),
618+
old_str='This is a test file.\nThis file is for testing purposes.',
619+
new_str='',
620+
)
621+
for i in range(0, 700):
622+
_ = editor(
623+
command='insert', path=str(test_file), insert_line=i, new_str=f'Line {i+1}'
624+
)
625+
626+
# View file
627+
result = editor(command='view', path=str(test_file))
628+
assert ' 1\tLine 1' in result.output
629+
assert ' 500\tLine 500' in result.output
630+
631+
# Replace line 500's content with '500 new'
632+
result = editor(
633+
command='str_replace',
634+
path=str(test_file),
635+
old_str='Line 500',
636+
new_str='500 new',
637+
)
638+
assert ' 500\t500 new' in result.output
639+
640+
# Delete the line '500 new'
641+
result = editor(
642+
command='str_replace', path=str(test_file), old_str='500 new\n', new_str=''
643+
)
644+
assert ' 499\tLine 499' in result.output
645+
assert ' 500\tLine 501' in result.output
646+
647+
# Insert content at line 500
648+
result = editor(
649+
command='insert',
650+
path=str(test_file),
651+
insert_line=499,
652+
new_str='Inserted line at 500',
653+
)
654+
assert ' 500\tInserted line at 500' in result.output

0 commit comments

Comments
 (0)