diff --git a/src/serena/agent.py b/src/serena/agent.py index 6f3c203b..ca763b87 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -25,6 +25,7 @@ from serena.project import Project from serena.prompt_factory import SerenaPromptFactory from serena.task_executor import TaskExecutor from serena.tools import ActivateProjectTool, GetCurrentConfigTool, ReplaceContentTool, Tool, ToolMarker, ToolRegistry +from serena.util.gui import system_has_usable_display from serena.util.inspection import iter_subclasses from serena.util.logging import MemoryLogHandler from solidlsp.ls_config import Language @@ -284,11 +285,14 @@ class SerenaAgent: dashboard_url = f"http://{dashboard_host}:{port}/dashboard/index.html" log.info("Serena web dashboard started at %s", dashboard_url) if self.serena_config.web_dashboard_open_on_launch: - # open the dashboard URL in the default web browser (using a separate process to control - # output redirection) - process = multiprocessing.Process(target=self._open_dashboard, args=(dashboard_url,)) - process.start() - process.join(timeout=1) + if not system_has_usable_display(): + log.warning("Not opening the Serena web dashboard automatically because no usable display was detected.") + else: + # open the dashboard URL in the default web browser (using a separate process to control + # output redirection) + process = multiprocessing.Process(target=self._open_dashboard, args=(dashboard_url,)) + process.start() + process.join(timeout=1) # inform the GUI window (if any) if self._gui_log_viewer is not None: self._gui_log_viewer.set_dashboard_url(dashboard_url) diff --git a/src/serena/util/gui.py b/src/serena/util/gui.py new file mode 100644 index 00000000..f87236d4 --- /dev/null +++ b/src/serena/util/gui.py @@ -0,0 +1,22 @@ +import os +import platform + + +def system_has_usable_display() -> bool: + system = platform.system() + + # macOS and native Windows: assume display is available for desktop usage + if system == "Darwin" or system == "Windows": + return True + + # Other systems, assumed to be Unix-like (Linux, FreeBSD, Cygwin/MSYS, etc.): + # detect display availability since users may operate in CLI contexts + else: + # Check X11 or Wayland - if environment variables are set to non-empty values, assume display is usable + display = os.environ.get("DISPLAY", "") + wayland_display = os.environ.get("WAYLAND_DISPLAY", "") + + if display or wayland_display: + return True + + return False