mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-06 12:52:11 +00:00
fix(agent): keep cooldown state on the active session (#54465)
This commit is contained in:
parent
cafe9d9261
commit
6fd701acbe
2 changed files with 57 additions and 1 deletions
18
run_agent.py
18
run_agent.py
|
|
@ -692,6 +692,24 @@ class AIAgent:
|
|||
reset_engine=True,
|
||||
)
|
||||
|
||||
# Reset-only session switches (/new, /resume, /branch) update
|
||||
# agent.session_id before calling reset_session_state(). The built-in
|
||||
# compressor keeps durable cooldown state keyed by its bound session,
|
||||
# so rebind it when the active session changed but no full start hook ran.
|
||||
engine = getattr(self, "context_compressor", None)
|
||||
target_session_id = getattr(self, "session_id", "") or ""
|
||||
bound_session_id = getattr(engine, "_session_id", "") if engine is not None else ""
|
||||
if (
|
||||
engine is not None
|
||||
and hasattr(engine, "bind_session_state")
|
||||
and target_session_id
|
||||
and target_session_id != bound_session_id
|
||||
):
|
||||
try:
|
||||
engine.bind_session_state(getattr(self, "_session_db", None), target_session_id)
|
||||
except Exception as exc:
|
||||
logger.debug("context engine bind_session_state during reset: %s", exc)
|
||||
|
||||
def _ensure_lmstudio_runtime_loaded(self, config_context_length: Optional[int] = None) -> None:
|
||||
"""
|
||||
Preload the LM Studio model with at least Hermes' minimum context.
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ from __future__ import annotations
|
|||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
|
||||
from agent.context_compressor import ContextCompressor
|
||||
from hermes_state import SessionDB
|
||||
from run_agent import AIAgent
|
||||
|
||||
|
||||
|
|
@ -158,6 +159,43 @@ def test_reset_session_state_default_call_only_resets():
|
|||
assert not engine.on_session_start.called
|
||||
|
||||
|
||||
def test_reset_session_state_rebinds_builtin_compressor_after_session_switch(tmp_path, monkeypatch):
|
||||
"""Reset-only session switches must rebind durable cooldown state to the new session."""
|
||||
db = SessionDB(db_path=tmp_path / "state.db")
|
||||
db.create_session("old-sid", source="cli")
|
||||
db.create_session("new-sid", source="cli")
|
||||
db.record_compression_failure_cooldown("old-sid", 4_000_000_000.0, "old-timeout")
|
||||
|
||||
monkeypatch.setattr(
|
||||
"agent.context_compressor.get_model_context_length",
|
||||
lambda *_a, **_k: 100_000,
|
||||
)
|
||||
compressor = ContextCompressor(
|
||||
model="fake-model",
|
||||
threshold_percent=0.85,
|
||||
protect_first_n=2,
|
||||
protect_last_n=2,
|
||||
quiet_mode=True,
|
||||
)
|
||||
compressor.bind_session_state(db, "old-sid")
|
||||
|
||||
agent = _bare_agent()
|
||||
agent._session_db = db
|
||||
agent.context_compressor = compressor
|
||||
agent.session_id = "new-sid"
|
||||
|
||||
agent.reset_session_state()
|
||||
|
||||
assert compressor._session_id == "new-sid"
|
||||
assert compressor.get_active_compression_failure_cooldown() is None
|
||||
assert db.get_compression_failure_cooldown("old-sid") is not None
|
||||
|
||||
compressor._record_compression_failure_cooldown(30.0, "new-timeout")
|
||||
|
||||
assert db.get_compression_failure_cooldown("new-sid") is not None
|
||||
assert db.get_compression_failure_cooldown("old-sid")["error"] == "old-timeout"
|
||||
|
||||
|
||||
def test_update_from_response_forwards_canonical_cache_buckets():
|
||||
"""conversation_loop passes cache_read/write/reasoning tokens to engine."""
|
||||
# Test the contract directly: a usage_dict built from CanonicalUsage must
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue