diff --git a/tests/tools/test_browser_hardening.py b/tests/tools/test_browser_hardening.py index 657edad2a20..23ff9c93b9c 100644 --- a/tests/tools/test_browser_hardening.py +++ b/tests/tools/test_browser_hardening.py @@ -115,6 +115,29 @@ class TestCommandTimeoutCache: mock_read.assert_called_once() +class TestSessionInactivityTimeout: + + def test_default_is_300(self, monkeypatch): + from tools.browser_tool import _get_session_inactivity_timeout + monkeypatch.delenv("BROWSER_INACTIVITY_TIMEOUT", raising=False) + with patch("hermes_cli.config.read_raw_config", return_value={}): + assert _get_session_inactivity_timeout() == 300 + + def test_reads_from_config_over_env(self, monkeypatch): + from tools.browser_tool import _get_session_inactivity_timeout + monkeypatch.setenv("BROWSER_INACTIVITY_TIMEOUT", "120") + cfg = {"browser": {"inactivity_timeout": 900}} + with patch("hermes_cli.config.read_raw_config", return_value=cfg): + assert _get_session_inactivity_timeout() == 900 + + def test_floor_at_30_seconds(self, monkeypatch): + from tools.browser_tool import _get_session_inactivity_timeout + monkeypatch.setenv("BROWSER_INACTIVITY_TIMEOUT", "120") + cfg = {"browser": {"inactivity_timeout": 1}} + with patch("hermes_cli.config.read_raw_config", return_value=cfg): + assert _get_session_inactivity_timeout() == 30 + + # --------------------------------------------------------------------------- # Caching: _discover_homebrew_node_dirs # --------------------------------------------------------------------------- diff --git a/tools/browser_tool.py b/tools/browser_tool.py index 66684b8ee35..2c56bf9bb7e 100644 --- a/tools/browser_tool.py +++ b/tools/browser_tool.py @@ -1177,10 +1177,23 @@ _cleanup_done = False # Inactivity Timeout Configuration # ============================================================================= -# Session inactivity timeout (seconds) - cleanup if no activity for this long -# Default: 5 minutes. Needs headroom for LLM reasoning between browser commands, -# especially when subagents are doing multi-step browser tasks. -BROWSER_SESSION_INACTIVITY_TIMEOUT = env_int("BROWSER_INACTIVITY_TIMEOUT", 300) +# Session inactivity timeout (seconds) - cleanup if no activity for this long. +# config.yaml is authoritative; BROWSER_INACTIVITY_TIMEOUT remains a legacy +# fallback so old deployments keep working if they have not migrated yet. +def _get_session_inactivity_timeout() -> int: + result = env_int("BROWSER_INACTIVITY_TIMEOUT", 300) + try: + from hermes_cli.config import read_raw_config + cfg = read_raw_config() + val = cfg_get(cfg, "browser", "inactivity_timeout") + if val is not None: + result = max(int(val), 30) # Floor at 30s to avoid instant reaping + except Exception as e: + logger.debug("Could not read inactivity_timeout from config: %s", e) + return result + + +BROWSER_SESSION_INACTIVITY_TIMEOUT = _get_session_inactivity_timeout() # Track last activity time per session _session_last_activity: Dict[str, float] = {}