fix: harden /save for test doubles, async session-store boundary, snapshot shape pin
Three CI-red follow-ups on the /save rework:
- cli.py save_conversation: getattr-guard _session_db/session_id so
SimpleNamespace/object.__new__ test doubles (and any embedder passing a
minimal stub) don't AttributeError (pitfall #17 pattern).
- gateway/slash_commands.py: route through the awaited
async_session_store.get_or_create_session boundary — the architecture
test forbids raw session_store calls in async gateway code.
- tests/cli/test_save_conversation_location.py: /save now emits the
canonical export_session payload shape; the session id key is "id"
(was "session_id" in the legacy snapshot format) — update the pin.
The slice-8 lost-and-found failure was pre-existing on main and is fixed
there by f2a30fa400 (test: derive lost-and-found synthetic width from the
live schema); picked up via rebase.
This commit is contained in:
@@ -9374,10 +9374,14 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin):
|
||||
|
||||
# Prefer the durable DB row (has metadata + tool calls); fall back to
|
||||
# the in-memory history for sessions that never touched the DB.
|
||||
# getattr: test doubles (SimpleNamespace / object.__new__) may not
|
||||
# carry _session_db or session_id.
|
||||
session_data = None
|
||||
if self._session_db and self.session_id:
|
||||
_db = getattr(self, "_session_db", None)
|
||||
_sid = getattr(self, "session_id", None)
|
||||
if _db and _sid:
|
||||
try:
|
||||
session_data = self._session_db.export_session(self.session_id)
|
||||
session_data = _db.export_session(_sid)
|
||||
except Exception:
|
||||
session_data = None
|
||||
if not session_data:
|
||||
|
||||
@@ -4543,7 +4543,7 @@ class GatewaySlashCommandsMixin:
|
||||
)
|
||||
|
||||
source = event.source
|
||||
session_entry = self.session_store.get_or_create_session(source)
|
||||
session_entry = await self.async_session_store.get_or_create_session(source)
|
||||
session_id = session_entry.session_id
|
||||
|
||||
if not self._session_db:
|
||||
|
||||
@@ -75,7 +75,9 @@ def test_save_conversation_writes_under_hermes_home(hermes_home, tmp_path, monke
|
||||
|
||||
payload = json.loads(files[0].read_text())
|
||||
assert payload["model"] == "test-model"
|
||||
assert payload["session_id"] == "20260101_120000_abc123"
|
||||
# /save now emits the canonical export_session shape: the session id
|
||||
# lives under "id" (was "session_id" in the legacy snapshot format).
|
||||
assert payload["id"] == "20260101_120000_abc123"
|
||||
assert payload["messages"] == [
|
||||
{"role": "user", "content": "hi"},
|
||||
{"role": "assistant", "content": "hello"},
|
||||
|
||||
Reference in New Issue
Block a user