hermes-agent/tests/cli/test_cli_context_warning.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

133 lines
5.3 KiB
Python

"""Tests for the low context length warning in the CLI banner."""
import os
from types import SimpleNamespace
from unittest.mock import MagicMock, patch
import pytest
from agent.model_metadata import MINIMUM_CONTEXT_LENGTH
@pytest.fixture
def _isolate(tmp_path, monkeypatch):
"""Isolate HERMES_HOME so tests don't touch real config."""
home = tmp_path / ".hermes"
home.mkdir()
monkeypatch.setenv("HERMES_HOME", str(home))
@pytest.fixture
def cli_obj(_isolate):
"""Create a minimal HermesCLI instance for banner testing."""
with patch("cli.load_cli_config", return_value={
"display": {"tool_progress": "new"},
"terminal": {},
}), patch("cli.get_tool_definitions", return_value=[]), \
patch("cli.build_welcome_banner"):
from cli import HermesCLI
obj = HermesCLI.__new__(HermesCLI)
obj.model = "test-model"
obj.enabled_toolsets = ["hermes-core"]
obj.compact = False
obj.console = MagicMock()
obj.session_id = None
obj.api_key = "test"
obj.base_url = ""
obj.provider = "test"
obj._provider_source = None
# Mock agent with context compressor
obj.agent = SimpleNamespace(
context_compressor=SimpleNamespace(context_length=None)
)
return obj
class TestLowContextWarning:
"""Tests that the CLI warns about low context lengths."""
def test_warning_for_below_minimum_context(self, cli_obj):
"""Warning shown when context is below Hermes' minimum."""
cli_obj.agent.context_compressor.context_length = 32768
with patch("cli.get_tool_definitions", return_value=[]), \
patch("cli.build_welcome_banner"):
cli_obj.show_banner()
calls = [str(c) for c in cli_obj.console.print.call_args_list]
warning_calls = [c for c in calls if "too low" in c]
assert len(warning_calls) == 1
minimum_calls = [c for c in calls if f"{MINIMUM_CONTEXT_LENGTH:,}" in c]
assert minimum_calls
def test_warning_for_2048_context(self, cli_obj):
"""Warning shown for 2048 tokens (common LM Studio default)."""
cli_obj.agent.context_compressor.context_length = 2048
with patch("cli.get_tool_definitions", return_value=[]), \
patch("cli.build_welcome_banner"):
cli_obj.show_banner()
calls = [str(c) for c in cli_obj.console.print.call_args_list]
warning_calls = [c for c in calls if "too low" in c]
assert len(warning_calls) == 1
def test_no_warning_at_boundary(self, cli_obj):
"""No warning at exactly Hermes' minimum context length."""
cli_obj.agent.context_compressor.context_length = MINIMUM_CONTEXT_LENGTH
with patch("cli.get_tool_definitions", return_value=[]), \
patch("cli.build_welcome_banner"):
cli_obj.show_banner()
calls = [str(c) for c in cli_obj.console.print.call_args_list]
warning_calls = [c for c in calls if "too low" in c]
assert len(warning_calls) == 0
def test_no_warning_above_boundary(self, cli_obj):
"""No warning above Hermes' minimum context length."""
cli_obj.agent.context_compressor.context_length = MINIMUM_CONTEXT_LENGTH + 1
with patch("cli.get_tool_definitions", return_value=[]), \
patch("cli.build_welcome_banner"):
cli_obj.show_banner()
calls = [str(c) for c in cli_obj.console.print.call_args_list]
warning_calls = [c for c in calls if "too low" in c]
assert len(warning_calls) == 0
def test_ollama_specific_hint(self, cli_obj):
"""Ollama-specific fix shown when port 11434 detected."""
cli_obj.agent.context_compressor.context_length = 4096
cli_obj.base_url = "http://localhost:11434/v1"
with patch("cli.get_tool_definitions", return_value=[]), \
patch("cli.build_welcome_banner"):
cli_obj.show_banner()
calls = [str(c) for c in cli_obj.console.print.call_args_list]
ollama_hints = [c for c in calls if "OLLAMA_CONTEXT_LENGTH" in c]
assert len(ollama_hints) == 1
assert str(MINIMUM_CONTEXT_LENGTH) in ollama_hints[0]
def test_generic_hint_for_other_servers(self, cli_obj):
"""Generic fix shown for unknown servers."""
cli_obj.agent.context_compressor.context_length = 4096
cli_obj.base_url = "http://localhost:8080/v1"
with patch("cli.get_tool_definitions", return_value=[]), \
patch("cli.build_welcome_banner"):
cli_obj.show_banner()
calls = [str(c) for c in cli_obj.console.print.call_args_list]
generic_hints = [c for c in calls if "config.yaml" in c]
assert len(generic_hints) == 1
def test_compact_banner_does_not_crash_on_narrow_terminal(self, cli_obj):
"""Compact mode should still have ctx_len defined for warning logic."""
cli_obj.agent.context_compressor.context_length = 4096
with patch("shutil.get_terminal_size", return_value=os.terminal_size((70, 40))), \
patch("cli._build_compact_banner", return_value="compact banner"):
cli_obj.show_banner()
calls = [str(c) for c in cli_obj.console.print.call_args_list]
warning_calls = [c for c in calls if "too low" in c]
assert len(warning_calls) == 1