feat: append_file incl. all tests [agentskills] (#2346)

* new skill: append_file incl. all tests

* more tests needed caring

* file_name for append_file/edit_file; updated tests
This commit is contained in:
tobitege
2024-06-10 19:18:40 +02:00
committed by GitHub
parent a5f5bc30b4
commit 9605106e72
20 changed files with 525 additions and 153 deletions

View File

@@ -5,7 +5,7 @@ _AGENT_SKILLS_DOCS = AgentSkillsRequirement.documentation
COMMAND_DOCS = (
'\nApart from the standard Python library, the assistant can also use the following functions (already imported) in <execute_ipython> environment:\n'
f'{_AGENT_SKILLS_DOCS}'
"Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run."
"Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run."
)
# ======= SYSTEM MESSAGE =======
@@ -74,7 +74,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)\"\"\"
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -213,7 +213,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:

View File

@@ -12,13 +12,15 @@ Functions:
- search_dir(search_term, dir_path='./'): Searches for a term in all files in the specified directory.
- search_file(search_term, file_path=None): Searches for a term in the specified file or the currently open file.
- find_file(file_name, dir_path='./'): Finds all files with the given name in the specified directory.
- edit_file(start, end, content): Replaces lines in a file with the given content.
- edit_file(file_name, start, end, content): Replaces lines in a file with the given content.
- append_file(file_name, content): Appends given content to a file.
"""
import base64
import functools
import os
import subprocess
import tempfile
from inspect import signature
from typing import Optional
@@ -66,12 +68,13 @@ def update_pwd_decorator(func):
return wrapper
def _lint_file(file_path: str) -> Optional[str]:
def _lint_file(file_path: str) -> tuple[Optional[str], Optional[int]]:
"""
Lint the file at the given path.
Lint the file at the given path and return a tuple with a boolean indicating if there are errors,
and the line number of the first error, if any.
Returns:
Optional[str]: A string containing the linting report if the file failed to lint, None otherwise.
tuple[str, Optional[int]]: (lint_error, first_error_line_number)
"""
if file_path.endswith('.py'):
@@ -91,13 +94,28 @@ def _lint_file(file_path: str) -> Optional[str]:
)
if result.returncode == 0:
# Linting successful. No issues found.
return None
else:
ret = 'ERRORS:\n'
ret += result.stdout.decode().strip()
return ret.rstrip('\n')
return None, None
# Extract the line number from the first error message
error_message = result.stdout.decode().strip()
lint_error = 'ERRORS:\n' + error_message
first_error_line = None
for line in error_message.split('\n'):
if line.strip():
# The format of the error message is: <filename>:<line>:<column>: <error code> <error message>
parts = line.split(':')
if len(parts) >= 2:
try:
first_error_line = int(parts[1])
break
except ValueError:
# Not a valid line number, continue to the next line
continue
return lint_error, first_error_line
# Not a python file, skip linting
return None
return None, None
def _print_window(CURRENT_FILE, CURRENT_LINE, WINDOW, return_str=False):
@@ -247,25 +265,26 @@ def create_file(filename: str) -> None:
@update_pwd_decorator
def edit_file(start: int, end: int, content: str) -> None:
def edit_file(file_name: str, start: int, end: int, content: str) -> None:
"""Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
"""
global CURRENT_FILE, CURRENT_LINE, WINDOW
if not CURRENT_FILE or not os.path.isfile(CURRENT_FILE):
raise FileNotFoundError('No file open. Use the open_file function first.')
if not os.path.isfile(file_name):
raise FileNotFoundError(f'File {file_name} not found.')
# Load the file
with open(CURRENT_FILE, 'r') as file:
with open(file_name, 'r') as file:
lines = file.readlines()
ERROR_MSG = f'[Error editing opened file {CURRENT_FILE}. Please confirm the opened file is correct.]'
ERROR_MSG = f'[Error editing file {file_name}. Please confirm the file is correct.]'
ERROR_MSG_SUFFIX = (
'Your changes have NOT been applied. Please fix your edit command and try again.\n'
'You either need to 1) Open the correct file and try again or 2) Specify the correct start/end line arguments.\n'
@@ -296,24 +315,29 @@ def edit_file(start: int, end: int, content: str) -> None:
return
edited_content = content + '\n'
n_edited_lines = len(edited_content.split('\n'))
new_lines = lines[: start - 1] + [edited_content] + lines[end:]
# directly write edited lines to the file
with open(CURRENT_FILE, 'w') as file:
with open(file_name, 'w') as file:
file.writelines(new_lines)
# set current line to the center of the edited lines
CURRENT_LINE = (start + end) // 2
first_error_line = None
# Handle linting
if ENABLE_AUTO_LINT:
# BACKUP the original file
original_file_backup_path = os.path.join(
os.path.dirname(CURRENT_FILE), f'.backup.{os.path.basename(CURRENT_FILE)}'
os.path.dirname(file_name), f'.backup.{os.path.basename(file_name)}'
)
with open(original_file_backup_path, 'w') as f:
f.writelines(lines)
lint_error = _lint_file(CURRENT_FILE)
if lint_error:
lint_error, first_error_line = _lint_file(file_name)
if lint_error is not None:
if first_error_line is not None:
CURRENT_LINE = int(first_error_line)
# only change any literal strings here in combination with unit tests!
print(
'[Your proposed edit has introduced new syntax error(s). Please understand the errors and retry your edit command.]'
@@ -322,8 +346,8 @@ def edit_file(start: int, end: int, content: str) -> None:
print('[This is how your edit would have looked if applied]')
print('-------------------------------------------------')
cur_line = (n_edited_lines // 2) + start
_print_window(CURRENT_FILE, cur_line, 10)
cur_line = first_error_line
_print_window(file_name, cur_line, 10)
print('-------------------------------------------------\n')
print('[This is the original code before your edit]')
@@ -339,7 +363,7 @@ def edit_file(start: int, end: int, content: str) -> None:
# recover the original file
with open(original_file_backup_path, 'r') as fin, open(
CURRENT_FILE, 'w'
file_name, 'w'
) as fout:
fout.write(fin.read())
os.remove(original_file_backup_path)
@@ -347,17 +371,129 @@ def edit_file(start: int, end: int, content: str) -> None:
os.remove(original_file_backup_path)
with open(CURRENT_FILE, 'r') as file:
# Update the file information and print the updated content
with open(file_name, 'r') as file:
n_total_lines = len(file.readlines())
# set current line to the center of the edited lines
CURRENT_LINE = (start + end) // 2
if first_error_line is not None and int(first_error_line) > 0:
CURRENT_LINE = first_error_line
else:
CURRENT_LINE = n_total_lines
print(
f'[File: {os.path.abspath(CURRENT_FILE)} ({n_total_lines} lines total after edit)]'
f'[File: {os.path.abspath(file_name)} ({n_total_lines} lines total after edit)]'
)
CURRENT_FILE = file_name
_print_window(CURRENT_FILE, CURRENT_LINE, WINDOW)
print(MSG_FILE_UPDATED)
@update_pwd_decorator
def append_file(file_name: str, content: str) -> None:
"""Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
"""
global CURRENT_FILE, CURRENT_LINE, WINDOW
if not os.path.isfile(file_name):
raise FileNotFoundError(f'File {file_name} not found.')
# Use a temporary file to write changes
temp_file_path = ''
first_error_line = None
try:
# Create a temporary file
with tempfile.NamedTemporaryFile('w', delete=False) as temp_file:
temp_file_path = temp_file.name
# Read the original file and check if empty and for a trailing newline
with open(file_name, 'r') as original_file:
lines = original_file.readlines()
if lines and not (len(lines) == 1 and lines[0].strip() == ''):
if not lines[-1].endswith('\n'):
lines[-1] += '\n'
content = ''.join(lines) + content
else:
content = content
if not content.endswith('\n'):
content += '\n'
# Append the new content with a trailing newline
temp_file.write(content)
# Replace the original file with the temporary file atomically
os.replace(temp_file_path, file_name)
# Handle linting
if ENABLE_AUTO_LINT:
# BACKUP the original file
original_file_backup_path = os.path.join(
os.path.dirname(file_name),
f'.backup.{os.path.basename(file_name)}',
)
with open(original_file_backup_path, 'w') as f:
f.writelines(lines)
lint_error, first_error_line = _lint_file(file_name)
if lint_error is not None:
if first_error_line is not None:
CURRENT_LINE = int(first_error_line)
print(
'[Your proposed edit has introduced new syntax error(s). Please understand the errors and retry your edit command.]'
)
print(lint_error)
print('[This is how your edit would have looked if applied]')
print('-------------------------------------------------')
_print_window(file_name, CURRENT_LINE, 10)
print('-------------------------------------------------\n')
print('[This is the original code before your edit]')
print('-------------------------------------------------')
_print_window(original_file_backup_path, CURRENT_LINE, 10)
print('-------------------------------------------------')
print(
'Your changes have NOT been applied. Please fix your edit command and try again.\n'
'You need to correct your added code.\n'
'DO NOT re-run the same failed edit command. Running it again will lead to the same error.'
)
# recover the original file
with open(original_file_backup_path, 'r') as fin, open(
file_name, 'w'
) as fout:
fout.write(fin.read())
os.remove(original_file_backup_path)
return
except Exception as e:
# Clean up the temporary file if an error occurs
if temp_file_path and os.path.exists(temp_file_path):
os.remove(temp_file_path)
raise e
# Update the file information and print the updated content
with open(file_name, 'r', encoding='utf-8') as file:
n_total_lines = len(file.readlines())
if first_error_line is not None and int(first_error_line) > 0:
CURRENT_LINE = first_error_line
else:
CURRENT_LINE = n_total_lines
print(
f'[File: {os.path.abspath(file_name)} ({n_total_lines} lines total after edit)]'
)
CURRENT_FILE = file_name
_print_window(CURRENT_FILE, CURRENT_LINE, WINDOW)
print(
'[File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.]'
)
@update_pwd_decorator
def search_dir(search_term: str, dir_path: str = './') -> None:
"""Searches for search_term in all files in dir. If dir is not provided, searches in the current directory.
@@ -672,6 +808,7 @@ __all__ = [
'scroll_down',
'scroll_up',
'create_file',
'append_file',
'edit_file',
'search_dir',
'search_file',

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:
@@ -327,11 +335,11 @@ open_file('bad.txt')
----------
OBSERVATION:
[File: /workspace/bad.txt (4 lines total)]
1|This is a stupid typoo.
2|Really?
3|No mor typos!
4|Enjoy!
[File: /workspace/bad.txt (4 lines total)]
1|This is a stupid typoo.
2|Really?
3|No mor typos!
4|Enjoy!
ENVIRONMENT REMINDER: You have 8 turns left to complete the task.

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:
@@ -327,18 +335,18 @@ open_file('bad.txt')
----------
OBSERVATION:
[File: /workspace/bad.txt (4 lines total)]
1|This is a stupid typoo.
2|Really?
3|No mor typos!
4|Enjoy!
[File: /workspace/bad.txt (4 lines total)]
1|This is a stupid typoo.
2|Really?
3|No mor typos!
4|Enjoy!
----------
Let's correct the typos in the `bad.txt` file.
<execute_ipython>
edit_file(start=1, end=4, content="""This is a stupid typo.
edit_file('bad.txt', start=1, end=4, content="""This is a stupid typo.
Really?
No more typos!
Enjoy!""")
@@ -347,12 +355,12 @@ Enjoy!""")
----------
OBSERVATION:
[File: /workspace/bad.txt (4 lines total after edit)]
1|This is a stupid typo.
2|Really?
3|No more typos!
4|Enjoy!
[File updated. 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)]
1|This is a stupid typo.
2|Really?
3|No more typos!
4|Enjoy!
[File updated. 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 7 turns left to complete the task.

View File

@@ -1,7 +1,7 @@
Let's correct the typos in the `bad.txt` file.
<execute_ipython>
edit_file(start=1, end=4, content="""This is a stupid typo.
edit_file('bad.txt', start=1, end=4, content="""This is a stupid typo.
Really?
No more typos!
Enjoy!""")

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:

View File

@@ -51,10 +51,18 @@ create_file(filename: str) -> None:
Args:
filename: str: The name of the file to create.
edit_file(start: int, end: int, content: str) -> None:
Edit a file.
It replaces lines `start` through `end` (inclusive) with the given text `content` in the open file. Remember, the file must be open before editing.
append_file(file_name: str, content: str) -> None:
Append content to the given file.
It appends text `content` to the end of the specified file.
Args:
file_name: str: The name of the file to append to.
content: str: The content to append to the file.
edit_file(file_name: str, start: int, end: int, content: str) -> None:
Edit a file.
Replaces in given file `file_name` the lines `start` through `end` (inclusive) with the given text `content`.
Args:
file_name: str: The name of the file to edit.
start: int: The start line number. Must satisfy start >= 1.
end: int: The end line number. Must satisfy start <= end <= number of lines in the file.
content: str: The content to replace the lines with.
@@ -97,7 +105,7 @@ parse_pptx(file_path: str) -> None:
Args:
file_path: str: The path to the file to open.
Please note that THE `edit_file` FUNCTION REQUIRES PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Please note that THE `edit_file` and `append_file` FUNCTIONS REQUIRE PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Responses should be concise.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
@@ -138,7 +146,7 @@ def index():
if __name__ == '__main__':
app.run(port=5000)"""
edit_file(start=1, end=1, content=EDITED_CODE)
edit_file('app.py', start=1, end=1, content=EDITED_CODE)
</execute_ipython>
USER:
@@ -277,7 +285,7 @@ USER:
ASSISTANT:
I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file:
<execute_ipython>
edit_file(start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
edit_file('app.py', start=7, end=7, content=" return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'")
</execute_ipython>
USER:

View File

@@ -16,6 +16,8 @@ WORKSPACE_MOUNT_PATH+="/_test_workspace"
WORKSPACE_BASE+="/_test_workspace"
WORKSPACE_MOUNT_PATH_IN_SANDBOX="/workspace"
mkdir -p $WORKSPACE_BASE
# use environmental variable if exist, otherwise use "ssh"
SANDBOX_TYPE="${SANDBOX_TYPE:-ssh}"
MAX_ITERATIONS=10
@@ -161,7 +163,7 @@ for ((i = 0; i < num_of_tests; i++)); do
rm -rf $WORKSPACE_BASE
mkdir $WORKSPACE_BASE
if [ -d "tests/integration/workspace/$test_name" ]; then
cp -r tests/integration/workspace/$test_name/* $WORKSPACE_BASE
cp -r "tests/integration/workspace/$test_name"/* $WORKSPACE_BASE
fi
if [ "$TEST_ONLY" = true ]; then

View File

@@ -6,6 +6,7 @@ import subprocess
import pytest
from opendevin.controller.state.state import State
from opendevin.core.config import AppConfig, load_from_toml
from opendevin.core.main import main
from opendevin.core.schema import AgentState
from opendevin.events.action import (
@@ -15,6 +16,17 @@ from opendevin.events.action import (
workspace_base = os.getenv('WORKSPACE_BASE')
# make sure we're testing in the same folder of an existing config.toml
if os.path.exists('config.toml'):
config = AppConfig()
load_from_toml(config, 'config.toml')
if config and config.workspace_base and config.workspace_base != workspace_base:
if os.path.exists(config.workspace_base) and os.access(
config.workspace_base, os.W_OK
):
print(f'Setting workspace_base to {config.workspace_base}')
workspace_base = config.workspace_base
@pytest.mark.skipif(
os.getenv('AGENT') == 'BrowsingAgent',
@@ -63,7 +75,7 @@ def test_write_simple_script():
reason='local sandbox shows environment-dependent absolute path for pwd command',
)
def test_edits():
# Move workspace artifacts to workspace_base location
# Copy workspace artifacts to workspace_base location
source_dir = os.path.join(os.path.dirname(__file__), 'workspace/test_edits/')
files = os.listdir(source_dir)
for file in files:

View File

@@ -17,7 +17,13 @@ poetry run pytest ./tests/unit/test_micro_agents.py
Run specific unit test
```bash
poetry run pytest ./tests/unit/test_micro_agents.py:test_coder_agent_with_summary
poetry run pytest ./tests/unit/test_micro_agents.py::test_coder_agent_with_summary
```
More details see [pytest doc](https://docs.pytest.org/en/latest/contents.html)
For a more verbose output, to above calls the `-v` flag can be used (even more verbose: `-vv` and `-vvv`):
```bash
poetry run pytest -v ./tests/unit/test_micro_agents.py
```
More details see [pytest doc](https://docs.pytest.org/en/latest/contents.html)

View File

@@ -1,5 +1,6 @@
import contextlib
import io
import os
import sys
import docx
@@ -8,6 +9,7 @@ import pytest
from opendevin.runtime.plugins.agent_skills.agentskills import (
MSG_FILE_UPDATED,
_print_window,
append_file,
create_file,
edit_file,
find_file,
@@ -350,7 +352,10 @@ check(any_int)"""
with io.StringIO() as buf:
with contextlib.redirect_stdout(buf):
edit_file(
start=9, end=9, content=' assert any_int(1.0, 2, 3) == False'
str(temp_file_path),
start=9,
end=9,
content=' assert any_int(1.0, 2, 3) == False',
)
result = buf.getvalue()
expected = (
@@ -361,7 +366,8 @@ check(any_int)"""
+ 'E999 IndentationError: unexpected indent\n'
'[This is how your edit would have looked if applied]\n'
'-------------------------------------------------\n'
'(5 more lines above)\n'
'(4 more lines above)\n'
'5| assert any_int(1, 2, 3) == True\n'
'6| assert any_int(1.5, 2, 3) == False\n'
'7| assert any_int(1, 2.5, 3) == False\n'
'8| assert any_int(1, 2, 3.5) == False\n'
@@ -371,13 +377,13 @@ check(any_int)"""
'12| assert any_int(0, 0, 0) == True\n'
'13| assert any_int(-1, -2, -3) == True\n'
'14| assert any_int(1, -2, 3) == True\n'
'15| assert any_int(1.5, -2, 3) == False\n'
'(18 more lines below)\n'
'(19 more lines below)\n'
'-------------------------------------------------\n'
'\n'
'[This is the original code before your edit]\n'
'-------------------------------------------------\n'
'(5 more lines above)\n'
'(4 more lines above)\n'
'5| assert any_int(1, 2, 3) == True\n'
'6| assert any_int(1.5, 2, 3) == False\n'
'7| assert any_int(1, 2.5, 3) == False\n'
'8| assert any_int(1, 2, 3.5) == False\n'
@@ -387,8 +393,7 @@ check(any_int)"""
'12| assert any_int(0, 0, 0) == True\n'
'13| assert any_int(-1, -2, -3) == True\n'
'14| assert any_int(1, -2, 3) == True\n'
'15| assert any_int(1.5, -2, 3) == False\n'
'(18 more lines below)\n'
'(19 more lines below)\n'
'-------------------------------------------------\n'
'Your changes have NOT been applied. Please fix your edit command and try again.\n'
'You either need to 1) Specify the correct start/end line arguments or 2) Correct your edit code.\n'
@@ -397,6 +402,94 @@ check(any_int)"""
assert result == expected
def test_append_file(tmp_path):
temp_file_path = tmp_path / 'a.txt'
content = 'Line 1\nLine 2'
temp_file_path.write_text(content)
open_file(str(temp_file_path))
with io.StringIO() as buf:
with contextlib.redirect_stdout(buf):
append_file(str(temp_file_path), content='APPENDED TEXT')
result = buf.getvalue()
expected = (
f'[File: {temp_file_path} (3 lines total after edit)]\n'
'1|Line 1\n'
'2|Line 2\n'
'3|APPENDED TEXT\n'
'[File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.]\n'
)
assert result.split('\n') == expected.split('\n')
with open(temp_file_path, 'r') as file:
lines = file.readlines()
assert len(lines) == 3
assert lines[0].rstrip() == 'Line 1'
assert lines[1].rstrip() == 'Line 2'
assert lines[2].rstrip() == 'APPENDED TEXT'
def test_append_file_from_scratch(tmp_path):
temp_file_path = tmp_path / 'a.txt'
create_file(str(temp_file_path))
try:
open_file(str(temp_file_path))
with io.StringIO() as buf:
with contextlib.redirect_stdout(buf):
append_file(str(temp_file_path), content='APPENDED TEXT')
result = buf.getvalue()
expected = (
f'[File: {temp_file_path} (1 lines total after edit)]\n'
'1|APPENDED TEXT\n'
'[File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.]\n'
)
assert result.split('\n') == expected.split('\n')
with open(temp_file_path, 'r') as file:
lines = file.readlines()
assert len(lines) == 1
assert lines[0].rstrip() == 'APPENDED TEXT'
finally:
os.remove(temp_file_path)
def test_append_file_from_scratch_multiline(tmp_path):
temp_file_path = tmp_path / 'a3.txt'
create_file(str(temp_file_path))
try:
open_file(temp_file_path)
with io.StringIO() as buf:
with contextlib.redirect_stdout(buf):
append_file(
str(temp_file_path),
content='APPENDED TEXT1\nAPPENDED TEXT2\nAPPENDED TEXT3',
)
result = buf.getvalue()
expected = (
f'[File: {temp_file_path} (3 lines total after edit)]\n'
'1|APPENDED TEXT1\n'
'2|APPENDED TEXT2\n'
'3|APPENDED TEXT3\n'
'[File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.]\n'
)
assert result.split('\n') == expected.split('\n')
with open(temp_file_path, 'r') as file:
lines = file.readlines()
assert len(lines) == 3
assert lines[0].rstrip() == 'APPENDED TEXT1'
assert lines[1].rstrip() == 'APPENDED TEXT2'
assert lines[2].rstrip() == 'APPENDED TEXT3'
finally:
os.remove(temp_file_path)
def test_append_file_not_opened():
with pytest.raises(FileNotFoundError):
append_file(str('unknown file'), content='APPEND TEXT')
def test_edit_file(tmp_path):
temp_file_path = tmp_path / 'a.txt'
content = 'Line 1\nLine 2\nLine 3\nLine 4\nLine 5'
@@ -406,7 +499,12 @@ def test_edit_file(tmp_path):
with io.StringIO() as buf:
with contextlib.redirect_stdout(buf):
edit_file(start=1, end=3, content='REPLACE TEXT')
edit_file(
str(temp_file_path),
start=1,
end=3,
content='REPLACE TEXT',
)
result = buf.getvalue()
expected = (
f'[File: {temp_file_path} (3 lines total after edit)]\n'
@@ -431,7 +529,12 @@ def test_edit_file_from_scratch(tmp_path):
with io.StringIO() as buf:
with contextlib.redirect_stdout(buf):
edit_file(start=1, end=1, content='REPLACE TEXT')
edit_file(
str(temp_file_path),
start=1,
end=1,
content='REPLACE TEXT',
)
result = buf.getvalue()
expected = (
f'[File: {temp_file_path} (1 lines total after edit)]\n'
@@ -453,6 +556,7 @@ def test_edit_file_from_scratch_multiline_with_backticks_and_second_edit(tmp_pat
with io.StringIO() as buf:
with contextlib.redirect_stdout(buf):
edit_file(
str(temp_file_path),
1,
1,
'`REPLACE TEXT1`\n`REPLACE TEXT2`\n`REPLACE TEXT3`',
@@ -480,6 +584,7 @@ def test_edit_file_from_scratch_multiline_with_backticks_and_second_edit(tmp_pat
with io.StringIO() as buf:
with contextlib.redirect_stdout(buf):
edit_file(
str(temp_file_path),
1,
3,
'`REPLACED TEXT1`\n`REPLACED TEXT2`\n`REPLACED TEXT3`',
@@ -512,8 +617,9 @@ def test_edit_file_from_scratch_multiline(tmp_path):
with io.StringIO() as buf:
with contextlib.redirect_stdout(buf):
edit_file(
start=1,
end=1,
str(temp_file_path),
1,
1,
content='REPLACE TEXT1\nREPLACE TEXT2\nREPLACE TEXT3',
)
result = buf.getvalue()
@@ -535,7 +641,12 @@ def test_edit_file_from_scratch_multiline(tmp_path):
def test_edit_file_not_opened():
with pytest.raises(FileNotFoundError):
edit_file(start=1, end=3, content='REPLACE TEXT')
edit_file(
str('unknown file'),
1,
3,
'REPLACE TEXT',
)
def test_search_dir(tmp_path):
@@ -720,7 +831,7 @@ def test_edit_lint_file_pass(tmp_path, monkeypatch):
with io.StringIO() as buf:
with contextlib.redirect_stdout(buf):
open_file(str(file_path))
edit_file(1, 1, "print('hello')\n")
edit_file(str(file_path), 1, 1, "print('hello')\n")
result = buf.getvalue()
assert result is not None
@@ -745,7 +856,7 @@ def test_lint_file_fail_undefined_name(tmp_path, monkeypatch, capsys):
)
open_file(str(file_path))
edit_file(1, 1, 'undefined_name()\n')
edit_file(str(file_path), 1, 1, 'undefined_name()\n')
result = capsys.readouterr().out
print(result)
@@ -784,7 +895,7 @@ def test_lint_file_fail_undefined_name_long(tmp_path, monkeypatch, capsys):
)
open_file(str(file_path))
edit_file(500, 500, 'undefined_name()\n')
edit_file(str(file_path), 500, 500, 'undefined_name()\n')
result = capsys.readouterr().out
print(result)
@@ -801,7 +912,8 @@ def test_lint_file_fail_undefined_name_long(tmp_path, monkeypatch, capsys):
f"{file_path}:500:1: F821 undefined name 'undefined_name'\n"
'[This is how your edit would have looked if applied]\n'
'-------------------------------------------------\n'
'(496 more lines above)\n'
'(495 more lines above)\n'
'496|\n'
'497|\n'
'498|\n'
'499|\n'
@@ -811,12 +923,12 @@ def test_lint_file_fail_undefined_name_long(tmp_path, monkeypatch, capsys):
'503|\n'
'504|\n'
'505|\n'
'506|\n'
'(495 more lines below)\n'
'(496 more lines below)\n'
'-------------------------------------------------\n\n'
'[This is the original code before your edit]\n'
'-------------------------------------------------\n'
'(496 more lines above)\n'
'(495 more lines above)\n'
'496|\n'
'497|\n'
'498|\n'
'499|\n'
@@ -826,8 +938,7 @@ def test_lint_file_fail_undefined_name_long(tmp_path, monkeypatch, capsys):
'503|\n'
'504|\n'
'505|\n'
'506|\n'
'(494 more lines below)\n'
'(495 more lines below)\n'
'-------------------------------------------------\n'
'Your changes have NOT been applied. Please fix your edit command and try again.\n'
'You either need to 1) Specify the correct start/end line arguments or 2) Correct your edit code.\n'
@@ -847,7 +958,7 @@ def test_lint_file_disabled_undefined_name(tmp_path, monkeypatch, capsys):
)
open_file(str(file_path))
edit_file(1, 1, 'undefined_name()\n')
edit_file(str(file_path), 1, 1, 'undefined_name()\n')
result = capsys.readouterr().out
assert result is not None