fix(tui-gateway): session.set_hidden no longer logs a stored-id hide as a rejected RPC

session.set_hidden is two-tier by design: live runtime id first, then a stored id/key
resolved in the profile db (the Bot Mode sweep and any plugin reconciling sessions it
owns hold stored ids for chats that are not live). The first tier went through
_sess_nowait, which logs "session-scoped RPC rejected: … not in memory (detached/reaped
runtime; client should resume the stored session)" — a warning meant to make a vanished
prompt.submit diagnosable — for every hide that was then fulfilled from the db. A
startup sweep over a handful of stored ids thus wrote a burst of false "rejected" lines
and buried the real stale-runtime-id signal (#114694).

Look the live session up quietly; an id neither live nor stored still returns 4001.
This commit is contained in:
teknium1
2026-09-18 00:51:05 -07:00
committed by Teknium
parent 8b5e0ce0e8
commit 8c5b66b6a7
2 changed files with 15 additions and 2 deletions

View File

@@ -59,6 +59,16 @@ def test_set_hidden_unknown_id_still_errors(db):
assert envelope.get("error"), envelope
def test_set_hidden_stored_id_does_not_log_a_rejection(db, caplog):
"""The stored-id tier is this method's design, not a stale-runtime-id rejection: a fulfilled hide must
not emit the "session-scoped RPC rejected … not in memory" warning that diagnoses vanished messages."""
_seed(db, "stored-chat")
with caplog.at_level("WARNING", logger=srv.logger.name):
envelope = _call("session.set_hidden", {"session_id": "stored-chat", "hidden": True})
assert "error" not in envelope, envelope
assert not [r for r in caplog.records if "session-scoped RPC rejected" in r.getMessage()]
def test_session_list_include_hidden(db):
_seed(db, "plain-chat")
_seed(db, "bot-chat")

View File

@@ -1040,7 +1040,10 @@ def _(rid, params: dict) -> dict:
"""Set/clear ``hidden`` (leaves the default list, stays resumable by its owner) on a session + lineage:
LIVE runtime id first (unpersisted drafts via ``pending_hidden``), then a stored id/key in the profile db."""
hidden = is_truthy_value(params.get("hidden", True))
session, err = _sess_nowait(params, rid)
# Quiet live lookup: a stored id that is not in memory is this method's expected second tier, not a
# rejection — _sess_nowait would log "session-scoped RPC rejected … not in memory" for a request that is
# then fulfilled from the profile db, burying the real stale-runtime-id signal under sweep noise.
session = _sessions.get(str(params.get("session_id") or ""))
with (_profile_db(params, writer=True) if session is None else _session_db(session)) as db:
if db is None:
return _db_unavailable_error(rid, code=5007)
@@ -1053,7 +1056,7 @@ def _(rid, params: dict) -> dict:
# ``resolve_session_id`` follows key/title aliases like the REST pin/archive path.
target = _str_param(params, "session_id")
if not (key := db.resolve_session_id(target) if hasattr(db, "resolve_session_id") else target):
return err
return _err(rid, 4001, "session not found")
db.set_session_hidden(key, hidden)
return _ok(rid, {"hidden": hidden, "session_key": key})
except Exception as e: