From 8d8ed0c3be6162e2c3c8ec5d4943f06c393cd6f0 Mon Sep 17 00:00:00 2001 From: Xingyao Wang Date: Wed, 15 May 2024 05:15:19 +0800 Subject: [PATCH] hotfix: Initialize plugin with new runtime (#1795) * fix plugin use in jupyter * fix jupyter plugin potential port conflict * update integration test * wait a bit for jupyter execution * add one unit tests for sandbox * fix integration test * fix integration * fix integration yet again * init sandbox plugins in the server --- opendevin/core/main.py | 3 +- opendevin/runtime/plugins/jupyter/execute_cli | 6 +- opendevin/runtime/plugins/jupyter/setup.sh | 20 +- opendevin/server/agent/agent.py | 3 + .../CodeActAgent/test_edits/prompt_002.log | 11 +- .../CodeActAgent/test_edits/prompt_003.log | 37 ++- .../CodeActAgent/test_edits/prompt_004.log | 276 ---------------- .../CodeActAgent/test_edits/prompt_005.log | 294 ------------------ .../CodeActAgent/test_edits/response_001.log | 3 +- .../CodeActAgent/test_edits/response_002.log | 10 +- .../CodeActAgent/test_edits/response_003.log | 9 +- .../CodeActAgent/test_edits/response_004.log | 6 - .../CodeActAgent/test_edits/response_005.log | 1 - .../CodeActAgent/test_ipython/prompt_002.log | 9 +- .../CodeActAgent/test_ipython/prompt_003.log | 255 --------------- .../CodeActAgent/test_ipython/prompt_004.log | 271 ---------------- .../test_ipython/response_001.log | 7 +- .../test_ipython/response_002.log | 6 +- .../test_ipython/response_003.log | 4 - .../test_ipython/response_004.log | 1 - .../test_write_simple_script/prompt_002.log | 5 +- .../test_write_simple_script/response_001.log | 5 +- .../test_write_simple_script/response_002.log | 2 +- tests/unit/test_sandbox.py | 23 ++ 24 files changed, 115 insertions(+), 1152 deletions(-) delete mode 100644 tests/integration/mock/CodeActAgent/test_edits/prompt_004.log delete mode 100644 tests/integration/mock/CodeActAgent/test_edits/prompt_005.log delete mode 100644 tests/integration/mock/CodeActAgent/test_edits/response_004.log delete mode 100644 tests/integration/mock/CodeActAgent/test_edits/response_005.log delete mode 100644 tests/integration/mock/CodeActAgent/test_ipython/prompt_003.log delete mode 100644 tests/integration/mock/CodeActAgent/test_ipython/prompt_004.log delete mode 100644 tests/integration/mock/CodeActAgent/test_ipython/response_003.log delete mode 100644 tests/integration/mock/CodeActAgent/test_ipython/response_004.log diff --git a/opendevin/core/main.py b/opendevin/core/main.py index a03876b749..b3915918f2 100644 --- a/opendevin/core/main.py +++ b/opendevin/core/main.py @@ -83,7 +83,8 @@ async def main(task_str: str = '', exit_on_message: bool = False) -> AgentState: max_chars=args.max_chars, event_stream=event_stream, ) - _ = ServerRuntime(event_stream=event_stream) + runtime = ServerRuntime(event_stream=event_stream) + runtime.init_sandbox_plugins(controller.agent.sandbox_plugins) await event_stream.add_event(MessageAction(content=task), EventSource.USER) await event_stream.add_event( diff --git a/opendevin/runtime/plugins/jupyter/execute_cli b/opendevin/runtime/plugins/jupyter/execute_cli index 0d697c1100..58e967b160 100755 --- a/opendevin/runtime/plugins/jupyter/execute_cli +++ b/opendevin/runtime/plugins/jupyter/execute_cli @@ -16,7 +16,11 @@ PORT = os.environ.get('JUPYTER_EXEC_SERVER_PORT') POST_URL = f'http://localhost:{PORT}/execute' for i in range(5): - response = requests.post(POST_URL, json={'kernel_id': kernel_id, 'code': code}) + try: + response = requests.post(POST_URL, json={'kernel_id': kernel_id, 'code': code}) + except requests.exceptions.ConnectionError: + time.sleep(1) + continue # if "500: Internal Server Error" is not in the response, break the loop if '500: Internal Server Error' not in response.text: break diff --git a/opendevin/runtime/plugins/jupyter/setup.sh b/opendevin/runtime/plugins/jupyter/setup.sh index 23ad1d8f42..4a6d6cc7bd 100755 --- a/opendevin/runtime/plugins/jupyter/setup.sh +++ b/opendevin/runtime/plugins/jupyter/setup.sh @@ -24,7 +24,23 @@ pip install jupyterlab notebook jupyter_kernel_gateway sudo mkdir -p /opendevin/logs && sudo chmod 777 /opendevin/logs # Run background process to start jupyter kernel gateway -export JUPYTER_GATEWAY_PORT=18888 +# write a bash function that finds a free port +find_free_port() { + local start_port="${1:-20000}" + local end_port="${2:-65535}" + + for port in $(seq $start_port $end_port); do + if ! ss -tuln | awk '{print $5}' | grep -q ":$port$"; then + echo $port + return + fi + done + + echo "No free ports found in the range $start_port to $end_port" >&2 + return 1 +} + +export JUPYTER_GATEWAY_PORT=$(find_free_port 20000 30000) jupyter kernelgateway --KernelGatewayApp.ip=0.0.0.0 --KernelGatewayApp.port=$JUPYTER_GATEWAY_PORT > /opendevin/logs/jupyter_kernel_gateway.log 2>&1 & export JUPYTER_GATEWAY_PID=$! echo "export JUPYTER_GATEWAY_PID=$JUPYTER_GATEWAY_PID" >> ~/.bashrc @@ -33,7 +49,7 @@ echo "export JUPYTER_GATEWAY_KERNEL_ID=$JUPYTER_GATEWAY_KERNEL_ID" >> ~/.bashrc echo "JupyterKernelGateway started with PID: $JUPYTER_GATEWAY_PID" # Start the jupyter_server -export JUPYTER_EXEC_SERVER_PORT=18889 +export JUPYTER_EXEC_SERVER_PORT=$(find_free_port 30000 40000) echo "export JUPYTER_EXEC_SERVER_PORT=$JUPYTER_EXEC_SERVER_PORT" >> ~/.bashrc /opendevin/plugins/jupyter/execute_server > /opendevin/logs/jupyter_execute_server.log 2>&1 & export JUPYTER_EXEC_SERVER_PID=$! diff --git a/opendevin/server/agent/agent.py b/opendevin/server/agent/agent.py index 43bd9f40e7..a897815e96 100644 --- a/opendevin/server/agent/agent.py +++ b/opendevin/server/agent/agent.py @@ -118,6 +118,9 @@ class AgentUnit: logger.warning( 'CodeActAgent requires DockerSSHBox as sandbox! Using other sandbox that are not stateful (LocalBox, DockerExecBox) will not work properly.' ) + # Initializing plugins into the runtime + assert self.runtime is not None, 'Runtime is not initialized' + self.runtime.init_sandbox_plugins(agent.sandbox_plugins) if self.controller is not None: await self.controller.close() diff --git a/tests/integration/mock/CodeActAgent/test_edits/prompt_002.log b/tests/integration/mock/CodeActAgent/test_edits/prompt_002.log index 1ed1b3b548..9b6c76219c 100644 --- a/tests/integration/mock/CodeActAgent/test_edits/prompt_002.log +++ b/tests/integration/mock/CodeActAgent/test_edits/prompt_002.log @@ -224,7 +224,8 @@ ENVIRONMENT REMINDER: You have 98 turns left to complete the task. ---------- -Let's start by opening the file `bad.txt` to identify and fix the typos. Let me open the file for you: +Certainly! I will start by opening the file `bad.txt` to see what content it has and then proceed to fix any typos I find. + open bad.txt @@ -232,7 +233,11 @@ open bad.txt ---------- OBSERVATION: --bash: open: command not found -[Command -1 finished with exit code 127]] +[File: /workspace/bad.txt (4 lines total)] +1:This is a stupid typoo. +2:Really? +3:No mor typos! +4:Enjoy! +[Command -1 finished with exit code 0]] ENVIRONMENT REMINDER: You have 97 turns left to complete the task. diff --git a/tests/integration/mock/CodeActAgent/test_edits/prompt_003.log b/tests/integration/mock/CodeActAgent/test_edits/prompt_003.log index e432403c3a..f4cc2a086c 100644 --- a/tests/integration/mock/CodeActAgent/test_edits/prompt_003.log +++ b/tests/integration/mock/CodeActAgent/test_edits/prompt_003.log @@ -224,7 +224,8 @@ ENVIRONMENT REMINDER: You have 98 turns left to complete the task. ---------- -Let's start by opening the file `bad.txt` to identify and fix the typos. Let me open the file for you: +Certainly! I will start by opening the file `bad.txt` to see what content it has and then proceed to fix any typos I find. + open bad.txt @@ -232,25 +233,43 @@ open bad.txt ---------- OBSERVATION: --bash: open: command not found -[Command -1 finished with exit code 127]] +[File: /workspace/bad.txt (4 lines total)] +1:This is a stupid typoo. +2:Really? +3:No mor typos! +4:Enjoy! +[Command -1 finished with exit code 0]] ENVIRONMENT REMINDER: You have 97 turns left to complete the task. ---------- -It seems that the `open` command is not available in this environment. Let's try to read the content of the file `bad.txt` to identify the typos. Let me display the content of the file for you: +I see a few typos in the file `bad.txt`. I will correct them now. + -cat bad.txt +edit 1:1 +This is a stupid typo. +end_of_edit +edit 3:3 +No more typos! +end_of_edit ---------- OBSERVATION: -This is a stupid typoo. -Really? -No mor typos! -Enjoy! +> > [File: /workspace/bad.txt (4 lines total)] +1:This is a stupid typo. +2:Really? +3:No mor 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)] +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. [Command -1 finished with exit code 0]] ENVIRONMENT REMINDER: You have 96 turns left to complete the task. diff --git a/tests/integration/mock/CodeActAgent/test_edits/prompt_004.log b/tests/integration/mock/CodeActAgent/test_edits/prompt_004.log deleted file mode 100644 index 02222dd022..0000000000 --- a/tests/integration/mock/CodeActAgent/test_edits/prompt_004.log +++ /dev/null @@ -1,276 +0,0 @@ - - ----------- - -A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions. -The assistant can interact with an interactive Python (Jupyter Notebook) environment and receive the corresponding output when needed. The code should be enclosed using "" tag, for example: - -print("Hello World!") - -The assistant can execute bash commands on behalf of the user by wrapping them with and . -For example, you can list the files in the current directory by ls . -The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block. -The assistant can install Python packages through bash by pip install [package needed] and should always import packages and define variables before starting to use them. -The assistant should stop and provide an answer when they have already obtained the answer from the execution result. -If the assistant encounters an import error in IPython for a newly installed package, they should try to restart the kernel and import the package again. IPython kernel can be re-started by: - -import IPython -IPython.Application.instance().kernel.do_shutdown(True) # Restart the kernel - - - -Apart from the standard bash commands, you can also use the following special commands in environment: -open [] - opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line -goto - moves the window to show -scroll_down - moves the window down {WINDOW} lines -scroll_up - moves the window down {WINDOW} lines -create - creates and opens a new file with the given name -search_dir [] - searches for search_term in all files in dir. If dir is not provided, searches in the current directory -search_file [] - searches for search_term in file. If file is not provided, searches in the current open file -find_file [] - finds all files with the given name in dir. If dir is not provided, searches in the current directory -edit : - -end_of_edit - replaces lines through (inclusive) with the given text in the open file. The replacement text is terminated by a line with only end_of_edit on it. All of the will be entered, so make sure your indentation is formatted properly. Python files will be checked for syntax errors after the edit. If the system detects a syntax error, the edit will not be executed. Simply try to edit the file again, but make sure to read the error message and modify the edit command you issue accordingly. Issuing the same command a second time will just lead to the same error message again. Remember, the file must be open before editing. -Please note that THE EDIT COMMAND REQUIRES PROPER INDENTATION. If you'd like to add the line ' print(x)' you 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. - -The assistant's response should be concise, but do express their thoughts. -Try to include one of or in each of your responses, unless it is a direct answer to a question OR a message to the user. -IMPORTANT: Whenever possible, execute the code for the user using or instead of providing it. - - ----------- - -Here is an example of how you can interact with the environment for task solving: - ---- START OF EXAMPLE --- - -USER: Can you create a list of numbers from 1 to 10, and create a web page to display them at port 5000? - -ASSISTANT: -Sure! Let me write the Python code for starting a web server and save it to a file `app.py`: - -CODE=''' -from flask import Flask -app = Flask(__name__) - -@app.route('/') -def index(): - numbers = list(range(1, 11)) - return str(numbers) - -if __name__ == '__main__': - app.run(port=5000) -''' -with open('app.py', 'w') as f: - f.write(CODE) - - -USER: -Observation: -[Code executed successfully with no output] - -ASSISTANT: -I have created a Python file `app.py` that will display a list of numbers from 1 to 10 when you run it. Let me run the Python file for you: - -python3 app.py > server.log 2>&1 & - - -USER: -Observation: -[1] 121[1]+ Exit 1 python3 app.py > server.log 2>&1 - -ASSISTANT: Looks like the server is running with PID 121 then crashed. Let me check the server log: - -cat server.log - - -USER: -Observation: -Traceback (most recent call last): - File "/workspace/app.py", line 2, in - from flask import Flask -ModuleNotFoundError: No module named 'flask' - -ASSISTANT: -It seems that Flask is not installed. Let me install Flask for you: - -pip install flask - - -USER: -Observation: -Defaulting to user installation because normal site-packages is not writeable -Collecting flask - Using cached flask-3.0.3-py3-none-any.whl (101 kB) -Collecting blinker>=1.6.2 - Using cached blinker-1.7.0-py3-none-any.whl (13 kB) -Collecting Werkzeug>=3.0.0 - Using cached werkzeug-3.0.2-py3-none-any.whl (226 kB) -Collecting click>=8.1.3 - Using cached click-8.1.7-py3-none-any.whl (97 kB) -Collecting itsdangerous>=2.1.2 - Using cached itsdangerous-2.2.0-py3-none-any.whl (16 kB) -Requirement already satisfied: Jinja2>=3.1.2 in /home/opendevin/.local/lib/python3.10/site-packages (from flask) (3.1.3) -Requirement already satisfied: MarkupSafe>=2.0 in /home/opendevin/.local/lib/python3.10/site-packages (from Jinja2>=3.1.2->flask) (2.1.5) -Installing collected packages: Werkzeug, itsdangerous, click, blinker, flask -Successfully installed Werkzeug-3.0.2 blinker-1.7.0 click-8.1.7 flask-3.0.3 itsdangerous-2.2.0 - -ASSISTANT: -Now that Flask is installed, let me run the Python file again: - -python3 app.py > server.log 2>&1 & - - -USER: -Observation: -[1] 124 - -ASSISTANT: -Let me check the server log again: - -cat server.log - - -USER: -Observation: -* Serving Flask app 'app' - * Debug mode: off -WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. - * Running on http://127.0.0.1:5000 -Press CTRL+C to quit - -ASSISTANT: -The server is running on port 5000 with PID 124. You can access the list of numbers by visiting http://127.0.0.1:5000. If you have any further questions, feel free to ask! - -USER: Now kill the server, make it display the numbers in a table format. - -ASSISTANT: -Sure! Let me stop the server first: - -kill 124 - - -USER: -Observation: -[1]+ Terminated python3 app.py > server.log 2>&1 - -ASSISTANT: -The server has been stopped. Let me open the Python file and modify it. - -open app.py - - -USER: -[File: /workspace/app.py (11 lines total)] -1: -2:from flask import Flask -3:app = Flask(__name__) -4: -5:@app.route('/') -6:def index(): -7: numbers = list(range(1, 11)) -8: return str(numbers) -9: -10:if __name__ == '__main__': -11: app.run(port=5000) - -ASSISTANT: -I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file: - -edit 8:8 - return '' + ''.join([f'' for i in numbers]) + '
{i}
' -end_of_edit -
- -USER: -Observation: -[File: /workspace/app.py (11 lines total)] -1: -2:from flask import Flask -3:app = Flask(__name__) -4: -5:@app.route('/') -6:def index(): -7: numbers = list(range(1, 11)) -8: return '' + ''.join([f'' for i in numbers]) + '
{i}
' -9: -10:if __name__ == '__main__': -11: app.run(port=5000) -File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary. - -ASSISTANT: -The file has been updated. Let me run the Python file again with the new changes: - -python3 app.py > server.log 2>&1 & - - -USER: -Observation: -[1] 126 - -ASSISTANT: -The server is running on port 5000 with PID 126. You can access the list of numbers in a table format by visiting http://127.0.0.1:5000. Free free to let me know if you have any further requests! - ---- END OF EXAMPLE --- - - -NOW, LET'S START! - ----------- - -Fix typos in bad.txt. Do not ask me for confirmation at any point. - -ENVIRONMENT REMINDER: You have 98 turns left to complete the task. - ----------- - -Let's start by opening the file `bad.txt` to identify and fix the typos. Let me open the file for you: - -open bad.txt - - ----------- - -OBSERVATION: --bash: open: command not found -[Command -1 finished with exit code 127]] - -ENVIRONMENT REMINDER: You have 97 turns left to complete the task. - ----------- - -It seems that the `open` command is not available in this environment. Let's try to read the content of the file `bad.txt` to identify the typos. Let me display the content of the file for you: - -cat bad.txt - - ----------- - -OBSERVATION: -This is a stupid typoo. -Really? -No mor typos! -Enjoy! -[Command -1 finished with exit code 0]] - -ENVIRONMENT REMINDER: You have 96 turns left to complete the task. - ----------- - -I have displayed the content of the file `bad.txt` and identified the typos. Let's proceed to fix the typos in the file. I will edit the file to correct the typos: - -edit 1:4 -This is a stupid typo. -Really? -No more typos! -Enjoy! -end_of_edit - - ----------- - -OBSERVATION: -> > > > > -bash: edit: command not found -[Command -1 finished with exit code 127]] - -ENVIRONMENT REMINDER: You have 95 turns left to complete the task. diff --git a/tests/integration/mock/CodeActAgent/test_edits/prompt_005.log b/tests/integration/mock/CodeActAgent/test_edits/prompt_005.log deleted file mode 100644 index c172d2b89d..0000000000 --- a/tests/integration/mock/CodeActAgent/test_edits/prompt_005.log +++ /dev/null @@ -1,294 +0,0 @@ - - ----------- - -A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions. -The assistant can interact with an interactive Python (Jupyter Notebook) environment and receive the corresponding output when needed. The code should be enclosed using "" tag, for example: - -print("Hello World!") - -The assistant can execute bash commands on behalf of the user by wrapping them with and . -For example, you can list the files in the current directory by ls . -The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block. -The assistant can install Python packages through bash by pip install [package needed] and should always import packages and define variables before starting to use them. -The assistant should stop and provide an answer when they have already obtained the answer from the execution result. -If the assistant encounters an import error in IPython for a newly installed package, they should try to restart the kernel and import the package again. IPython kernel can be re-started by: - -import IPython -IPython.Application.instance().kernel.do_shutdown(True) # Restart the kernel - - - -Apart from the standard bash commands, you can also use the following special commands in environment: -open [] - opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line -goto - moves the window to show -scroll_down - moves the window down {WINDOW} lines -scroll_up - moves the window down {WINDOW} lines -create - creates and opens a new file with the given name -search_dir [] - searches for search_term in all files in dir. If dir is not provided, searches in the current directory -search_file [] - searches for search_term in file. If file is not provided, searches in the current open file -find_file [] - finds all files with the given name in dir. If dir is not provided, searches in the current directory -edit : - -end_of_edit - replaces lines through (inclusive) with the given text in the open file. The replacement text is terminated by a line with only end_of_edit on it. All of the will be entered, so make sure your indentation is formatted properly. Python files will be checked for syntax errors after the edit. If the system detects a syntax error, the edit will not be executed. Simply try to edit the file again, but make sure to read the error message and modify the edit command you issue accordingly. Issuing the same command a second time will just lead to the same error message again. Remember, the file must be open before editing. -Please note that THE EDIT COMMAND REQUIRES PROPER INDENTATION. If you'd like to add the line ' print(x)' you 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. - -The assistant's response should be concise, but do express their thoughts. -Try to include one of or in each of your responses, unless it is a direct answer to a question OR a message to the user. -IMPORTANT: Whenever possible, execute the code for the user using or instead of providing it. - - ----------- - -Here is an example of how you can interact with the environment for task solving: - ---- START OF EXAMPLE --- - -USER: Can you create a list of numbers from 1 to 10, and create a web page to display them at port 5000? - -ASSISTANT: -Sure! Let me write the Python code for starting a web server and save it to a file `app.py`: - -CODE=''' -from flask import Flask -app = Flask(__name__) - -@app.route('/') -def index(): - numbers = list(range(1, 11)) - return str(numbers) - -if __name__ == '__main__': - app.run(port=5000) -''' -with open('app.py', 'w') as f: - f.write(CODE) - - -USER: -Observation: -[Code executed successfully with no output] - -ASSISTANT: -I have created a Python file `app.py` that will display a list of numbers from 1 to 10 when you run it. Let me run the Python file for you: - -python3 app.py > server.log 2>&1 & - - -USER: -Observation: -[1] 121[1]+ Exit 1 python3 app.py > server.log 2>&1 - -ASSISTANT: Looks like the server is running with PID 121 then crashed. Let me check the server log: - -cat server.log - - -USER: -Observation: -Traceback (most recent call last): - File "/workspace/app.py", line 2, in - from flask import Flask -ModuleNotFoundError: No module named 'flask' - -ASSISTANT: -It seems that Flask is not installed. Let me install Flask for you: - -pip install flask - - -USER: -Observation: -Defaulting to user installation because normal site-packages is not writeable -Collecting flask - Using cached flask-3.0.3-py3-none-any.whl (101 kB) -Collecting blinker>=1.6.2 - Using cached blinker-1.7.0-py3-none-any.whl (13 kB) -Collecting Werkzeug>=3.0.0 - Using cached werkzeug-3.0.2-py3-none-any.whl (226 kB) -Collecting click>=8.1.3 - Using cached click-8.1.7-py3-none-any.whl (97 kB) -Collecting itsdangerous>=2.1.2 - Using cached itsdangerous-2.2.0-py3-none-any.whl (16 kB) -Requirement already satisfied: Jinja2>=3.1.2 in /home/opendevin/.local/lib/python3.10/site-packages (from flask) (3.1.3) -Requirement already satisfied: MarkupSafe>=2.0 in /home/opendevin/.local/lib/python3.10/site-packages (from Jinja2>=3.1.2->flask) (2.1.5) -Installing collected packages: Werkzeug, itsdangerous, click, blinker, flask -Successfully installed Werkzeug-3.0.2 blinker-1.7.0 click-8.1.7 flask-3.0.3 itsdangerous-2.2.0 - -ASSISTANT: -Now that Flask is installed, let me run the Python file again: - -python3 app.py > server.log 2>&1 & - - -USER: -Observation: -[1] 124 - -ASSISTANT: -Let me check the server log again: - -cat server.log - - -USER: -Observation: -* Serving Flask app 'app' - * Debug mode: off -WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. - * Running on http://127.0.0.1:5000 -Press CTRL+C to quit - -ASSISTANT: -The server is running on port 5000 with PID 124. You can access the list of numbers by visiting http://127.0.0.1:5000. If you have any further questions, feel free to ask! - -USER: Now kill the server, make it display the numbers in a table format. - -ASSISTANT: -Sure! Let me stop the server first: - -kill 124 - - -USER: -Observation: -[1]+ Terminated python3 app.py > server.log 2>&1 - -ASSISTANT: -The server has been stopped. Let me open the Python file and modify it. - -open app.py - - -USER: -[File: /workspace/app.py (11 lines total)] -1: -2:from flask import Flask -3:app = Flask(__name__) -4: -5:@app.route('/') -6:def index(): -7: numbers = list(range(1, 11)) -8: return str(numbers) -9: -10:if __name__ == '__main__': -11: app.run(port=5000) - -ASSISTANT: -I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file: - -edit 8:8 - return '' + ''.join([f'' for i in numbers]) + '
{i}
' -end_of_edit -
- -USER: -Observation: -[File: /workspace/app.py (11 lines total)] -1: -2:from flask import Flask -3:app = Flask(__name__) -4: -5:@app.route('/') -6:def index(): -7: numbers = list(range(1, 11)) -8: return '' + ''.join([f'' for i in numbers]) + '
{i}
' -9: -10:if __name__ == '__main__': -11: app.run(port=5000) -File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary. - -ASSISTANT: -The file has been updated. Let me run the Python file again with the new changes: - -python3 app.py > server.log 2>&1 & - - -USER: -Observation: -[1] 126 - -ASSISTANT: -The server is running on port 5000 with PID 126. You can access the list of numbers in a table format by visiting http://127.0.0.1:5000. Free free to let me know if you have any further requests! - ---- END OF EXAMPLE --- - - -NOW, LET'S START! - ----------- - -Fix typos in bad.txt. Do not ask me for confirmation at any point. - -ENVIRONMENT REMINDER: You have 98 turns left to complete the task. - ----------- - -Let's start by opening the file `bad.txt` to identify and fix the typos. Let me open the file for you: - -open bad.txt - - ----------- - -OBSERVATION: --bash: open: command not found -[Command -1 finished with exit code 127]] - -ENVIRONMENT REMINDER: You have 97 turns left to complete the task. - ----------- - -It seems that the `open` command is not available in this environment. Let's try to read the content of the file `bad.txt` to identify the typos. Let me display the content of the file for you: - -cat bad.txt - - ----------- - -OBSERVATION: -This is a stupid typoo. -Really? -No mor typos! -Enjoy! -[Command -1 finished with exit code 0]] - -ENVIRONMENT REMINDER: You have 96 turns left to complete the task. - ----------- - -I have displayed the content of the file `bad.txt` and identified the typos. Let's proceed to fix the typos in the file. I will edit the file to correct the typos: - -edit 1:4 -This is a stupid typo. -Really? -No more typos! -Enjoy! -end_of_edit - - ----------- - -OBSERVATION: -> > > > > -bash: edit: command not found -[Command -1 finished with exit code 127]] - -ENVIRONMENT REMINDER: You have 95 turns left to complete the task. - ----------- - -It seems that the `edit` command is not available in this environment as well. Let's try a different approach to fix the typos in the file `bad.txt`. I will overwrite the content of the file with the corrected text: - -echo "This is a stupid typo. -Really? -No more typos! -Enjoy!" > bad.txt - - ----------- - -OBSERVATION: -> > > -[Command -1 finished with exit code 0]] - -ENVIRONMENT REMINDER: You have 94 turns left to complete the task. diff --git a/tests/integration/mock/CodeActAgent/test_edits/response_001.log b/tests/integration/mock/CodeActAgent/test_edits/response_001.log index ad055fd76b..56ec1bbd36 100644 --- a/tests/integration/mock/CodeActAgent/test_edits/response_001.log +++ b/tests/integration/mock/CodeActAgent/test_edits/response_001.log @@ -1,3 +1,4 @@ -Let's start by opening the file `bad.txt` to identify and fix the typos. Let me open the file for you: +Certainly! I will start by opening the file `bad.txt` to see what content it has and then proceed to fix any typos I find. + open bad.txt diff --git a/tests/integration/mock/CodeActAgent/test_edits/response_002.log b/tests/integration/mock/CodeActAgent/test_edits/response_002.log index a3b3349aae..3dfd3f47e5 100644 --- a/tests/integration/mock/CodeActAgent/test_edits/response_002.log +++ b/tests/integration/mock/CodeActAgent/test_edits/response_002.log @@ -1,3 +1,9 @@ -It seems that the `open` command is not available in this environment. Let's try to read the content of the file `bad.txt` to identify the typos. Let me display the content of the file for you: +I see a few typos in the file `bad.txt`. I will correct them now. + -cat bad.txt +edit 1:1 +This is a stupid typo. +end_of_edit +edit 3:3 +No more typos! +end_of_edit diff --git a/tests/integration/mock/CodeActAgent/test_edits/response_003.log b/tests/integration/mock/CodeActAgent/test_edits/response_003.log index 7d2801563a..4b2024e1ee 100644 --- a/tests/integration/mock/CodeActAgent/test_edits/response_003.log +++ b/tests/integration/mock/CodeActAgent/test_edits/response_003.log @@ -1,8 +1 @@ -I have displayed the content of the file `bad.txt` and identified the typos. Let's proceed to fix the typos in the file. I will edit the file to correct the typos: - -edit 1:4 -This is a stupid typo. -Really? -No more typos! -Enjoy! -end_of_edit +The typos in the file `bad.txt` have been fixed. The content should now be correct without any spelling mistakes. If there's anything else you need, let me know! diff --git a/tests/integration/mock/CodeActAgent/test_edits/response_004.log b/tests/integration/mock/CodeActAgent/test_edits/response_004.log deleted file mode 100644 index e9a93d2ba9..0000000000 --- a/tests/integration/mock/CodeActAgent/test_edits/response_004.log +++ /dev/null @@ -1,6 +0,0 @@ -It seems that the `edit` command is not available in this environment as well. Let's try a different approach to fix the typos in the file `bad.txt`. I will overwrite the content of the file with the corrected text: - -echo "This is a stupid typo. -Really? -No more typos! -Enjoy!" > bad.txt diff --git a/tests/integration/mock/CodeActAgent/test_edits/response_005.log b/tests/integration/mock/CodeActAgent/test_edits/response_005.log deleted file mode 100644 index 31cca61dc8..0000000000 --- a/tests/integration/mock/CodeActAgent/test_edits/response_005.log +++ /dev/null @@ -1 +0,0 @@ -The typos in the file `bad.txt` have been successfully fixed by overwriting the content with the corrected text. If you need any further assistance or have any more tasks, feel free to let me know! diff --git a/tests/integration/mock/CodeActAgent/test_ipython/prompt_002.log b/tests/integration/mock/CodeActAgent/test_ipython/prompt_002.log index 3635dcdb28..44b766fde2 100644 --- a/tests/integration/mock/CodeActAgent/test_ipython/prompt_002.log +++ b/tests/integration/mock/CodeActAgent/test_ipython/prompt_002.log @@ -224,16 +224,17 @@ ENVIRONMENT REMINDER: You have 98 turns left to complete the task. ---------- -To write 'hello world' to a text file named 'test.txt' in the '/workspace' directory without asking for confirmation, I will execute the following Python code: +Certainly! I will write the text 'hello world' to the file `/workspace/test.txt` using IPython. -with open('/workspace/test.txt', 'w') as f: - f.write('hello world') +# Writing 'hello world' to the specified text file +with open('/workspace/test.txt', 'w') as file: + file.write('hello world') ---------- OBSERVATION: --bash: execute_cli: command not found +[Code executed successfully with no output] ENVIRONMENT REMINDER: You have 97 turns left to complete the task. diff --git a/tests/integration/mock/CodeActAgent/test_ipython/prompt_003.log b/tests/integration/mock/CodeActAgent/test_ipython/prompt_003.log deleted file mode 100644 index e9a7af3157..0000000000 --- a/tests/integration/mock/CodeActAgent/test_ipython/prompt_003.log +++ /dev/null @@ -1,255 +0,0 @@ - - ----------- - -A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions. -The assistant can interact with an interactive Python (Jupyter Notebook) environment and receive the corresponding output when needed. The code should be enclosed using "" tag, for example: - -print("Hello World!") - -The assistant can execute bash commands on behalf of the user by wrapping them with and . -For example, you can list the files in the current directory by ls . -The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block. -The assistant can install Python packages through bash by pip install [package needed] and should always import packages and define variables before starting to use them. -The assistant should stop and provide an answer when they have already obtained the answer from the execution result. -If the assistant encounters an import error in IPython for a newly installed package, they should try to restart the kernel and import the package again. IPython kernel can be re-started by: - -import IPython -IPython.Application.instance().kernel.do_shutdown(True) # Restart the kernel - - - -Apart from the standard bash commands, you can also use the following special commands in environment: -open [] - opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line -goto - moves the window to show -scroll_down - moves the window down {WINDOW} lines -scroll_up - moves the window down {WINDOW} lines -create - creates and opens a new file with the given name -search_dir [] - searches for search_term in all files in dir. If dir is not provided, searches in the current directory -search_file [] - searches for search_term in file. If file is not provided, searches in the current open file -find_file [] - finds all files with the given name in dir. If dir is not provided, searches in the current directory -edit : - -end_of_edit - replaces lines through (inclusive) with the given text in the open file. The replacement text is terminated by a line with only end_of_edit on it. All of the will be entered, so make sure your indentation is formatted properly. Python files will be checked for syntax errors after the edit. If the system detects a syntax error, the edit will not be executed. Simply try to edit the file again, but make sure to read the error message and modify the edit command you issue accordingly. Issuing the same command a second time will just lead to the same error message again. Remember, the file must be open before editing. -Please note that THE EDIT COMMAND REQUIRES PROPER INDENTATION. If you'd like to add the line ' print(x)' you 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. - -The assistant's response should be concise, but do express their thoughts. -Try to include one of or in each of your responses, unless it is a direct answer to a question OR a message to the user. -IMPORTANT: Whenever possible, execute the code for the user using or instead of providing it. - - ----------- - -Here is an example of how you can interact with the environment for task solving: - ---- START OF EXAMPLE --- - -USER: Can you create a list of numbers from 1 to 10, and create a web page to display them at port 5000? - -ASSISTANT: -Sure! Let me write the Python code for starting a web server and save it to a file `app.py`: - -CODE=''' -from flask import Flask -app = Flask(__name__) - -@app.route('/') -def index(): - numbers = list(range(1, 11)) - return str(numbers) - -if __name__ == '__main__': - app.run(port=5000) -''' -with open('app.py', 'w') as f: - f.write(CODE) - - -USER: -Observation: -[Code executed successfully with no output] - -ASSISTANT: -I have created a Python file `app.py` that will display a list of numbers from 1 to 10 when you run it. Let me run the Python file for you: - -python3 app.py > server.log 2>&1 & - - -USER: -Observation: -[1] 121[1]+ Exit 1 python3 app.py > server.log 2>&1 - -ASSISTANT: Looks like the server is running with PID 121 then crashed. Let me check the server log: - -cat server.log - - -USER: -Observation: -Traceback (most recent call last): - File "/workspace/app.py", line 2, in - from flask import Flask -ModuleNotFoundError: No module named 'flask' - -ASSISTANT: -It seems that Flask is not installed. Let me install Flask for you: - -pip install flask - - -USER: -Observation: -Defaulting to user installation because normal site-packages is not writeable -Collecting flask - Using cached flask-3.0.3-py3-none-any.whl (101 kB) -Collecting blinker>=1.6.2 - Using cached blinker-1.7.0-py3-none-any.whl (13 kB) -Collecting Werkzeug>=3.0.0 - Using cached werkzeug-3.0.2-py3-none-any.whl (226 kB) -Collecting click>=8.1.3 - Using cached click-8.1.7-py3-none-any.whl (97 kB) -Collecting itsdangerous>=2.1.2 - Using cached itsdangerous-2.2.0-py3-none-any.whl (16 kB) -Requirement already satisfied: Jinja2>=3.1.2 in /home/opendevin/.local/lib/python3.10/site-packages (from flask) (3.1.3) -Requirement already satisfied: MarkupSafe>=2.0 in /home/opendevin/.local/lib/python3.10/site-packages (from Jinja2>=3.1.2->flask) (2.1.5) -Installing collected packages: Werkzeug, itsdangerous, click, blinker, flask -Successfully installed Werkzeug-3.0.2 blinker-1.7.0 click-8.1.7 flask-3.0.3 itsdangerous-2.2.0 - -ASSISTANT: -Now that Flask is installed, let me run the Python file again: - -python3 app.py > server.log 2>&1 & - - -USER: -Observation: -[1] 124 - -ASSISTANT: -Let me check the server log again: - -cat server.log - - -USER: -Observation: -* Serving Flask app 'app' - * Debug mode: off -WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. - * Running on http://127.0.0.1:5000 -Press CTRL+C to quit - -ASSISTANT: -The server is running on port 5000 with PID 124. You can access the list of numbers by visiting http://127.0.0.1:5000. If you have any further questions, feel free to ask! - -USER: Now kill the server, make it display the numbers in a table format. - -ASSISTANT: -Sure! Let me stop the server first: - -kill 124 - - -USER: -Observation: -[1]+ Terminated python3 app.py > server.log 2>&1 - -ASSISTANT: -The server has been stopped. Let me open the Python file and modify it. - -open app.py - - -USER: -[File: /workspace/app.py (11 lines total)] -1: -2:from flask import Flask -3:app = Flask(__name__) -4: -5:@app.route('/') -6:def index(): -7: numbers = list(range(1, 11)) -8: return str(numbers) -9: -10:if __name__ == '__main__': -11: app.run(port=5000) - -ASSISTANT: -I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file: - -edit 8:8 - return '' + ''.join([f'' for i in numbers]) + '
{i}
' -end_of_edit -
- -USER: -Observation: -[File: /workspace/app.py (11 lines total)] -1: -2:from flask import Flask -3:app = Flask(__name__) -4: -5:@app.route('/') -6:def index(): -7: numbers = list(range(1, 11)) -8: return '' + ''.join([f'' for i in numbers]) + '
{i}
' -9: -10:if __name__ == '__main__': -11: app.run(port=5000) -File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary. - -ASSISTANT: -The file has been updated. Let me run the Python file again with the new changes: - -python3 app.py > server.log 2>&1 & - - -USER: -Observation: -[1] 126 - -ASSISTANT: -The server is running on port 5000 with PID 126. You can access the list of numbers in a table format by visiting http://127.0.0.1:5000. Free free to let me know if you have any further requests! - ---- END OF EXAMPLE --- - - -NOW, LET'S START! - ----------- - -Use Jupyter IPython to write a text file containing 'hello world' to '/workspace/test.txt'. Do not ask me for confirmation at any point. - -ENVIRONMENT REMINDER: You have 98 turns left to complete the task. - ----------- - -To write 'hello world' to a text file named 'test.txt' in the '/workspace' directory without asking for confirmation, I will execute the following Python code: - - -with open('/workspace/test.txt', 'w') as f: - f.write('hello world') - - ----------- - -OBSERVATION: --bash: execute_cli: command not found - -ENVIRONMENT REMINDER: You have 97 turns left to complete the task. - ----------- - -It seems there was an issue with the execution. Let me try running the code again to write 'hello world' to the text file 'test.txt' in the '/workspace' directory: - - -with open('/workspace/test.txt', 'w') as f: - f.write('hello world') - - ----------- - -OBSERVATION: --bash: execute_cli: command not found - -ENVIRONMENT REMINDER: You have 96 turns left to complete the task. diff --git a/tests/integration/mock/CodeActAgent/test_ipython/prompt_004.log b/tests/integration/mock/CodeActAgent/test_ipython/prompt_004.log deleted file mode 100644 index d0169d4dce..0000000000 --- a/tests/integration/mock/CodeActAgent/test_ipython/prompt_004.log +++ /dev/null @@ -1,271 +0,0 @@ - - ----------- - -A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions. -The assistant can interact with an interactive Python (Jupyter Notebook) environment and receive the corresponding output when needed. The code should be enclosed using "" tag, for example: - -print("Hello World!") - -The assistant can execute bash commands on behalf of the user by wrapping them with and . -For example, you can list the files in the current directory by ls . -The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block. -The assistant can install Python packages through bash by pip install [package needed] and should always import packages and define variables before starting to use them. -The assistant should stop and provide an answer when they have already obtained the answer from the execution result. -If the assistant encounters an import error in IPython for a newly installed package, they should try to restart the kernel and import the package again. IPython kernel can be re-started by: - -import IPython -IPython.Application.instance().kernel.do_shutdown(True) # Restart the kernel - - - -Apart from the standard bash commands, you can also use the following special commands in environment: -open [] - opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line -goto - moves the window to show -scroll_down - moves the window down {WINDOW} lines -scroll_up - moves the window down {WINDOW} lines -create - creates and opens a new file with the given name -search_dir [] - searches for search_term in all files in dir. If dir is not provided, searches in the current directory -search_file [] - searches for search_term in file. If file is not provided, searches in the current open file -find_file [] - finds all files with the given name in dir. If dir is not provided, searches in the current directory -edit : - -end_of_edit - replaces lines through (inclusive) with the given text in the open file. The replacement text is terminated by a line with only end_of_edit on it. All of the will be entered, so make sure your indentation is formatted properly. Python files will be checked for syntax errors after the edit. If the system detects a syntax error, the edit will not be executed. Simply try to edit the file again, but make sure to read the error message and modify the edit command you issue accordingly. Issuing the same command a second time will just lead to the same error message again. Remember, the file must be open before editing. -Please note that THE EDIT COMMAND REQUIRES PROPER INDENTATION. If you'd like to add the line ' print(x)' you 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. - -The assistant's response should be concise, but do express their thoughts. -Try to include one of or in each of your responses, unless it is a direct answer to a question OR a message to the user. -IMPORTANT: Whenever possible, execute the code for the user using or instead of providing it. - - ----------- - -Here is an example of how you can interact with the environment for task solving: - ---- START OF EXAMPLE --- - -USER: Can you create a list of numbers from 1 to 10, and create a web page to display them at port 5000? - -ASSISTANT: -Sure! Let me write the Python code for starting a web server and save it to a file `app.py`: - -CODE=''' -from flask import Flask -app = Flask(__name__) - -@app.route('/') -def index(): - numbers = list(range(1, 11)) - return str(numbers) - -if __name__ == '__main__': - app.run(port=5000) -''' -with open('app.py', 'w') as f: - f.write(CODE) - - -USER: -Observation: -[Code executed successfully with no output] - -ASSISTANT: -I have created a Python file `app.py` that will display a list of numbers from 1 to 10 when you run it. Let me run the Python file for you: - -python3 app.py > server.log 2>&1 & - - -USER: -Observation: -[1] 121[1]+ Exit 1 python3 app.py > server.log 2>&1 - -ASSISTANT: Looks like the server is running with PID 121 then crashed. Let me check the server log: - -cat server.log - - -USER: -Observation: -Traceback (most recent call last): - File "/workspace/app.py", line 2, in - from flask import Flask -ModuleNotFoundError: No module named 'flask' - -ASSISTANT: -It seems that Flask is not installed. Let me install Flask for you: - -pip install flask - - -USER: -Observation: -Defaulting to user installation because normal site-packages is not writeable -Collecting flask - Using cached flask-3.0.3-py3-none-any.whl (101 kB) -Collecting blinker>=1.6.2 - Using cached blinker-1.7.0-py3-none-any.whl (13 kB) -Collecting Werkzeug>=3.0.0 - Using cached werkzeug-3.0.2-py3-none-any.whl (226 kB) -Collecting click>=8.1.3 - Using cached click-8.1.7-py3-none-any.whl (97 kB) -Collecting itsdangerous>=2.1.2 - Using cached itsdangerous-2.2.0-py3-none-any.whl (16 kB) -Requirement already satisfied: Jinja2>=3.1.2 in /home/opendevin/.local/lib/python3.10/site-packages (from flask) (3.1.3) -Requirement already satisfied: MarkupSafe>=2.0 in /home/opendevin/.local/lib/python3.10/site-packages (from Jinja2>=3.1.2->flask) (2.1.5) -Installing collected packages: Werkzeug, itsdangerous, click, blinker, flask -Successfully installed Werkzeug-3.0.2 blinker-1.7.0 click-8.1.7 flask-3.0.3 itsdangerous-2.2.0 - -ASSISTANT: -Now that Flask is installed, let me run the Python file again: - -python3 app.py > server.log 2>&1 & - - -USER: -Observation: -[1] 124 - -ASSISTANT: -Let me check the server log again: - -cat server.log - - -USER: -Observation: -* Serving Flask app 'app' - * Debug mode: off -WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. - * Running on http://127.0.0.1:5000 -Press CTRL+C to quit - -ASSISTANT: -The server is running on port 5000 with PID 124. You can access the list of numbers by visiting http://127.0.0.1:5000. If you have any further questions, feel free to ask! - -USER: Now kill the server, make it display the numbers in a table format. - -ASSISTANT: -Sure! Let me stop the server first: - -kill 124 - - -USER: -Observation: -[1]+ Terminated python3 app.py > server.log 2>&1 - -ASSISTANT: -The server has been stopped. Let me open the Python file and modify it. - -open app.py - - -USER: -[File: /workspace/app.py (11 lines total)] -1: -2:from flask import Flask -3:app = Flask(__name__) -4: -5:@app.route('/') -6:def index(): -7: numbers = list(range(1, 11)) -8: return str(numbers) -9: -10:if __name__ == '__main__': -11: app.run(port=5000) - -ASSISTANT: -I should edit the file to display the numbers in a table format. I should include correct indentation. Let me update the file: - -edit 8:8 - return '' + ''.join([f'' for i in numbers]) + '
{i}
' -end_of_edit -
- -USER: -Observation: -[File: /workspace/app.py (11 lines total)] -1: -2:from flask import Flask -3:app = Flask(__name__) -4: -5:@app.route('/') -6:def index(): -7: numbers = list(range(1, 11)) -8: return '' + ''.join([f'' for i in numbers]) + '
{i}
' -9: -10:if __name__ == '__main__': -11: app.run(port=5000) -File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary. - -ASSISTANT: -The file has been updated. Let me run the Python file again with the new changes: - -python3 app.py > server.log 2>&1 & - - -USER: -Observation: -[1] 126 - -ASSISTANT: -The server is running on port 5000 with PID 126. You can access the list of numbers in a table format by visiting http://127.0.0.1:5000. Free free to let me know if you have any further requests! - ---- END OF EXAMPLE --- - - -NOW, LET'S START! - ----------- - -Use Jupyter IPython to write a text file containing 'hello world' to '/workspace/test.txt'. Do not ask me for confirmation at any point. - -ENVIRONMENT REMINDER: You have 98 turns left to complete the task. - ----------- - -To write 'hello world' to a text file named 'test.txt' in the '/workspace' directory without asking for confirmation, I will execute the following Python code: - - -with open('/workspace/test.txt', 'w') as f: - f.write('hello world') - - ----------- - -OBSERVATION: --bash: execute_cli: command not found - -ENVIRONMENT REMINDER: You have 97 turns left to complete the task. - ----------- - -It seems there was an issue with the execution. Let me try running the code again to write 'hello world' to the text file 'test.txt' in the '/workspace' directory: - - -with open('/workspace/test.txt', 'w') as f: - f.write('hello world') - - ----------- - -OBSERVATION: --bash: execute_cli: command not found - -ENVIRONMENT REMINDER: You have 96 turns left to complete the task. - ----------- - -It seems there is still an issue with the execution. Let me try a different approach to write 'hello world' to the text file 'test.txt' in the '/workspace' directory: - - -echo "hello world" > /workspace/test.txt - - ----------- - -OBSERVATION: - -[Command -1 finished with exit code 0]] - -ENVIRONMENT REMINDER: You have 95 turns left to complete the task. diff --git a/tests/integration/mock/CodeActAgent/test_ipython/response_001.log b/tests/integration/mock/CodeActAgent/test_ipython/response_001.log index b6b1ae3ebb..9d44462487 100644 --- a/tests/integration/mock/CodeActAgent/test_ipython/response_001.log +++ b/tests/integration/mock/CodeActAgent/test_ipython/response_001.log @@ -1,5 +1,6 @@ -To write 'hello world' to a text file named 'test.txt' in the '/workspace' directory without asking for confirmation, I will execute the following Python code: +Certainly! I will write the text 'hello world' to the file `/workspace/test.txt` using IPython. -with open('/workspace/test.txt', 'w') as f: - f.write('hello world') +# Writing 'hello world' to the specified text file +with open('/workspace/test.txt', 'w') as file: + file.write('hello world') diff --git a/tests/integration/mock/CodeActAgent/test_ipython/response_002.log b/tests/integration/mock/CodeActAgent/test_ipython/response_002.log index da71a6915a..873abf1f12 100644 --- a/tests/integration/mock/CodeActAgent/test_ipython/response_002.log +++ b/tests/integration/mock/CodeActAgent/test_ipython/response_002.log @@ -1,5 +1 @@ -It seems there was an issue with the execution. Let me try running the code again to write 'hello world' to the text file 'test.txt' in the '/workspace' directory: - - -with open('/workspace/test.txt', 'w') as f: - f.write('hello world') +The text 'hello world' has been successfully written to `/workspace/test.txt`. If you need any further assistance or another task to be done, feel free to let me know! diff --git a/tests/integration/mock/CodeActAgent/test_ipython/response_003.log b/tests/integration/mock/CodeActAgent/test_ipython/response_003.log deleted file mode 100644 index deca9a34b0..0000000000 --- a/tests/integration/mock/CodeActAgent/test_ipython/response_003.log +++ /dev/null @@ -1,4 +0,0 @@ -It seems there is still an issue with the execution. Let me try a different approach to write 'hello world' to the text file 'test.txt' in the '/workspace' directory: - - -echo "hello world" > /workspace/test.txt diff --git a/tests/integration/mock/CodeActAgent/test_ipython/response_004.log b/tests/integration/mock/CodeActAgent/test_ipython/response_004.log deleted file mode 100644 index 9954c22283..0000000000 --- a/tests/integration/mock/CodeActAgent/test_ipython/response_004.log +++ /dev/null @@ -1 +0,0 @@ -The text 'hello world' has been successfully written to the file 'test.txt' in the '/workspace' directory. If you need any further assistance or have any more tasks in mind, feel free to let me know! diff --git a/tests/integration/mock/CodeActAgent/test_write_simple_script/prompt_002.log b/tests/integration/mock/CodeActAgent/test_write_simple_script/prompt_002.log index 6a33c5c706..047f8e6754 100644 --- a/tests/integration/mock/CodeActAgent/test_write_simple_script/prompt_002.log +++ b/tests/integration/mock/CodeActAgent/test_write_simple_script/prompt_002.log @@ -224,9 +224,10 @@ ENVIRONMENT REMINDER: You have 98 turns left to complete the task. ---------- -I will create a shell script named 'hello.sh' that prints 'hello' without asking for confirmation. Let me write the script for you: +Certainly! I will create a shell script named `hello.sh` that prints "hello" when executed. + -echo "echo 'hello'" > hello.sh +echo 'echo hello' > hello.sh && chmod +x hello.sh ---------- diff --git a/tests/integration/mock/CodeActAgent/test_write_simple_script/response_001.log b/tests/integration/mock/CodeActAgent/test_write_simple_script/response_001.log index 4fbc0b81f1..5f55b150aa 100644 --- a/tests/integration/mock/CodeActAgent/test_write_simple_script/response_001.log +++ b/tests/integration/mock/CodeActAgent/test_write_simple_script/response_001.log @@ -1,3 +1,4 @@ -I will create a shell script named 'hello.sh' that prints 'hello' without asking for confirmation. Let me write the script for you: +Certainly! I will create a shell script named `hello.sh` that prints "hello" when executed. + -echo "echo 'hello'" > hello.sh +echo 'echo hello' > hello.sh && chmod +x hello.sh diff --git a/tests/integration/mock/CodeActAgent/test_write_simple_script/response_002.log b/tests/integration/mock/CodeActAgent/test_write_simple_script/response_002.log index f49ce6d4a7..17999ba56a 100644 --- a/tests/integration/mock/CodeActAgent/test_write_simple_script/response_002.log +++ b/tests/integration/mock/CodeActAgent/test_write_simple_script/response_002.log @@ -1 +1 @@ -The shell script 'hello.sh' has been successfully created. You can run it to print 'hello'. If you have any more tasks or questions, feel free to ask! +The shell script `hello.sh` has been created and made executable. You can now run this script to print "hello". If you need anything else, feel free to ask! diff --git a/tests/unit/test_sandbox.py b/tests/unit/test_sandbox.py index d3ee13d6b8..d3e70dc739 100644 --- a/tests/unit/test_sandbox.py +++ b/tests/unit/test_sandbox.py @@ -9,6 +9,7 @@ from opendevin.core.config import AppConfig, config from opendevin.runtime.docker.exec_box import DockerExecBox from opendevin.runtime.docker.local_box import LocalBox from opendevin.runtime.docker.ssh_box import DockerSSHBox, split_bash_commands +from opendevin.runtime.plugins import JupyterRequirement @pytest.fixture @@ -273,3 +274,25 @@ def test_sandbox_whitespace(temp_dir): 'The output should be the same as the input for ' + box.__class__.__name__ ) + + +def test_sandbox_jupyter_plugin(temp_dir): + # get a temporary directory + with patch.object(config, 'workspace_base', new=temp_dir), patch.object( + config, 'workspace_mount_path', new=temp_dir + ), patch.object(config, 'run_as_devin', new='true'), patch.object( + config, 'sandbox_type', new='ssh' + ): + for box in [DockerSSHBox()]: + box.init_plugins([JupyterRequirement]) + + # test the ssh box + exit_code, output = box.execute('echo "print(1)" | execute_cli') + print(output) + assert exit_code == 0, ( + 'The exit code should be 0 for ' + box.__class__.__name__ + ) + assert output == '1\r\n', ( + 'The output should be the same as the input for ' + + box.__class__.__name__ + )