diff --git a/src/serena/agent.py b/src/serena/agent.py index 93f40c65..3c6e14e3 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -699,6 +699,11 @@ class SerenaAgent: f"(2) Configure one MCP server per backend in your client." ) + # shut down the previously active project to release its language server processes + if self._active_project is not None: + log.info(f"Shutting down previously active project '{self._active_project.project_name}' before switching") + self._active_project.shutdown() + self._active_project = project project.set_agent(self) @@ -845,7 +850,8 @@ class SerenaAgent: """ Shuts down the agent, freeing resources and stopping background tasks. """ - if not hasattr(self, "_is_initialized"): + # guard against __del__ being called on a partially constructed instance + if not hasattr(self, "_active_project"): return log.info("SerenaAgent is shutting down ...") if self._active_project is not None: diff --git a/src/serena/mcp.py b/src/serena/mcp.py index 83b8278b..c83dadc7 100644 --- a/src/serena/mcp.py +++ b/src/serena/mcp.py @@ -341,8 +341,12 @@ class SerenaMCPFactory: openai_tool_compatible = self.context.name in ["chatgpt", "codex", "oaicompat-agent"] self._set_mcp_tools(mcp_server, openai_tool_compatible=openai_tool_compatible) log.info("MCP server lifetime setup complete") - yield - log.info("MCP server shutting down") + try: + yield + finally: + log.info("MCP server shutting down") + if self.agent is not None: + self.agent.shutdown() def _get_initial_instructions(self) -> str: assert self.agent is not None