From 568e6cdb40daa6295817f3066d1341ec71791242 Mon Sep 17 00:00:00 2001 From: Xingyao Wang Date: Tue, 13 Aug 2024 18:08:31 +0800 Subject: [PATCH] feat: change Jupyter cwd alone with "bash" (#3331) * remove unused plugin mixin * change the entire jupyter PWD with bash; print jupyter pwd in obs as well; * remove unused field * remove unused comments * change the entire jupyter PWD with bash; print jupyter pwd in obs as well; * fix runtime tests for jupyter * update intgeration tests * fix test again --------- Co-authored-by: Graham Neubig --- opendevin/runtime/client/client.py | 4 +- .../plugins/agent_skills/agentskills.py | 65 ------------------- .../CodeActAgent/test_ipython/prompt_001.log | 2 + .../CodeActAgent/test_ipython/prompt_002.log | 3 +- .../test_ipython_module/prompt_001.log | 2 + .../test_ipython_module/prompt_002.log | 8 +-- .../test_ipython_module/prompt_003.log | 9 +-- .../test_ipython_module/prompt_004.log | 9 +-- .../test_ipython/prompt_002.log | 1 + .../test_ipython_module/prompt_002.log | 6 +- .../test_ipython_module/prompt_003.log | 7 +- .../test_ipython_module/prompt_004.log | 7 +- tests/unit/test_runtime.py | 28 ++++++-- 13 files changed, 58 insertions(+), 93 deletions(-) diff --git a/opendevin/runtime/client/client.py b/opendevin/runtime/client/client.py index a1883bb829..333f1671bf 100644 --- a/opendevin/runtime/client/client.py +++ b/opendevin/runtime/client/client.py @@ -301,7 +301,7 @@ class RuntimeClient: logger.debug( f"{self.pwd} != {getattr(self, '_jupyter_pwd', None)} -> reset Jupyter PWD" ) - reset_jupyter_pwd_code = f'import os; os.environ["JUPYTER_PWD"] = os.path.abspath("{self.pwd}")' + reset_jupyter_pwd_code = f'import os; os.chdir("{self.pwd}")' _aux_action = IPythonRunCellAction(code=reset_jupyter_pwd_code) _reset_obs = await _jupyter_plugin.run(_aux_action) logger.debug( @@ -310,6 +310,8 @@ class RuntimeClient: self._jupyter_pwd = self.pwd obs: IPythonRunCellObservation = await _jupyter_plugin.run(action) + obs.content = obs.content.rstrip() + obs.content += f'\n[Jupyter current working directory: {self.pwd}]' return obs else: raise RuntimeError( diff --git a/opendevin/runtime/plugins/agent_skills/agentskills.py b/opendevin/runtime/plugins/agent_skills/agentskills.py index b7244b744a..1f424b6f59 100644 --- a/opendevin/runtime/plugins/agent_skills/agentskills.py +++ b/opendevin/runtime/plugins/agent_skills/agentskills.py @@ -17,7 +17,6 @@ Functions: """ import base64 -import functools import os import re import shutil @@ -75,52 +74,6 @@ def _get_openai_client(): # ================================================================================================== -# Define the decorator using the functionality of UpdatePwd -def update_pwd_decorator(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - jupyter_pwd = os.environ.get('JUPYTER_PWD', None) - try: - old_pwd = os.getcwd() - except FileNotFoundError: - import json - import subprocess - - print( - f'DEBUGGING Environment variables: {json.dumps(dict(os.environ), indent=2)}' - ) - print(f'DEBUGGING User ID: {os.getuid()}, Group ID: {os.getgid()}') - - out = subprocess.run(['pwd'], capture_output=True) - old_pwd = out.stdout.decode('utf-8').strip() - os.chdir(old_pwd) - print(f'DEBUGGING Change to working directory: {old_pwd}') - - import tempfile - - try: - tempfile.TemporaryFile(dir=old_pwd) - print(f'DEBUGGING Directory {old_pwd} is writable') - except Exception as e: - print(f'DEBUGGING Directory {old_pwd} is not writable: {str(e)}') - - # ls -alh - out = subprocess.run(['ls', '-alh', old_pwd], capture_output=True) - print( - f'DEBUGGING OLD working directory contents: {out.stdout.decode("utf-8")}' - ) - print(f'DEBUGGING Target JUPYTER pwd: {jupyter_pwd}') - - if jupyter_pwd: - os.chdir(jupyter_pwd) - try: - return func(*args, **kwargs) - finally: - os.chdir(old_pwd) - - return wrapper - - def _is_valid_filename(file_name) -> bool: if not file_name or not isinstance(file_name, str) or not file_name.strip(): return False @@ -240,7 +193,6 @@ def _cur_file_header(current_file, total_lines) -> str: return f'[File: {os.path.abspath(current_file)} ({total_lines} lines total)]\n' -@update_pwd_decorator def open_file( path: str, line_number: int | None = 1, context_lines: int | None = WINDOW ) -> None: @@ -277,7 +229,6 @@ def open_file( print(output) -@update_pwd_decorator def goto_line(line_number: int) -> None: """Moves the window to show the specified line number. @@ -299,7 +250,6 @@ def goto_line(line_number: int) -> None: print(output) -@update_pwd_decorator def scroll_down() -> None: """Moves the window down by 100 lines. @@ -317,7 +267,6 @@ def scroll_down() -> None: print(output) -@update_pwd_decorator def scroll_up() -> None: """Moves the window up by 100 lines. @@ -335,7 +284,6 @@ def scroll_up() -> None: print(output) -@update_pwd_decorator def create_file(filename: str) -> None: """Creates and opens a new file with the given name. @@ -647,7 +595,6 @@ def _edit_file_impl( return ret_str -@update_pwd_decorator def edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> None: """Edit a file. This will search for `to_replace` in the given file and replace it with `new_content`. @@ -749,7 +696,6 @@ def edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> N print(ret_str) -@update_pwd_decorator def insert_content_at_line(file_name: str, line_number: int, content: str) -> None: """Insert content at the given line number in a file. This will NOT modify the content of the lines before OR after the given line number. @@ -784,7 +730,6 @@ def insert_content_at_line(file_name: str, line_number: int, content: str) -> No print(ret_str) -@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. @@ -805,7 +750,6 @@ def append_file(file_name: str, content: str) -> None: print(ret_str) -@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. @@ -845,7 +789,6 @@ def search_dir(search_term: str, dir_path: str = './') -> None: print(f'[End of matches for "{search_term}" in {dir_path}]') -@update_pwd_decorator def search_file(search_term: str, file_path: Optional[str] = None) -> None: """Searches for search_term in file. If file is not provided, searches in the current open file. @@ -878,7 +821,6 @@ def search_file(search_term: str, file_path: Optional[str] = None) -> None: print(f'[No matches found for "{search_term}" in {file_path}]') -@update_pwd_decorator def find_file(file_name: str, dir_path: str = './') -> None: """Finds all files with the given name in the specified directory. @@ -904,7 +846,6 @@ def find_file(file_name: str, dir_path: str = './') -> None: print(f'[No matches found for "{file_name}" in {dir_path}]') -@update_pwd_decorator def parse_pdf(file_path: str) -> None: """Parses the content of a PDF file and prints it. @@ -923,7 +864,6 @@ def parse_pdf(file_path: str) -> None: print(text.strip()) -@update_pwd_decorator def parse_docx(file_path: str) -> None: """Parses the content of a DOCX file and prints it. @@ -938,7 +878,6 @@ def parse_docx(file_path: str) -> None: print(text) -@update_pwd_decorator def parse_latex(file_path: str) -> None: """Parses the content of a LaTex file and prints it. @@ -991,7 +930,6 @@ def _prepare_image_messages(task: str, base64_image: str): ] -@update_pwd_decorator def parse_audio(file_path: str, model: str = 'whisper-1') -> None: """Parses the content of an audio file and prints it. @@ -1012,7 +950,6 @@ def parse_audio(file_path: str, model: str = 'whisper-1') -> None: print(f'Error transcribing audio file: {e}') -@update_pwd_decorator def parse_image( file_path: str, task: str = 'Describe this image as detail as possible.' ) -> None: @@ -1038,7 +975,6 @@ def parse_image( print(f'Error with the request: {error}') -@update_pwd_decorator def parse_video( file_path: str, task: str = 'Describe this image as detail as possible.', @@ -1086,7 +1022,6 @@ def parse_video( print(f'Error with the request: {error}') -@update_pwd_decorator def parse_pptx(file_path: str) -> None: """Parses the content of a pptx file and prints it. diff --git a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython/prompt_001.log b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython/prompt_001.log index c620c89184..d9d03af5a5 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython/prompt_001.log +++ b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython/prompt_001.log @@ -396,6 +396,8 @@ The server is running on port 5000 with PID 126. You can access the list of numb 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 14 turns left to complete the task. When finished reply with . diff --git a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython/prompt_002.log b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython/prompt_002.log index 013180481a..588e886d29 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython/prompt_002.log +++ b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython/prompt_002.log @@ -412,5 +412,6 @@ with open('/workspace/test.txt', 'w') as file: OBSERVATION: [Code executed successfully with no output] +[Jupyter current working directory: /workspace] -ENVIRONMENT REMINDER: You have 13 turns left to complete the task. When finished reply with +ENVIRONMENT REMINDER: You have 13 turns left to complete the task. When finished reply with . diff --git a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_001.log b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_001.log index 3ecc273f58..8df7756295 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_001.log +++ b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_001.log @@ -396,6 +396,8 @@ The server is running on port 5000 with PID 126. You can access the list of numb NOW, LET'S START! +---------- + Install and import pymsgbox==1.0.9 and print it's version in /workspace/test.txt. Do not ask me for confirmation at any point. ENVIRONMENT REMINDER: You have 14 turns left to complete the task. When finished reply with . diff --git a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_002.log b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_002.log index 54f39c635d..fde41bc461 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_002.log +++ b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_002.log @@ -412,12 +412,12 @@ Sure! Let's start by installing the `pymsgbox` package. OBSERVATION: Collecting pymsgbox==1.0.9 Downloading PyMsgBox-1.0.9.tar.gz (18 kB) - Installing build dependencies ... [?25l- \ | / done + Installing build dependencies ... [?25l- \ | / - \ | / - \ | / - \ | / - done [?25h Getting requirements to build wheel ... [?25l- done [?25h Preparing metadata (pyproject.toml) ... [?25l- done [?25hBuilding wheels for collected packages: pymsgbox Building wheel for pymsgbox (pyproject.toml) ... [?25l- done -[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7406 sha256=7cc4ff18827e3c2e2bd0780a92ca70fd625dc7645b994b6f3191dfb0660e606e +[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7406 sha256=0aa91e03ed30fdcf42db3522fd0444c80951cccb215529a6ed9a95fc2b8a6f0c Stored in directory: /home/opendevin/.cache/pip/wheels/85/92/63/e126ee5f33d8f2ed04f96e43ef5df7270a2f331848752e8662 Successfully built pymsgbox Installing collected packages: pymsgbox @@ -426,6 +426,6 @@ Successfully installed pymsgbox-1.0.9 [notice] A new release of pip is available: 24.1 -> 24.2 [notice] To update, run: pip install --upgrade pip Note: you may need to restart the kernel to use updated packages. +[Jupyter current working directory: /workspace] - -ENVIRONMENT REMINDER: You have 13 turns left to complete the task. When finished reply with +ENVIRONMENT REMINDER: You have 13 turns left to complete the task. When finished reply with . diff --git a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_003.log b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_003.log index 2d2e459218..834293a3e9 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_003.log +++ b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_003.log @@ -412,12 +412,12 @@ Sure! Let's start by installing the `pymsgbox` package. OBSERVATION: Collecting pymsgbox==1.0.9 Downloading PyMsgBox-1.0.9.tar.gz (18 kB) - Installing build dependencies ... [?25l- \ | / done + Installing build dependencies ... [?25l- \ | / - \ | / - \ | / - \ | / - done [?25h Getting requirements to build wheel ... [?25l- done [?25h Preparing metadata (pyproject.toml) ... [?25l- done [?25hBuilding wheels for collected packages: pymsgbox Building wheel for pymsgbox (pyproject.toml) ... [?25l- done -[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7406 sha256=7cc4ff18827e3c2e2bd0780a92ca70fd625dc7645b994b6f3191dfb0660e606e +[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7406 sha256=0aa91e03ed30fdcf42db3522fd0444c80951cccb215529a6ed9a95fc2b8a6f0c Stored in directory: /home/opendevin/.cache/pip/wheels/85/92/63/e126ee5f33d8f2ed04f96e43ef5df7270a2f331848752e8662 Successfully built pymsgbox Installing collected packages: pymsgbox @@ -426,7 +426,7 @@ Successfully installed pymsgbox-1.0.9 [notice] A new release of pip is available: 24.1 -> 24.2 [notice] To update, run: pip install --upgrade pip Note: you may need to restart the kernel to use updated packages. - +[Jupyter current working directory: /workspace] ---------- @@ -444,5 +444,6 @@ with open('/workspace/test.txt', 'w') as file: OBSERVATION: [Code executed successfully with no output] +[Jupyter current working directory: /workspace] -ENVIRONMENT REMINDER: You have 12 turns left to complete the task. When finished reply with +ENVIRONMENT REMINDER: You have 12 turns left to complete the task. When finished reply with . diff --git a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_004.log b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_004.log index 043c096f61..80223e23ce 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_004.log +++ b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_004.log @@ -412,12 +412,12 @@ Sure! Let's start by installing the `pymsgbox` package. OBSERVATION: Collecting pymsgbox==1.0.9 Downloading PyMsgBox-1.0.9.tar.gz (18 kB) - Installing build dependencies ... [?25l- \ | / done + Installing build dependencies ... [?25l- \ | / - \ | / - \ | / - \ | / - done [?25h Getting requirements to build wheel ... [?25l- done [?25h Preparing metadata (pyproject.toml) ... [?25l- done [?25hBuilding wheels for collected packages: pymsgbox Building wheel for pymsgbox (pyproject.toml) ... [?25l- done -[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7406 sha256=7cc4ff18827e3c2e2bd0780a92ca70fd625dc7645b994b6f3191dfb0660e606e +[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7406 sha256=0aa91e03ed30fdcf42db3522fd0444c80951cccb215529a6ed9a95fc2b8a6f0c Stored in directory: /home/opendevin/.cache/pip/wheels/85/92/63/e126ee5f33d8f2ed04f96e43ef5df7270a2f331848752e8662 Successfully built pymsgbox Installing collected packages: pymsgbox @@ -426,7 +426,7 @@ Successfully installed pymsgbox-1.0.9 [notice] A new release of pip is available: 24.1 -> 24.2 [notice] To update, run: pip install --upgrade pip Note: you may need to restart the kernel to use updated packages. - +[Jupyter current working directory: /workspace] ---------- @@ -444,6 +444,7 @@ with open('/workspace/test.txt', 'w') as file: OBSERVATION: [Code executed successfully with no output] +[Jupyter current working directory: /workspace] ---------- @@ -460,4 +461,4 @@ pymsgbox version: 1.0.9 opendevin@docker-desktop:/workspace $ [Command -1 finished with exit code 0] -ENVIRONMENT REMINDER: You have 11 turns left to complete the task. When finished reply with +ENVIRONMENT REMINDER: You have 11 turns left to complete the task. When finished reply with . diff --git a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython/prompt_002.log b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython/prompt_002.log index e0d98a986b..59b08b3ab5 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython/prompt_002.log +++ b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython/prompt_002.log @@ -603,5 +603,6 @@ with open('/workspace/test.txt', 'w') as file: OBSERVATION: [Code executed successfully with no output] +[Jupyter current working directory: /workspace] ENVIRONMENT REMINDER: You have 13 turns left to complete the task. When finished reply with . diff --git a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_002.log b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_002.log index 16fc340733..1570f2b02a 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_002.log +++ b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_002.log @@ -603,12 +603,12 @@ Understood. Let's start by installing the `pymsgbox` package. OBSERVATION: Collecting pymsgbox==1.0.9 Downloading PyMsgBox-1.0.9.tar.gz (18 kB) - Installing build dependencies ... [?25l- \ | / - \ | / done + Installing build dependencies ... [?25l- \ | / - \ | / - \ | / - \ | / - \ done [?25h Getting requirements to build wheel ... [?25l- done [?25h Preparing metadata (pyproject.toml) ... [?25l- done [?25hBuilding wheels for collected packages: pymsgbox Building wheel for pymsgbox (pyproject.toml) ... [?25l- done -[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7406 sha256=e504d1b40c05b7da59bba1f908d23edcd98381d8e0ecc41a1162745ee4ee6fd2 +[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7406 sha256=e6c344aecd9e7b02d3ff2bb4d98a74d0fe6156b5f523d40b402350da7aac55e6 Stored in directory: /home/opendevin/.cache/pip/wheels/85/92/63/e126ee5f33d8f2ed04f96e43ef5df7270a2f331848752e8662 Successfully built pymsgbox Installing collected packages: pymsgbox @@ -617,6 +617,6 @@ Successfully installed pymsgbox-1.0.9 [notice] A new release of pip is available: 24.1 -> 24.2 [notice] To update, run: pip install --upgrade pip Note: you may need to restart the kernel to use updated packages. - +[Jupyter current working directory: /workspace] ENVIRONMENT REMINDER: You have 13 turns left to complete the task. When finished reply with . diff --git a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_003.log b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_003.log index 9fc3c047cd..c419091185 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_003.log +++ b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_003.log @@ -603,12 +603,12 @@ Understood. Let's start by installing the `pymsgbox` package. OBSERVATION: Collecting pymsgbox==1.0.9 Downloading PyMsgBox-1.0.9.tar.gz (18 kB) - Installing build dependencies ... [?25l- \ | / - \ | / done + Installing build dependencies ... [?25l- \ | / - \ | / - \ | / - \ | / - \ done [?25h Getting requirements to build wheel ... [?25l- done [?25h Preparing metadata (pyproject.toml) ... [?25l- done [?25hBuilding wheels for collected packages: pymsgbox Building wheel for pymsgbox (pyproject.toml) ... [?25l- done -[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7406 sha256=e504d1b40c05b7da59bba1f908d23edcd98381d8e0ecc41a1162745ee4ee6fd2 +[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7406 sha256=e6c344aecd9e7b02d3ff2bb4d98a74d0fe6156b5f523d40b402350da7aac55e6 Stored in directory: /home/opendevin/.cache/pip/wheels/85/92/63/e126ee5f33d8f2ed04f96e43ef5df7270a2f331848752e8662 Successfully built pymsgbox Installing collected packages: pymsgbox @@ -617,7 +617,7 @@ Successfully installed pymsgbox-1.0.9 [notice] A new release of pip is available: 24.1 -> 24.2 [notice] To update, run: pip install --upgrade pip Note: you may need to restart the kernel to use updated packages. - +[Jupyter current working directory: /workspace] ---------- @@ -637,5 +637,6 @@ version_info OBSERVATION: '1.0.9' +[Jupyter current working directory: /workspace] ENVIRONMENT REMINDER: You have 12 turns left to complete the task. When finished reply with . diff --git a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_004.log b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_004.log index 815ffa8585..d5e7cbce32 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_004.log +++ b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_004.log @@ -603,12 +603,12 @@ Understood. Let's start by installing the `pymsgbox` package. OBSERVATION: Collecting pymsgbox==1.0.9 Downloading PyMsgBox-1.0.9.tar.gz (18 kB) - Installing build dependencies ... [?25l- \ | / - \ | / done + Installing build dependencies ... [?25l- \ | / - \ | / - \ | / - \ | / - \ done [?25h Getting requirements to build wheel ... [?25l- done [?25h Preparing metadata (pyproject.toml) ... [?25l- done [?25hBuilding wheels for collected packages: pymsgbox Building wheel for pymsgbox (pyproject.toml) ... [?25l- done -[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7406 sha256=e504d1b40c05b7da59bba1f908d23edcd98381d8e0ecc41a1162745ee4ee6fd2 +[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7406 sha256=e6c344aecd9e7b02d3ff2bb4d98a74d0fe6156b5f523d40b402350da7aac55e6 Stored in directory: /home/opendevin/.cache/pip/wheels/85/92/63/e126ee5f33d8f2ed04f96e43ef5df7270a2f331848752e8662 Successfully built pymsgbox Installing collected packages: pymsgbox @@ -617,7 +617,7 @@ Successfully installed pymsgbox-1.0.9 [notice] A new release of pip is available: 24.1 -> 24.2 [notice] To update, run: pip install --upgrade pip Note: you may need to restart the kernel to use updated packages. - +[Jupyter current working directory: /workspace] ---------- @@ -637,6 +637,7 @@ version_info OBSERVATION: '1.0.9' +[Jupyter current working directory: /workspace] ---------- diff --git a/tests/unit/test_runtime.py b/tests/unit/test_runtime.py index 190998436c..50d9b67231 100644 --- a/tests/unit/test_runtime.py +++ b/tests/unit/test_runtime.py @@ -303,7 +303,10 @@ async def test_simple_cmd_ipython_and_fileop(temp_dir, box_class, run_as_devin): assert isinstance(obs, IPythonRunCellObservation) logger.info(obs, extra={'msg_type': 'OBSERVATION'}) - assert obs.content.strip() == 'Hello, `World`!' + assert ( + obs.content.strip() + == 'Hello, `World`!\n[Jupyter current working directory: /workspace]' + ) # Test read file (file should not exist) action_read = FileReadAction(path='hello.sh') @@ -768,7 +771,10 @@ async def test_ipython_multi_user(temp_dir, box_class, run_as_devin): obs = await runtime.run_action(action_ipython) assert isinstance(obs, IPythonRunCellObservation) logger.info(obs, extra={'msg_type': 'OBSERVATION'}) - assert obs.content.strip() == '/workspace' + assert ( + obs.content.strip() + == '/workspace\n[Jupyter current working directory: /workspace]' + ) # write a file test_code = "with open('test.txt', 'w') as f: f.write('Hello, world!')" @@ -777,7 +783,10 @@ async def test_ipython_multi_user(temp_dir, box_class, run_as_devin): obs = await runtime.run_action(action_ipython) logger.info(obs, extra={'msg_type': 'OBSERVATION'}) assert isinstance(obs, IPythonRunCellObservation) - assert obs.content.strip() == '[Code executed successfully with no output]' + assert ( + obs.content.strip() + == '[Code executed successfully with no output]\n[Jupyter current working directory: /workspace]' + ) # check file owner via bash action = CmdRunAction(command='ls -alh test.txt') @@ -816,7 +825,7 @@ async def test_ipython_simple(temp_dir, box_class): obs = await runtime.run_action(action_ipython) assert isinstance(obs, IPythonRunCellObservation) logger.info(obs, extra={'msg_type': 'OBSERVATION'}) - assert obs.content.strip() == '1' + assert obs.content.strip() == '1\n[Jupyter current working directory: /workspace]' await runtime.close() await asyncio.sleep(1) @@ -850,6 +859,7 @@ async def _test_ipython_agentskills_fileop_pwd_impl( '1|\n' '(this is the end of the file)\n' '[File hello.py created.]\n' + '[Jupyter current working directory: /workspace]' ).strip().split('\n') action = CmdRunAction(command='cd test') @@ -872,6 +882,7 @@ async def _test_ipython_agentskills_fileop_pwd_impl( '1|\n' '(this is the end of the file)\n' '[File hello.py created.]\n' + '[Jupyter current working directory: /workspace/test]' ).strip().split('\n') if enable_auto_lint: @@ -904,6 +915,7 @@ ERRORS: Your changes have NOT been applied. Please fix your edit command and try again. You either need to 1) Specify the correct start/end line arguments or 2) Correct your edit code. DO NOT re-run the same failed edit command. Running it again will lead to the same error. +[Jupyter current working directory: /workspace/test] """ ).strip().split('\n') @@ -922,6 +934,7 @@ DO NOT re-run the same failed edit command. Running it again will lead to the sa 1|print("hello world") (this is the end of the file) [File updated (edited at line 1). Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.] +[Jupyter current working directory: /workspace/test] """ ).strip().split('\n') @@ -988,6 +1001,7 @@ async def test_ipython_agentskills_fileop_pwd_with_userdir(temp_dir, box_class): '1|\n' '(this is the end of the file)\n' '[File hello.py created.]\n' + '[Jupyter current working directory: /root]' ).strip().split('\n') action = CmdRunAction(command='cd test') @@ -1010,6 +1024,7 @@ async def test_ipython_agentskills_fileop_pwd_with_userdir(temp_dir, box_class): '1|\n' '(this is the end of the file)\n' '[File hello.py created.]\n' + '[Jupyter current working directory: /root/test]' ).strip().split('\n') await runtime.close() @@ -1073,7 +1088,10 @@ async def test_ipython_package_install(temp_dir, box_class, run_as_devin): obs = await runtime.run_action(action) logger.info(obs, extra={'msg_type': 'OBSERVATION'}) # import should not error out - assert obs.content.strip() == '[Code executed successfully with no output]' + assert ( + obs.content.strip() + == '[Code executed successfully with no output]\n[Jupyter current working directory: /workspace]' + ) await runtime.close() await asyncio.sleep(1)