fix: reopen resumed gateway sessions in sqlite

This commit is contained in:
landy 2026-04-13 17:50:42 +08:00 committed by Teknium
parent d945cf6b1a
commit dbed40f39b
2 changed files with 47 additions and 1 deletions

View File

@ -878,7 +878,8 @@ class SessionStore:
Used by ``/resume`` to restore a previously-named session.
Ends the current session in SQLite (like reset), but instead of
generating a fresh session ID, re-uses ``target_session_id`` so the
old transcript is loaded on the next message.
old transcript is loaded on the next message. If the target session was
previously ended, re-open it so gateway resume semantics match the CLI.
"""
db_end_session_id = None
new_entry = None
@ -918,6 +919,12 @@ class SessionStore:
except Exception as e:
logger.debug("Session DB end_session failed: %s", e)
if self._db:
try:
self._db.reopen_session(target_session_id)
except Exception as e:
logger.debug("Session DB reopen_session failed: %s", e)
return new_entry
def list_sessions(self, active_minutes: Optional[int] = None) -> List[SessionEntry]:

View File

@ -552,6 +552,45 @@ class TestLoadTranscriptPreferLongerSource:
assert result[0]["content"] == "db-q"
class TestSessionStoreSwitchSession:
"""Regression coverage for gateway /resume session switching semantics."""
def test_switch_session_reopens_target_session_in_db(self, tmp_path):
from hermes_state import SessionDB
config = GatewayConfig()
with patch("gateway.session.SessionStore._ensure_loaded"):
store = SessionStore(sessions_dir=tmp_path / "sessions", config=config)
db = SessionDB(db_path=tmp_path / "state.db")
store._db = db
store._loaded = True
source = SessionSource(
platform=Platform.FEISHU,
chat_id="chat-1",
chat_type="dm",
user_id="user-1",
user_name="tester",
)
current_entry = store.get_or_create_session(source)
current_session_id = current_entry.session_id
target_session_id = "old_session_abc"
db.create_session(target_session_id, source="feishu", user_id="user-1")
db.end_session(target_session_id, end_reason="user_exit")
assert db.get_session(target_session_id)["ended_at"] is not None
switched = store.switch_session(current_entry.session_key, target_session_id)
assert switched is not None
assert switched.session_id == target_session_id
assert db.get_session(current_session_id)["end_reason"] == "session_switch"
resumed = db.get_session(target_session_id)
assert resumed["ended_at"] is None
assert resumed["end_reason"] is None
db.close()
class TestWhatsAppDMSessionKeyConsistency:
"""Regression: all session-key construction must go through build_session_key
so DMs are isolated by chat_id across platforms."""