mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-28 15:01:34 +08:00
* fix(tests): make AIAgent constructor calls self-contained (no env leakage)
Tests in tests/run_agent/ were constructing AIAgent() without passing
both api_key and base_url, then relying on leaked state from other
tests in the same xdist worker (or process-level env vars) to keep
provider resolution happy. Under hermetic conftest + pytest-split,
that state is gone and the tests fail with 'No LLM provider configured'.
Fix: pass both api_key and base_url explicitly on 47 AIAgent()
construction sites across 13 files. AIAgent.__init__ with both set
takes the direct-construction path (line 960 in run_agent.py) and
skips the resolver entirely.
One call site (test_none_base_url_passed_as_none) left alone — that
test asserts behavior for base_url=None specifically.
This is a prerequisite for any future matrix-split or stricter
isolation work, and lands cleanly on its own.
Validation:
- tests/run_agent/ full: 760 passed, 0 failed (local)
- Previously relied on cross-test pollution; now self-contained
* fix(tests): update opencode-go model order assertion to match kimi-k2.5-first
commit 78a74bb promoted kimi-k2.5 to first position in model suggestion
lists but didn't update this test, which has been failing on main since.
Reorder expected list to match the new canonical order.
92 lines
3.0 KiB
Python
92 lines
3.0 KiB
Python
"""Tests that plugin context engines get update_model() called during init.
|
|
|
|
Regression test for #9071 — plugin engines were never initialized with
|
|
context_length, causing the CLI status bar to show 'ctx --'.
|
|
"""
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from agent.context_engine import ContextEngine
|
|
|
|
|
|
class _StubEngine(ContextEngine):
|
|
"""Minimal concrete context engine for testing."""
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
return "stub"
|
|
|
|
def update_from_response(self, usage):
|
|
pass
|
|
|
|
def should_compress(self, prompt_tokens=None):
|
|
return False
|
|
|
|
def compress(self, messages, current_tokens=None):
|
|
return messages
|
|
|
|
|
|
def test_plugin_engine_gets_context_length_on_init():
|
|
"""Plugin context engine should have context_length set during AIAgent init."""
|
|
engine = _StubEngine()
|
|
assert engine.context_length == 0 # ABC default before fix
|
|
|
|
cfg = {"context": {"engine": "stub"}, "agent": {}}
|
|
|
|
with (
|
|
patch("hermes_cli.config.load_config", return_value=cfg),
|
|
patch("plugins.context_engine.load_context_engine", return_value=engine),
|
|
patch("agent.model_metadata.get_model_context_length", return_value=204_800),
|
|
patch("run_agent.get_tool_definitions", return_value=[]),
|
|
patch("run_agent.check_toolset_requirements", return_value={}),
|
|
patch("run_agent.OpenAI"),
|
|
):
|
|
from run_agent import AIAgent
|
|
|
|
agent = AIAgent(
|
|
api_key="test-key-1234567890",
|
|
base_url="https://openrouter.ai/api/v1",
|
|
quiet_mode=True,
|
|
skip_context_files=True,
|
|
skip_memory=True,
|
|
)
|
|
|
|
assert agent.context_compressor is engine
|
|
assert engine.context_length == 204_800
|
|
assert engine.threshold_tokens == int(204_800 * engine.threshold_percent)
|
|
|
|
|
|
def test_plugin_engine_update_model_args():
|
|
"""Verify update_model() receives model, context_length, base_url, api_key, provider."""
|
|
engine = _StubEngine()
|
|
engine.update_model = MagicMock()
|
|
|
|
cfg = {"context": {"engine": "stub"}, "agent": {}}
|
|
|
|
with (
|
|
patch("hermes_cli.config.load_config", return_value=cfg),
|
|
patch("plugins.context_engine.load_context_engine", return_value=engine),
|
|
patch("agent.model_metadata.get_model_context_length", return_value=131_072),
|
|
patch("run_agent.get_tool_definitions", return_value=[]),
|
|
patch("run_agent.check_toolset_requirements", return_value={}),
|
|
patch("run_agent.OpenAI"),
|
|
):
|
|
from run_agent import AIAgent
|
|
|
|
agent = AIAgent(
|
|
model="openrouter/auto",
|
|
api_key="test-key-1234567890",
|
|
base_url="https://openrouter.ai/api/v1",
|
|
quiet_mode=True,
|
|
skip_context_files=True,
|
|
skip_memory=True,
|
|
)
|
|
|
|
engine.update_model.assert_called_once()
|
|
kw = engine.update_model.call_args.kwargs
|
|
assert kw["context_length"] == 131_072
|
|
assert "model" in kw
|
|
assert "provider" in kw
|
|
# Should NOT pass api_mode — the ABC doesn't accept it
|
|
assert "api_mode" not in kw
|