fbaea9bddc
* feat(sessions): generic 'hidden' session flag (sidebar-hide, still resumable)
Adds a source-orthogonal, archive-orthogonal 'hidden' session flag meaning
'don't show in the global Sessions sidebar, but stay fully resumable by the
surface that owns it'. Mirrors the existing archived/pinned capability end to
end, so it's a generic widening (any plugin that owns its own session lifecycle
- kanban, Bot Mode, future plugins - can keep its sessions out of the shared
recents list) rather than a per-plugin special-case.
- Schema: hidden INTEGER NOT NULL DEFAULT 0 on sessions (additive; lands on
existing DBs via the declarative _reconcile_columns ADD COLUMN path, same as
archived/pinned - no version-gated migration).
- DB: SessionDB.set_session_hidden(session_id, hidden) (clones set_session_pinned
incl. the compression-lineage recursive CTE); list_sessions_rich gains
include_hidden=False, appending 's.hidden = 0' by default so hidden rows drop
from every listing path (and the REST sidebar endpoints inherit it with no
change).
- Gateway: session.set_hidden RPC (mirrors session.title); session.create accepts
hidden=true, deferred via pending_hidden and applied in _ensure_session_db_row
when the row is lazily created (mirrors pending_title).
- REST parity: PATCH /api/sessions/{id} accepts+bool-validates 'hidden' ->
set_session_hidden; _session_response exposes it.
Enables Hermes-Bot-Mode to hide canonical 'Bot Chat' sessions from the sidebar
(NousResearch/Hermes-Bot-Mode#46) WITHOUT retagging source (which would mis-set
the agent platform). Bot Chats keep source=desktop. Gateway RPC needs a
SERVE-backend restart to take effect live. 1 focused test (default-exclude /
include_hidden / unhide round-trip).
* fix: teach lost-and-found recovery about the 55-column sessions layout
Adding the 'hidden' column makes the current sessions table 55 columns. The
SQLite lost-and-found recovery classifier keys off the physical field count
(SESSIONS_LAYOUT_NFIELDS) to identify a salvaged sessions row, so a recovered
current-layout row (nfield=55) would otherwise be unrecognized and dropped.
Add 55 to the frozenset (54/52 stay as historical prefixes) and update the
column-count assertions + synthetic current-layout insert in the recovery test.
---------
Co-authored-by: Teknium <teknium1@users.noreply.github.com>
45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
import pytest
|
|
|
|
from hermes_state import SessionDB
|
|
|
|
|
|
@pytest.fixture
|
|
def db(tmp_path):
|
|
database = SessionDB(tmp_path / "state.db")
|
|
try:
|
|
yield database
|
|
finally:
|
|
database.close()
|
|
|
|
|
|
def test_hidden_excluded_by_default_included_on_request(db):
|
|
db.create_session("visible", source="cli")
|
|
db.create_session("secret", source="cli")
|
|
# Give both a message so the default min_message_count filter keeps them.
|
|
for sid in ("visible", "secret"):
|
|
db._conn.execute(
|
|
"UPDATE sessions SET message_count = 1 WHERE id = ?", (sid,)
|
|
)
|
|
db._conn.commit()
|
|
|
|
# Flip the hidden flag on one session.
|
|
assert db.set_session_hidden("secret", True) is True
|
|
assert db.get_session("secret")["hidden"] == 1
|
|
assert db.get_session("visible")["hidden"] == 0
|
|
|
|
# Default listing drops the hidden row; include_hidden=True surfaces it.
|
|
default_ids = {s["id"] for s in db.list_sessions_rich(min_message_count=1)}
|
|
assert default_ids == {"visible"}
|
|
|
|
all_ids = {
|
|
s["id"]
|
|
for s in db.list_sessions_rich(min_message_count=1, include_hidden=True)
|
|
}
|
|
assert all_ids == {"visible", "secret"}
|
|
|
|
# Unhiding brings it back into the default listing.
|
|
assert db.set_session_hidden("secret", False) is True
|
|
assert db.get_session("secret")["hidden"] == 0
|
|
unhidden_ids = {s["id"] for s in db.list_sessions_rich(min_message_count=1)}
|
|
assert unhidden_ids == {"visible", "secret"}
|