diff --git a/gateway/platforms/api_server.py b/gateway/platforms/api_server.py index fb23664f017..ee4ff239198 100644 --- a/gateway/platforms/api_server.py +++ b/gateway/platforms/api_server.py @@ -1480,10 +1480,11 @@ class APIServerAdapter(BasePlatformAdapter): if err: return err db = self._ensure_session_db() - messages = db.get_messages(session_id) + resolved_id = db.resolve_resume_session_id(session_id) + messages = db.get_messages(resolved_id) return web.json_response({ "object": "list", - "session_id": session_id, + "session_id": resolved_id, "data": [self._message_response(m) for m in messages], }) diff --git a/hermes_cli/web_server.py b/hermes_cli/web_server.py index fd6ada67d69..224003c5924 100644 --- a/hermes_cli/web_server.py +++ b/hermes_cli/web_server.py @@ -5470,6 +5470,7 @@ async def get_session_messages(session_id: str, profile: Optional[str] = None): sid = db.resolve_session_id(session_id) if not sid: raise HTTPException(status_code=404, detail="Session not found") + sid = db.resolve_resume_session_id(sid) messages = db.get_messages(sid) return {"session_id": sid, "messages": messages} finally: diff --git a/tests/gateway/test_session_api.py b/tests/gateway/test_session_api.py index d5262e9aecb..28d15e9a554 100644 --- a/tests/gateway/test_session_api.py +++ b/tests/gateway/test_session_api.py @@ -121,6 +121,26 @@ async def test_session_crud_and_message_history(adapter, session_db): assert session_db.get_session(session_id) is None +@pytest.mark.asyncio +async def test_session_messages_follow_compression_tip(adapter, session_db): + source_id = session_db.create_session("source-session", "api_server") + session_db.append_message(source_id, "user", "before compression") + session_db.end_session(source_id, "compression") + session_db.create_session("tip-session", "api_server", parent_session_id=source_id) + session_db.replace_messages(source_id, []) + session_db.append_message("tip-session", "user", "after compression") + + app = _create_session_app(adapter) + async with TestClient(TestServer(app)) as cli: + messages_resp = await cli.get(f"/api/sessions/{source_id}/messages") + assert messages_resp.status == 200 + messages = await messages_resp.json() + + assert messages["object"] == "list" + assert messages["session_id"] == "tip-session" + assert [m["content"] for m in messages["data"]] == ["after compression"] + + @pytest.mark.asyncio async def test_session_fork_uses_current_sessiondb_branch_primitives(adapter, session_db): source_id = session_db.create_session("source-session", "api_server", model="test-model") diff --git a/tests/hermes_cli/test_web_server.py b/tests/hermes_cli/test_web_server.py index 2e1c48f80b6..2d9cd5a5ce2 100644 --- a/tests/hermes_cli/test_web_server.py +++ b/tests/hermes_cli/test_web_server.py @@ -638,6 +638,37 @@ class TestWebServerEndpoints: for r in results ) + def test_get_session_messages_follows_compression_tip(self): + """Reading a compressed session by its old id should hydrate from the + live continuation, matching /resume behavior.""" + import time as _time + + from hermes_state import SessionDB + + db = SessionDB() + try: + db.create_session(session_id="desktop-root", source="cli") + db.append_message(session_id="desktop-root", role="user", content="before compression") + db.end_session("desktop-root", "compression") + now = _time.time() + db._conn.execute( + "UPDATE sessions SET started_at = ?, ended_at = ? WHERE id = ?", + (now - 10, now - 5, "desktop-root"), + ) + db.create_session(session_id="desktop-tip", source="cli", parent_session_id="desktop-root") + db._conn.execute("UPDATE sessions SET started_at = ? WHERE id = ?", (now - 4, "desktop-tip")) + db.replace_messages("desktop-root", []) + db.append_message(session_id="desktop-tip", role="user", content="after compression") + db._conn.commit() + finally: + db.close() + + resp = self.client.get("/api/sessions/desktop-root/messages") + assert resp.status_code == 200 + payload = resp.json() + assert payload["session_id"] == "desktop-tip" + assert [m["content"] for m in payload["messages"]] == ["after compression"] + def test_get_sessions_archived_is_boolean(self): from hermes_state import SessionDB