Skip to content

Commit 09430b0

Browse files
committed
Fix: Host validation required a local host even if the listen address was set to a non-local address
(regression introduced in 1.5.2)
1 parent 3240403 commit 09430b0

3 files changed

Lines changed: 24 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ Status of the `main` branch. Changes prior to the next official version change w
88
and `workspace/configuration` pulls. Enables Yarn PnP setups with `typescript.tsdk` pointing
99
at the Yarn-generated SDK.
1010

11+
* Dashboard:
12+
- Fix: Host validation required a local host regardless of the listen address (regression introduced in v1.5.2),
13+
preventing remote connections
14+
1115
# v1.5.3 (2026-05-26)
1216

1317
# v1.5.2 (2026-05-26)
@@ -17,6 +21,9 @@ Status of the `main` branch. Changes prior to the next official version change w
1721
- Add `serena-agent` CLI command so that `uvx serena-agent` can be used as entrypoint.
1822
- Fortls and pyright are now installed on the fly instead of being bundled in the serena-agent package.
1923

24+
* Dashboard:
25+
- Add host validation
26+
2027
* Hooks:
2128
- Extend list of extensions that are considered code files (affects the reminder hook counter).
2229

src/serena/agent.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,8 +664,12 @@ def get_memory_log_handler() -> MemoryLogHandler:
664664
# may access various parts of the agent
665665
if self.serena_config.web_dashboard:
666666
self._dashboard_thread, port = SerenaDashboardAPI(
667-
get_memory_log_handler(), tool_names, agent=self, tool_usage_stats=self._tool_usage_stats
668-
).run_in_thread(host=self.serena_config.web_dashboard_listen_address)
667+
get_memory_log_handler(),
668+
tool_names,
669+
agent=self,
670+
tool_usage_stats=self._tool_usage_stats,
671+
host=self.serena_config.web_dashboard_listen_address,
672+
).run_in_thread()
669673
self._dashboard_manager = DashboardManager(
670674
port,
671675
self.serena_config.web_dashboard_listen_address,

src/serena/dashboard.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,14 +197,16 @@ def __init__(
197197
tool_names: list[str],
198198
agent: "SerenaAgent",
199199
tool_usage_stats: ToolUsageStats | None = None,
200+
host: str = "127.0.0.1",
200201
) -> None:
201202
self._memory_log_handler = memory_log_handler
202203
self._tool_names = tool_names
203204
self._agent = agent
205+
self._host = host
204206
self._app = Flask(__name__)
205-
206-
self._app.config["TRUSTED_HOSTS"] = ["127.0.0.1", "localhost"]
207-
207+
local_hosts = ["127.0.0.1", "localhost"]
208+
if self._host in local_hosts:
209+
self._app.config["TRUSTED_HOSTS"] = local_hosts
208210
self._tool_usage_stats = tool_usage_stats
209211
self._loaded_news: dict[str, str] = {}
210212
self._news_ready = threading.Event()
@@ -770,21 +772,21 @@ def _find_first_free_port(start_port: int, host: str) -> int:
770772

771773
raise RuntimeError(f"No free ports found starting from {start_port}")
772774

773-
def run(self, host: str, port: int) -> int:
775+
def run(self, port: int) -> int:
774776
"""
775777
Runs the dashboard on the given host and port and returns the port number.
776778
"""
777779
# patch flask.cli.show_server to avoid printing the server info
778780
from flask import cli
779781

780782
cli.show_server_banner = lambda *args, **kwargs: None
781-
self._app.run(host=host, port=port, debug=False, use_reloader=False, threaded=True)
783+
self._app.run(host=self._host, port=port, debug=False, use_reloader=False, threaded=True)
782784
return port
783785

784-
def run_in_thread(self, host: str) -> tuple[threading.Thread, int]:
785-
port = self._find_first_free_port(self.BASE_PORT, host)
786-
log.info("Starting dashboard (listen_address=%s, port=%d)", host, port)
787-
thread = threading.Thread(target=lambda: self.run(host=host, port=port), daemon=True)
786+
def run_in_thread(self) -> tuple[threading.Thread, int]:
787+
port = self._find_first_free_port(self.BASE_PORT, self._host)
788+
log.info("Starting dashboard (listen_address=%s, port=%d)", self._host, port)
789+
thread = threading.Thread(target=lambda: self.run(port=port), daemon=True)
788790
thread.start()
789791
return thread, port
790792

0 commit comments

Comments
 (0)