From d6816caf588feb0db90c603938ac128ca0c1af3a Mon Sep 17 00:00:00 2001 From: Dominik Jain Date: Mon, 20 Apr 2026 13:48:22 +0200 Subject: [PATCH] Make open_url_in_brower more flexible, avoiding unnecessary subprocess in tray manager --- src/serena/agent.py | 4 ++-- src/serena/dashboard.py | 28 ++++++++++++++++++---------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/serena/agent.py b/src/serena/agent.py index c37d3b04..221b2cdf 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -338,7 +338,7 @@ class DashboardManager: self.open_dashboard_in_browser() def open_dashboard_in_browser(self) -> None: - open_url_in_browser(self.url) + open_url_in_browser(self.url, use_subprocess=True) @staticmethod def _start_dashboard_viewer_process_function(url: str, minimized: bool, parent_process_id: int) -> None: @@ -351,7 +351,7 @@ class DashboardManager: log.warning(f"Could not open Serena Dashboard viewer. Cause:\n{e}") # Fall back to opening the browser window if the window was supposed to be shown directly if not minimized: - open_url_in_browser(url) + open_url_in_browser(url, use_subprocess=True) def _start_dashboard_viewer(self, minimized: bool) -> None: """ diff --git a/src/serena/dashboard.py b/src/serena/dashboard.py index f66a7b93..e1da5efa 100644 --- a/src/serena/dashboard.py +++ b/src/serena/dashboard.py @@ -789,20 +789,28 @@ class SerenaDashboardAPI: return thread, port -def open_url_in_browser(url: str) -> None: +def open_url_in_browser(url: str, use_subprocess: bool = False) -> None: """ - Opens the given URL in the user's default web browser without blocking the main process or printing any output. + Opens the given URL in the user's default web browser, + optionally using a subprocess to ensure that no output is written to stdout + (highly problematic when run within a stdio MCP server context) :param url: the URL to open + :param use_subprocess: whether to use a subprocess to opening the URL, making stdio contamination impossible """ - # Use a subprocess to avoid any output from webbrowser.open being written to stdout - subprocess.Popen( - [sys.executable, "-c", f"import webbrowser; webbrowser.open({url!r})"], - stdin=subprocess.DEVNULL, - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL, - start_new_session=False, - ) + if use_subprocess: + # Use a subprocess to avoid any output from webbrowser.open being written to stdout + subprocess.Popen( + [sys.executable, "-c", f"import webbrowser; webbrowser.open({url!r})"], + stdin=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + start_new_session=False, + ) + else: + import webbrowser + + webbrowser.open(url) class SerenaDashboardViewer(WebViewWithTray):