From cf22af0ce6b3938656d288f686c25466eab788d8 Mon Sep 17 00:00:00 2001 From: Austin Pickett Date: Mon, 11 May 2026 23:55:13 -0400 Subject: [PATCH] fix(tests): align full-suite expectations with current defaults Update stale gateway and auxiliary-client tests for current defaults, harden media delivery and API kwargs helpers for partial fixtures, and keep process-scan tests on the intended ps fallback path. Co-authored-by: Cursor --- gateway/run.py | 9 ++++++++- run_agent.py | 5 +++-- tests/agent/test_auxiliary_client.py | 2 +- tests/gateway/test_config.py | 4 ++-- tests/gateway/test_update_streaming.py | 6 +++++- tests/gateway/test_verbose_command.py | 16 ++++++++-------- tests/hermes_cli/test_update_gateway_restart.py | 3 +++ tests/run_agent/test_async_httpx_del_neuter.py | 3 ++- tests/run_agent/test_provider_parity.py | 2 +- 9 files changed, 33 insertions(+), 17 deletions(-) diff --git a/gateway/run.py b/gateway/run.py index 1da45e3f03..d006d5cebf 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -9992,7 +9992,14 @@ class GatewayRunner: _, cleaned = adapter.extract_images(response) local_files, _ = adapter.extract_local_files(cleaned) - _thread_meta = self._thread_metadata_for_source(event.source, self._reply_anchor_for_event(event)) + reply_anchor_fn = getattr(self, "_reply_anchor_for_event", None) + reply_anchor = reply_anchor_fn(event) if callable(reply_anchor_fn) else None + thread_meta_fn = getattr(self, "_thread_metadata_for_source", None) + if callable(thread_meta_fn): + _thread_meta = thread_meta_fn(event.source, reply_anchor) + else: + thread_id = getattr(event.source, "thread_id", None) + _thread_meta = {"thread_id": thread_id} if thread_id else None from gateway.platforms.base import should_send_media_as_audio diff --git a/run_agent.py b/run_agent.py index aa01c8ecdf..9894dbbcce 100644 --- a/run_agent.py +++ b/run_agent.py @@ -9373,10 +9373,11 @@ class AIAgent: # tool — this caches the entire tools array cross-session via # Anthropic's tools→system→messages prefix order. The function # returns a deep copy, so self.tools is never mutated. - if self._use_long_lived_prefix_cache and self.tools: + if getattr(self, "_use_long_lived_prefix_cache", False) and self.tools: from agent.prompt_caching import mark_tools_for_long_lived_cache tools_for_api = mark_tools_for_long_lived_cache( - self.tools, long_lived_ttl=self._long_lived_cache_ttl, + self.tools, + long_lived_ttl=getattr(self, "_long_lived_cache_ttl", "1h"), ) else: tools_for_api = self.tools diff --git a/tests/agent/test_auxiliary_client.py b/tests/agent/test_auxiliary_client.py index cdac34d328..1b2b76389c 100644 --- a/tests/agent/test_auxiliary_client.py +++ b/tests/agent/test_auxiliary_client.py @@ -666,7 +666,7 @@ class TestAuxiliaryPoolAwareness: client, model = _try_nous() assert client is not None - assert model == "google/gemini-3-flash-preview" + assert model == "qwen/qwen3.6-plus" assert mock_openai.call_args.kwargs["api_key"] == "pooled-agent-key" assert mock_openai.call_args.kwargs["base_url"] == "https://inference.pool.example/v1" diff --git a/tests/gateway/test_config.py b/tests/gateway/test_config.py index c53e34b757..c59b27d800 100644 --- a/tests/gateway/test_config.py +++ b/tests/gateway/test_config.py @@ -176,8 +176,8 @@ class TestStreamingConfig: "fresh_final_after_seconds": "oops", } ) - assert restored.edit_interval == 1.0 - assert restored.buffer_threshold == 40 + assert restored.edit_interval == 0.8 + assert restored.buffer_threshold == 24 assert restored.fresh_final_after_seconds == 60.0 diff --git a/tests/gateway/test_update_streaming.py b/tests/gateway/test_update_streaming.py index b1681e1f34..06556f006d 100644 --- a/tests/gateway/test_update_streaming.py +++ b/tests/gateway/test_update_streaming.py @@ -16,7 +16,7 @@ from unittest.mock import patch, MagicMock, AsyncMock import pytest -from gateway.config import Platform +from gateway.config import GatewayConfig, Platform from gateway.platforms.base import MessageEvent from gateway.session import SessionSource @@ -37,7 +37,11 @@ def _make_runner(hermes_home=None): """Create a bare GatewayRunner without calling __init__.""" from gateway.run import GatewayRunner runner = object.__new__(GatewayRunner) + runner.config = GatewayConfig() runner.adapters = {} + runner.session_store = MagicMock() + runner.hooks = MagicMock() + runner.hooks.emit_collect = AsyncMock(return_value=[]) runner._voice_mode = {} runner._update_prompt_pending = {} runner._running_agents = {} diff --git a/tests/gateway/test_verbose_command.py b/tests/gateway/test_verbose_command.py index d6debebae5..3b3540cf73 100644 --- a/tests/gateway/test_verbose_command.py +++ b/tests/gateway/test_verbose_command.py @@ -129,7 +129,7 @@ class TestVerboseCommand: @pytest.mark.asyncio async def test_defaults_to_all_when_no_tool_progress_set(self, tmp_path, monkeypatch): - """When tool_progress is not in config, defaults to 'all' then cycles to verbose.""" + """When tool_progress is not in config, defaults to off then cycles to all.""" hermes_home = tmp_path / "hermes" hermes_home.mkdir() config_path = hermes_home / "config.yaml" @@ -143,17 +143,17 @@ class TestVerboseCommand: runner = _make_runner() result = await runner._handle_verbose_command(_make_event()) - # Telegram default is "all" (high tier) → cycles to verbose - assert "VERBOSE" in result + # Missing explicit config uses the global off baseline, then cycles to all. + assert "ALL" in result saved = yaml.safe_load(config_path.read_text(encoding="utf-8")) - assert saved["display"]["platforms"]["telegram"]["tool_progress"] == "verbose" + assert saved["display"]["platforms"]["telegram"]["tool_progress"] == "all" @pytest.mark.asyncio async def test_per_platform_isolation(self, tmp_path, monkeypatch): """Cycling /verbose on Telegram doesn't change Slack's setting. - Without a global tool_progress, each platform uses its built-in - default: Telegram = 'all' (high tier), Slack = 'off' (quiet Slack default). + Without a global tool_progress, platforms start from the quiet + baseline and the first /verbose cycle saves their scoped preference. """ hermes_home = tmp_path / "hermes" hermes_home.mkdir() @@ -178,8 +178,8 @@ class TestVerboseCommand: saved = yaml.safe_load(config_path.read_text(encoding="utf-8")) platforms = saved["display"]["platforms"] - # Telegram: all -> verbose (high tier default = all) - assert platforms["telegram"]["tool_progress"] == "verbose" + # Missing explicit config uses the global off baseline, then cycles to all. + assert platforms["telegram"]["tool_progress"] == "all" # Slack: off -> new (first /verbose cycle from quiet default) assert platforms["slack"]["tool_progress"] == "new" diff --git a/tests/hermes_cli/test_update_gateway_restart.py b/tests/hermes_cli/test_update_gateway_restart.py index 5493acb52c..f221b6c732 100644 --- a/tests/hermes_cli/test_update_gateway_restart.py +++ b/tests/hermes_cli/test_update_gateway_restart.py @@ -1068,6 +1068,7 @@ class TestFindGatewayPidsExclude: def test_excludes_specified_pids(self, monkeypatch): monkeypatch.setattr(gateway_cli, "is_windows", lambda: False) + monkeypatch.setattr(gateway_cli.os.path, "isdir", lambda _path: False) def fake_run(cmd, **kwargs): return subprocess.CompletedProcess( @@ -1088,6 +1089,7 @@ class TestFindGatewayPidsExclude: def test_no_exclude_returns_all(self, monkeypatch): monkeypatch.setattr(gateway_cli, "is_windows", lambda: False) + monkeypatch.setattr(gateway_cli.os.path, "isdir", lambda _path: False) def fake_run(cmd, **kwargs): return subprocess.CompletedProcess( @@ -1110,6 +1112,7 @@ class TestFindGatewayPidsExclude: profile_dir = tmp_path / ".hermes" / "profiles" / "orcha" profile_dir.mkdir(parents=True) monkeypatch.setattr(gateway_cli, "is_windows", lambda: False) + monkeypatch.setattr(gateway_cli.os.path, "isdir", lambda _path: False) monkeypatch.setattr(gateway_cli, "get_hermes_home", lambda: profile_dir) def fake_run(cmd, **kwargs): diff --git a/tests/run_agent/test_async_httpx_del_neuter.py b/tests/run_agent/test_async_httpx_del_neuter.py index e616ea23ac..833146630f 100644 --- a/tests/run_agent/test_async_httpx_del_neuter.py +++ b/tests/run_agent/test_async_httpx_del_neuter.py @@ -177,12 +177,13 @@ class TestClientCacheBoundedGrowth: def test_same_key_replaces_stale_loop_entry(self): """When the loop changes, the old entry should be replaced, not duplicated.""" from agent.auxiliary_client import ( + _client_cache_key, _client_cache, _client_cache_lock, _get_cached_client, ) - key = ("test_replace", True, "", "", "", (), False) + key = _client_cache_key("test_replace", async_mode=True) # Simulate a stale entry from a closed loop old_loop = asyncio.new_event_loop() diff --git a/tests/run_agent/test_provider_parity.py b/tests/run_agent/test_provider_parity.py index 8eb7478b41..5b56d1ef3c 100644 --- a/tests/run_agent/test_provider_parity.py +++ b/tests/run_agent/test_provider_parity.py @@ -947,7 +947,7 @@ class TestAuxiliaryClientProviderPriority: with patch("agent.auxiliary_client._read_nous_auth", return_value={"access_token": "nous-tok"}), \ patch("agent.auxiliary_client.OpenAI") as mock: client, model = get_text_auxiliary_client() - assert model == "google/gemini-3-flash-preview" + assert model == "qwen/qwen3.6-plus" def test_custom_endpoint_when_no_nous(self, monkeypatch): """Custom endpoint is used when no OpenRouter/Nous keys are available.