fix: exclude archived keys in heartbeat & fallback missing session timestamps

This commit is contained in:
Heng Wei Bin
2026-06-24 15:45:49 +08:00
committed by Xubin Ren
parent 9c6eaf0bed
commit de4009efbd
4 changed files with 57 additions and 4 deletions
+7
View File
@@ -1065,8 +1065,15 @@ def _run_gateway(
def _pick_heartbeat_target() -> tuple[str, str]:
"""Pick a routable channel/chat target for heartbeat-triggered messages."""
enabled = set(channels.enabled_channels)
from nanobot.webui.sidebar_state import read_webui_sidebar_state
sidebar_state = read_webui_sidebar_state()
archived_keys = set(sidebar_state.get("archived_keys", []))
for item in session_manager.list_sessions():
key = item.get("key") or ""
if key in archived_keys:
continue
if ":" not in key:
continue
channel, chat_id = key.split(":", 1)
+4 -2
View File
@@ -843,11 +843,13 @@ class SessionManager:
if not fallback_preview and item.get("role") == "assistant":
fallback_preview = text
preview = preview or fallback_preview
from datetime import datetime
fallback_time = datetime.fromtimestamp(path.stat().st_mtime).isoformat()
sessions.append(
{
"key": key,
"created_at": data.get("created_at"),
"updated_at": data.get("updated_at"),
"created_at": data.get("created_at") or fallback_time,
"updated_at": data.get("updated_at") or fallback_time,
"title": title,
"preview": preview,
"path": str(path),
+9 -2
View File
@@ -269,13 +269,20 @@ def _scan_session_row(session_manager: SessionManager, path: Path) -> dict[str,
if not fallback_preview and item.get("role") == "assistant":
fallback_preview = text
signature = _file_signature(path)
created_at_s = data.get("created_at")
updated_at_s = data.get("updated_at")
if not created_at_s or not updated_at_s:
from datetime import datetime
fallback_time = datetime.fromtimestamp(signature["mtime_ns"] / 1e9).isoformat()
created_at_s = created_at_s or fallback_time
updated_at_s = updated_at_s or fallback_time
key = data.get("key") or fallback_key
activity_signature = _webui_activity_signature(key)
activity_updated_at = _webui_activity_updated_at(activity_signature)
return {
"key": key,
"created_at": data.get("created_at"),
"updated_at": _latest_updated_at(data.get("updated_at"), activity_updated_at),
"created_at": created_at_s,
"updated_at": _latest_updated_at(updated_at_s, activity_updated_at),
"title": _metadata_title(data.get("metadata", {})),
"preview": preview or fallback_preview,
"file": path.name,
+37
View File
@@ -171,3 +171,40 @@ def test_webui_session_list_rescans_when_transcript_changes(
def list_webui_sessions(manager: SessionManager) -> list[dict]:
return session_list_index.list_webui_sessions(manager)
def test_webui_session_list_fallback_time_when_missing(tmp_path: Path) -> None:
manager = SessionManager(tmp_path)
path = manager._get_session_path("websocket:missing-time")
path.write_text(
'{"_type": "metadata", "key": "websocket:missing-time"}\n'
'{"_type": "message", "role": "user", "content": "hello"}\n',
encoding="utf-8",
)
rows = list_webui_sessions(manager)
assert len(rows) == 1
assert rows[0]["key"] == "websocket:missing-time"
assert rows[0]["created_at"] is not None
assert rows[0]["updated_at"] is not None
datetime.fromisoformat(rows[0]["created_at"])
datetime.fromisoformat(rows[0]["updated_at"])
def test_session_manager_list_sessions_fallback_time_when_missing(tmp_path: Path) -> None:
manager = SessionManager(tmp_path)
path = manager._get_session_path("websocket:missing-time2")
path.write_text(
'{"_type": "metadata", "key": "websocket:missing-time2"}\n'
'{"_type": "message", "role": "user", "content": "hello"}\n',
encoding="utf-8",
)
sessions = manager.list_sessions()
assert len(sessions) == 1
assert sessions[0]["key"] == "websocket:missing-time2"
assert sessions[0]["created_at"] is not None
assert sessions[0]["updated_at"] is not None
datetime.fromisoformat(sessions[0]["created_at"])
datetime.fromisoformat(sessions[0]["updated_at"])