From b5a534d617f9eed45ccd8c36c2ddabe22dfce286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=A3=92=E6=A3=92?= Date: Sun, 10 Mar 2024 22:18:13 +0800 Subject: [PATCH 1/3] fix: ipykernel_error that is `Too many open files in system` --- metagpt/roles/role.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/metagpt/roles/role.py b/metagpt/roles/role.py index 3938664ba..73edfc52b 100644 --- a/metagpt/roles/role.py +++ b/metagpt/roles/role.py @@ -503,6 +503,9 @@ class Role(SerializationMixin, ContextMixin, BaseModel): self.rc.memory.add(rsp) # add to persistent memory + if hasattr(self, "execute_code") and hasattr(self.execute_code, "terminate"): + await self.execute_code.terminate() + return rsp async def _act_on_task(self, current_task: Task) -> TaskResult: From 1e04e3410346efafc4c8efcf35700650a2ad5608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=A3=92=E6=A3=92?= Date: Sun, 10 Mar 2024 23:52:19 +0800 Subject: [PATCH 2/3] add test. --- tests/metagpt/actions/mi/test_execute_nb_code.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/metagpt/actions/mi/test_execute_nb_code.py b/tests/metagpt/actions/mi/test_execute_nb_code.py index 59a814054..3059ad3ae 100644 --- a/tests/metagpt/actions/mi/test_execute_nb_code.py +++ b/tests/metagpt/actions/mi/test_execute_nb_code.py @@ -104,6 +104,15 @@ async def test_terminate(): time.sleep(2) assert executor.nb_client.km is None + for _ in range(200): + executor = ExecuteNbCode() + await executor.run(code='print("This is a code!")', language="python") + is_kernel_alive = await executor.nb_client.km.is_alive() + assert is_kernel_alive + await executor.terminate() + assert executor.nb_client.km is None + assert executor.nb_client.kc is None + await executor.terminate() @pytest.mark.asyncio From 803359a7588f5d955395222368320e450cc27bf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=A3=92=E6=A3=92?= Date: Mon, 11 Mar 2024 11:25:23 +0800 Subject: [PATCH 3/3] refine: add terminate in Interpreter instead of Role. --- metagpt/actions/mi/execute_nb_code.py | 3 ++- metagpt/roles/mi/interpreter.py | 4 ++++ metagpt/roles/role.py | 3 --- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/metagpt/actions/mi/execute_nb_code.py b/metagpt/actions/mi/execute_nb_code.py index 0e4563a37..3a64a8bec 100644 --- a/metagpt/actions/mi/execute_nb_code.py +++ b/metagpt/actions/mi/execute_nb_code.py @@ -58,7 +58,8 @@ class ExecuteNbCode(Action): async def terminate(self): """kill NotebookClient""" - await self.nb_client._async_cleanup_kernel() + if self.nb_client.km is not None: + await self.nb_client._async_cleanup_kernel() async def reset(self): """reset NotebookClient""" diff --git a/metagpt/roles/mi/interpreter.py b/metagpt/roles/mi/interpreter.py index fa50098e9..2392863a0 100644 --- a/metagpt/roles/mi/interpreter.py +++ b/metagpt/roles/mi/interpreter.py @@ -42,6 +42,10 @@ class Interpreter(Role): def working_memory(self): return self.rc.working_memory + async def _plan_and_act(self) -> Message: + await super()._plan_and_act() + await self.execute_code.terminate() + async def _act_on_task(self, current_task: Task) -> TaskResult: code, result, is_success = await self._write_and_exec_code() task_result = TaskResult(code=code, result=result, is_success=is_success) diff --git a/metagpt/roles/role.py b/metagpt/roles/role.py index 73edfc52b..3938664ba 100644 --- a/metagpt/roles/role.py +++ b/metagpt/roles/role.py @@ -503,9 +503,6 @@ class Role(SerializationMixin, ContextMixin, BaseModel): self.rc.memory.add(rsp) # add to persistent memory - if hasattr(self, "execute_code") and hasattr(self.execute_code, "terminate"): - await self.execute_code.terminate() - return rsp async def _act_on_task(self, current_task: Task) -> TaskResult: