mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
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).
159 lines
5 KiB
Python
159 lines
5 KiB
Python
"""Tests for cold-start credits hydration at session open.
|
|
|
|
The L3 cold-start seed primes agent._credits_state from /api/oauth/account (or a
|
|
HERMES_DEV_CREDITS_FIXTURE) so depletion AND the 90% grant warning fire immediately
|
|
at session open, not only after the first inference header. These tests assert the
|
|
notice policy fires correctly for a seed-shaped CreditsState with the warn90 latch
|
|
primed the way conversation_loop does it.
|
|
"""
|
|
import time
|
|
|
|
from agent.credits_tracker import CreditsState, evaluate_credits_notices
|
|
|
|
|
|
def _cold_start_notices(state: CreditsState):
|
|
"""Mirror the conversation_loop seed: prime seen_below_90 when used_fraction is
|
|
computable (the snapshot IS the first observation), then evaluate once."""
|
|
latch = {"active": set(), "seen_below_90": False}
|
|
if state.used_fraction is not None:
|
|
latch["seen_below_90"] = True
|
|
show, clear = evaluate_credits_notices(state, latch)
|
|
return [n.key for n in show]
|
|
|
|
|
|
def _state(**kw) -> CreditsState:
|
|
kw.setdefault("from_header", False)
|
|
kw.setdefault("captured_at", time.time())
|
|
return CreditsState(**kw)
|
|
|
|
|
|
def test_cold_start_healthy_no_notice():
|
|
s = _state(
|
|
remaining_micros=30_340_000, subscription_micros=18_000_000,
|
|
subscription_limit_micros=20_000_000, subscription_limit_usd="20.00",
|
|
denominator_kind="subscription_cap", paid_access=True,
|
|
)
|
|
assert abs(s.used_fraction - 0.1) < 1e-9
|
|
assert _cold_start_notices(s) == []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_dev_fixtures_drive_cold_start():
|
|
"""Every HERMES_DEV_CREDITS_FIXTURE state produces a valid seed CreditsState."""
|
|
import os
|
|
|
|
from agent.credits_tracker import dev_fixture_credits_state
|
|
|
|
expected = {
|
|
"healthy": [],
|
|
"sub_90pct": ["credits.usage"],
|
|
"depleted": ["credits.depleted"],
|
|
}
|
|
for name, want in expected.items():
|
|
os.environ["HERMES_DEV_CREDITS"] = "1" # fixtures gate on the dev flag
|
|
os.environ["HERMES_DEV_CREDITS_FIXTURE"] = name
|
|
try:
|
|
fx = dev_fixture_credits_state()
|
|
assert fx is not None, name
|
|
assert _cold_start_notices(fx) == want, (name, _cold_start_notices(fx))
|
|
finally:
|
|
os.environ.pop("HERMES_DEV_CREDITS_FIXTURE", None)
|
|
os.environ.pop("HERMES_DEV_CREDITS", None)
|
|
|
|
|
|
# ── seed_credits_at_session_start: the shared session-open hydrator ───────────
|
|
|
|
|
|
class _FakeAgent:
|
|
"""Minimal agent surface for the seed helper: state slots + an emit that runs
|
|
the real policy against the latch (mirroring run_agent._emit_credits_notices,
|
|
including the free-model suppression flag)."""
|
|
|
|
def __init__(self, provider="nous", model=""):
|
|
from agent.credits_tracker import evaluate_credits_notices, is_free_tier_model
|
|
|
|
self.provider = provider
|
|
self.model = model
|
|
self._credits_state = None
|
|
self._credits_session_start_micros = None
|
|
self._credits_latch = {"active": set(), "seen_below_90": False, "usage_band": None}
|
|
self.emitted: list = []
|
|
self._eval = evaluate_credits_notices
|
|
self._is_free = is_free_tier_model
|
|
|
|
def _emit_credits_notices(self):
|
|
if self._credits_state is None:
|
|
return
|
|
show, clear = self._eval(
|
|
self._credits_state,
|
|
self._credits_latch,
|
|
model_is_free=self._is_free(self.model),
|
|
)
|
|
self.emitted.append(([n.key for n in show], clear))
|
|
|
|
|
|
def _seed(agent, fixture):
|
|
import os
|
|
|
|
from agent.credits_tracker import seed_credits_at_session_start
|
|
|
|
os.environ["HERMES_DEV_CREDITS"] = "1" # fixtures gate on the dev flag
|
|
os.environ["HERMES_DEV_CREDITS_FIXTURE"] = fixture
|
|
try:
|
|
return seed_credits_at_session_start(agent)
|
|
finally:
|
|
os.environ.pop("HERMES_DEV_CREDITS_FIXTURE", None)
|
|
os.environ.pop("HERMES_DEV_CREDITS", None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_live_crossing_after_seed_still_fires_grant_spent():
|
|
"""The gate opens when the session observes the grant NOT yet spent — a healthy
|
|
seed followed by a grant-exhausted header is a real in-session crossing and must
|
|
still announce grant_spent once."""
|
|
a = _FakeAgent()
|
|
assert _seed(a, "healthy") is True
|
|
a.emitted = []
|
|
a._credits_state = _state( # the grant_exhausted shape, as a live header would carry it
|
|
remaining_micros=12_340_000, subscription_micros=0,
|
|
subscription_limit_micros=20_000_000, subscription_limit_usd="20.00",
|
|
purchased_micros=12_340_000, purchased_usd="12.34",
|
|
denominator_kind="subscription_cap", paid_access=True,
|
|
)
|
|
a._emit_credits_notices()
|
|
assert a.emitted == [(["credits.grant_spent"], [])]
|
|
|
|
|
|
def test_seed_is_idempotent():
|
|
a = _FakeAgent()
|
|
_seed(a, "sub_90pct")
|
|
a.emitted = []
|
|
# second call must no-op (state already populated)
|
|
assert _seed(a, "sub_90pct") is False
|
|
assert a.emitted == []
|
|
|
|
|
|
def test_seed_skips_non_nous():
|
|
from agent.credits_tracker import seed_credits_at_session_start
|
|
|
|
a = _FakeAgent(provider="openrouter")
|
|
assert seed_credits_at_session_start(a) is False
|
|
assert a._credits_state is None
|