From e61f1a29a6d705473c5f747259d8f5f8816961e5 Mon Sep 17 00:00:00 2001 From: Dominik Jain Date: Wed, 2 Jul 2025 18:33:18 +0200 Subject: [PATCH 1/2] Fix shutdown trying to use removed function from process_isolated_agent --- src/serena/dashboard.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/serena/dashboard.py b/src/serena/dashboard.py index 4cd98b6..8ab3412 100644 --- a/src/serena/dashboard.py +++ b/src/serena/dashboard.py @@ -128,11 +128,8 @@ class SerenaDashboardAPI: if self._shutdown_callback: self._shutdown_callback() else: - # Try to use the global shutdown function from process_isolated_agent - from serena.process_isolated_agent import request_global_shutdown - - request_global_shutdown() # noinspection PyProtectedMember + # noinspection PyUnresolvedReferences os._exit(0) @staticmethod From a1c972f2e7317fb2a9e94cca980692e194893668 Mon Sep 17 00:00:00 2001 From: Dominik Jain Date: Wed, 2 Jul 2025 19:01:54 +0200 Subject: [PATCH 2/2] Redirect output of webbrowser (can contaminate stdout otherwise) #257 --- pyproject.toml | 1 + src/serena/agent.py | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8ad0332..e0f4794 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -224,6 +224,7 @@ ignore = [ "TID252", # forbids relative imports "B904", # forces use of raise from other_exception "RUF012", # forbids mutable attributes as ClassVar + "SIM117", # forbids nested with statements ] unfixable = ["F841", "F601", "F602", "B018"] extend-fixable = ["F401", "B905", "W291"] diff --git a/src/serena/agent.py b/src/serena/agent.py index 4f83737..8c2abfd 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -2,6 +2,7 @@ The Serena Model Context Protocol (MCP) Server """ +import contextlib import inspect import json import os @@ -795,7 +796,11 @@ class SerenaAgent: Logger.root.addHandler(dashboard_log_handler) self._dashboard_thread, port = SerenaDashboardAPI(dashboard_log_handler, tool_names).run_in_thread() if self.serena_config.web_dashboard_open_on_launch: - webbrowser.open(f"http://localhost:{port}/dashboard/index.html") + # open the dashboard URL in the default web browser, making sure to redirect output, + # as this can print to stdout (contaminating the MCP server stream) + with open(os.devnull, "w") as fnull: + with contextlib.redirect_stdout(fnull), contextlib.redirect_stderr(fnull): + webbrowser.open(f"http://localhost:{port}/dashboard/index.html") log.info(f"Starting Serena server (version={serena_version()}, process id={os.getpid()}, parent process id={os.getppid()})") log.info("Available projects: {}".format(", ".join(self.serena_config.project_names)))