hermes-agent/tests/run_agent/test_switch_model_reasoning_override.py
Teknium 6b81590c55
test: prune low-value tests suite-wide (wave 1) — 46,820 → 28,106 test functions
Systematic prune per AGENTS.md test policy, one pass over every major
test tree (gateway, hermes_cli, tools, agent, run_agent, plugins, cli,
cron, tui_gateway, honcho/openviking, root-level):

- DELETE: source-reading tests (read_text/getsource on prod files),
  change-detector tests (exact catalog counts, model-name snapshots,
  config version literals), mock-echo tests (assert a mock returns what
  it was told), assertion-free/trivial tests, near-duplicate
  parametrizations (boundaries + one representative kept), async/sync
  twin duplicates, cosmetic within-file variations.
- KEEP (mandatory): security/redaction/approval guards, message-role
  alternation invariants, prompt-caching/deterministic-call-id
  invariants, issue-number regression tests (deduped), E2E tests.
- 6 test files deleted outright (script-style/no-assert or fully
  redundant); conftest.py, fakes/, fixtures/ untouched.
- tests/acp/conftest.py added: autouse fixture stubs the live
  models.dev/GitHub/Copilot/Anthropic inventory fetches that ACP server
  tests performed on every session create — test_server.py 147s → 3.4s,
  and the tests are now genuinely hermetic.
- Sleep-based slowness shrunk where safe (codex_ttfb_watchdog,
  compression_concurrent_fork, etc.); no wall-clock assertion tightened.

Verification: full hermetic suite via scripts/run_tests.sh —
2439 files, 31,130 tests passed, 0 failed, 0 flaky retries, 315s wall
(baseline: 583s wall, 13,564s subprocess CPU).
2026-07-29 13:10:23 -07:00

126 lines
4.9 KiB
Python

"""Tests for per-model reasoning_effort override during /model switch.
Tests that switch_model:
1. Re-resolves reasoning_config when switching to a model with an override
2. Falls back to global when switching to a model without an override
3. Saves reasoning_config into _primary_runtime for fallback recovery
"""
import pytest
from unittest.mock import MagicMock, patch
class TestSwitchModelReasoningOverride:
"""Test switch_model re-resolves reasoning_config on model switch."""
def _make_fake_agent(self, model="gpt-5", provider="openai"):
"""Create a minimal fake agent for switch_model testing."""
agent = MagicMock()
agent.model = model
agent.provider = provider
agent.base_url = "https://api.openai.com/v1"
agent.api_mode = "openai"
agent.api_key = "test-key"
agent._client_kwargs = {"api_key": "test-key", "base_url": "https://api.openai.com/v1"}
agent._use_prompt_caching = False
agent._use_native_cache_layout = False
agent.reasoning_config = {"enabled": True, "effort": "medium"}
agent._fallback_activated = False
agent._fallback_index = 0
agent._fallback_chain = []
agent._fallback_model = None
agent._config_context_length = None
agent._transport_cache = {}
agent.context_compressor = None
agent._cached_system_prompt = None
agent._anthropic_api_key = ""
agent._anthropic_base_url = None
agent._is_anthropic_oauth = False
agent._anthropic_prompt_cache_policy = MagicMock(
return_value=(False, False)
)
agent._ensure_lmstudio_runtime_loaded = MagicMock()
agent._create_openai_client = MagicMock(return_value=MagicMock())
return agent
def test_primary_runtime_includes_reasoning_config(self):
"""After switch_model, _primary_runtime should contain reasoning_config key."""
from agent.agent_runtime_helpers import switch_model
agent = self._make_fake_agent()
fake_cfg = {
"model": {"default": "claude-opus-4.5"},
"agent": {
"reasoning_effort": "medium",
"reasoning_overrides": {
"claude-opus-4.5": "xhigh",
},
},
}
with patch("hermes_cli.config.load_config", return_value=fake_cfg):
try:
switch_model(
agent,
new_model="claude-opus-4.5",
new_provider="anthropic",
base_url="https://api.anthropic.com",
api_mode="anthropic_messages",
)
except Exception:
# Client creation may fail in test env; check _primary_runtime was set
pass
assert hasattr(agent, "_primary_runtime")
assert "reasoning_config" in agent._primary_runtime
def test_restore_primary_runtime_restores_reasoning(self):
"""restore_primary_runtime should restore reasoning_config from snapshot."""
from agent.agent_runtime_helpers import restore_primary_runtime
agent = MagicMock()
agent._primary_runtime = {
"model": "claude-opus-4.5",
"provider": "anthropic",
"base_url": "https://api.anthropic.com",
"api_mode": "anthropic_messages",
"api_key": "key",
"client_kwargs": {},
"use_prompt_caching": True,
"use_native_cache_layout": False,
"reasoning_config": {"enabled": True, "effort": "xhigh"},
"compressor_model": "claude-opus-4.5",
"compressor_base_url": "",
"compressor_api_key": "",
"compressor_provider": "",
"compressor_context_length": 0,
"compressor_api_mode": "",
"compressor_threshold_tokens": 0,
"anthropic_api_key": "key",
"anthropic_base_url": "https://api.anthropic.com",
"is_anthropic_oauth": False,
}
agent._fallback_activated = True
agent._fallback_index = 0
agent._fallback_chain = []
agent._fallback_model = None
agent._transport_cache = {}
agent._config_context_length = None
agent._rate_limited_until = 0
agent.model = "fallback-model"
agent.provider = "openai"
agent.reasoning_config = {"enabled": True, "effort": "medium"}
agent.context_compressor = MagicMock()
agent.base_url = ""
# Mock the methods restore_primary_runtime calls
agent._anthropic_prompt_cache_policy = MagicMock(return_value=(True, False))
agent._create_openai_client = MagicMock(return_value=MagicMock())
agent._ensure_lmstudio_runtime_loaded = MagicMock()
result = restore_primary_runtime(agent)
assert result is True
assert agent.reasoning_config == {"enabled": True, "effort": "xhigh"}