mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-21 16:18:55 +00:00
fix(gateway): end finalized expired sessions as reset
This commit is contained in:
parent
78b9d98d76
commit
e701cdc86e
2 changed files with 80 additions and 0 deletions
|
|
@ -1582,6 +1582,19 @@ class SessionStore:
|
|||
"Session DB expiry_finalized write failed for %s: %s",
|
||||
entry.session_id, exc,
|
||||
)
|
||||
try:
|
||||
# Expiry finalization is a real conversation boundary. Without
|
||||
# a durable ``session_reset`` end_reason, later agent cleanup can
|
||||
# close the row as ``agent_close``; stale-route recovery treats
|
||||
# that as resumable and resurrects the expired full history.
|
||||
# Reopen first because SessionDB.end_session is first-writer-wins.
|
||||
self._db.reopen_session(entry.session_id)
|
||||
self._db.end_session(entry.session_id, "session_reset")
|
||||
except Exception as exc:
|
||||
logger.debug(
|
||||
"Session DB end_session(session_reset) failed for %s: %s",
|
||||
entry.session_id, exc,
|
||||
)
|
||||
|
||||
def _is_session_expired(self, entry: SessionEntry) -> bool:
|
||||
"""Check if a session has expired based on its reset policy.
|
||||
|
|
|
|||
67
tests/gateway/test_session_store_expiry_finalized.py
Normal file
67
tests/gateway/test_session_store_expiry_finalized.py
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
"""Session expiry finalization closes sessions as session_reset.
|
||||
|
||||
Regression coverage for #61220: the expiry watcher marks a session expired,
|
||||
then agent cleanup can close it as ``agent_close``. Stale routing recovery treats
|
||||
``agent_close`` as recoverable, so expired sessions were reopened with full
|
||||
history unless expiry finalization also persisted the real conversation boundary
|
||||
as ``end_reason='session_reset'``.
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from gateway.config import GatewayConfig, Platform, SessionResetPolicy
|
||||
from gateway.session import SessionEntry, SessionStore
|
||||
|
||||
|
||||
def _make_store_with_db(tmp_path, db_mock) -> SessionStore:
|
||||
config = GatewayConfig(default_reset_policy=SessionResetPolicy(mode="daily"))
|
||||
with patch("gateway.session.SessionStore._ensure_loaded"):
|
||||
store = SessionStore(sessions_dir=tmp_path, config=config)
|
||||
store._db = db_mock
|
||||
store._loaded = True
|
||||
return store
|
||||
|
||||
|
||||
def _entry(session_id: str = "sid-expired") -> SessionEntry:
|
||||
now = datetime.now()
|
||||
return SessionEntry(
|
||||
session_key="agent:main:telegram:dm:8494508720",
|
||||
session_id=session_id,
|
||||
created_at=now - timedelta(days=1),
|
||||
updated_at=now - timedelta(days=1),
|
||||
platform=Platform.TELEGRAM,
|
||||
chat_type="dm",
|
||||
model_override={"provider": "openrouter", "model": "test/model"},
|
||||
)
|
||||
|
||||
|
||||
def test_set_expiry_finalized_persists_session_reset_boundary(tmp_path):
|
||||
db = MagicMock()
|
||||
db.set_expiry_finalized.return_value = None
|
||||
db.reopen_session.return_value = None
|
||||
db.end_session.return_value = None
|
||||
store = _make_store_with_db(tmp_path, db)
|
||||
entry = _entry()
|
||||
|
||||
store.set_expiry_finalized(entry)
|
||||
|
||||
assert entry.expiry_finalized is True
|
||||
assert entry.model_override is None
|
||||
db.set_expiry_finalized.assert_called_once_with("sid-expired", True)
|
||||
db.reopen_session.assert_called_once_with("sid-expired")
|
||||
db.end_session.assert_called_once_with("sid-expired", "session_reset")
|
||||
|
||||
|
||||
def test_set_expiry_finalized_still_sets_flag_if_end_session_fails(tmp_path):
|
||||
db = MagicMock()
|
||||
db.set_expiry_finalized.return_value = None
|
||||
db.reopen_session.side_effect = RuntimeError("database locked")
|
||||
store = _make_store_with_db(tmp_path, db)
|
||||
entry = _entry()
|
||||
|
||||
store.set_expiry_finalized(entry)
|
||||
|
||||
assert entry.expiry_finalized is True
|
||||
db.set_expiry_finalized.assert_called_once_with("sid-expired", True)
|
||||
db.end_session.assert_not_called()
|
||||
Loading…
Add table
Add a link
Reference in a new issue