fix(state): an adopted Bot Mode chat stays hidden after import
Stranded-session adoption copies a profile bot's chat from the default store through import_sessions, which dropped hidden. Bot Mode chats are hidden, and hidden is what makes the canonical Bot Chat canonical: the adopted copy showed in every session listing, lost the rename guard on its registry title and became a stale-archive candidate. hidden joins archived and pinned as a restored flag. (cherry picked from commit 1deb08a9cfd08845bc1de25cc502c3bcb51e8569)
This commit is contained in:
committed by
kshitij
parent
e00b87869c
commit
db6ffa8ea6
@@ -42,7 +42,7 @@ _IMPORT_SESSION_INSERT_SQL = """INSERT INTO sessions (
|
||||
cwd, git_branch, git_repo_root,
|
||||
billing_provider, billing_base_url, billing_mode,
|
||||
estimated_cost_usd, actual_cost_usd, cost_status, cost_source,
|
||||
pricing_version, title, api_call_count, archived, pinned
|
||||
pricing_version, title, api_call_count, archived, pinned, hidden
|
||||
)
|
||||
VALUES (
|
||||
:id, :source, :user_id, :model, :model_config,
|
||||
@@ -53,7 +53,7 @@ _IMPORT_SESSION_INSERT_SQL = """INSERT INTO sessions (
|
||||
:billing_provider, :billing_base_url, :billing_mode,
|
||||
:estimated_cost_usd, :actual_cost_usd, :cost_status,
|
||||
:cost_source, :pricing_version, :title,
|
||||
:api_call_count, :archived, :pinned
|
||||
:api_call_count, :archived, :pinned, :hidden
|
||||
)"""
|
||||
# Columns copied verbatim from the payload; typed columns are converted below.
|
||||
_IMPORT_PASSTHROUGH_COLS = (
|
||||
@@ -66,7 +66,9 @@ _IMPORT_INT_COLS = (
|
||||
_IMPORT_FLOAT_COLS = ("ended_at", "estimated_cost_usd", "actual_cost_usd")
|
||||
# Durable user decisions, not live runtime state: a restore that drops ``pinned`` hands the "keep"
|
||||
# session to the next startup prune and the stale-archive sweep, the two things the pin opts out of.
|
||||
_IMPORT_FLAG_COLS = ("archived", "pinned")
|
||||
# ``hidden`` is what makes an adopted Bot Mode chat canonical: without it the chat shows in every
|
||||
# listing, loses its rename guard and becomes a stale-archive candidate.
|
||||
_IMPORT_FLAG_COLS = ("archived", "pinned", "hidden")
|
||||
|
||||
|
||||
def _rich_select(select_cols: str, where: str, tail: str = "", prompt_select: Optional[str] = "") -> str:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"""A restored or adopted session keeps the user's durable flags.
|
||||
|
||||
``import_sessions`` (the dashboard import of a ``hermes sessions export`` backup, and stranded-session
|
||||
adoption) restored ``archived`` but not ``pinned``. Pinned is the "keep" flag the startup prune and the
|
||||
stale-archive sweep both exempt, so an old pinned session came back unpinned and the next startup
|
||||
deleted it.
|
||||
adoption) restored ``archived`` but not ``pinned`` or ``hidden``. Pinned is the "keep" flag the startup
|
||||
prune and the stale-archive sweep both exempt, so an old pinned session came back unpinned and the next
|
||||
startup deleted it; an adopted Bot Mode chat came back visible and no longer canonical.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -39,3 +39,24 @@ def test_restored_pinned_session_survives_the_startup_prune(tmp_path):
|
||||
finally:
|
||||
source.close()
|
||||
target.close()
|
||||
|
||||
|
||||
def test_adopted_bot_chat_stays_the_hidden_canonical_chat(tmp_path):
|
||||
"""Stranded-session adoption imports the donor's Bot Mode chat into the profile store; Bot Mode
|
||||
chats are hidden, and hidden is what keeps the canonical one out of listings and the stale sweep."""
|
||||
donor = SessionDB(db_path=tmp_path / "default.db")
|
||||
profile = SessionDB(db_path=tmp_path / "profile.db")
|
||||
try:
|
||||
donor.create_session(SESSION_ID, source="tui")
|
||||
donor.set_session_title(SESSION_ID, SessionDB.CANONICAL_BOT_CHAT_TITLE)
|
||||
donor.set_session_hidden(SESSION_ID, True)
|
||||
donor.append_message(SESSION_ID, "user", "hi bot")
|
||||
|
||||
assert profile.adopt_session_lineage_from(donor, SESSION_ID)["adopted"]
|
||||
|
||||
assert profile.get_session(SESSION_ID)["hidden"]
|
||||
assert SESSION_ID not in {s["id"] for s in profile.list_sessions_rich(limit=50)}
|
||||
assert profile.archive_stale_sessions(idle_days=0) == 0
|
||||
finally:
|
||||
donor.close()
|
||||
profile.close()
|
||||
|
||||
Reference in New Issue
Block a user