Fix sidebar reconciliation review issues

This commit is contained in:
Frank Song authored and nesquena-hermes committed 2026-06-26 00:36:15 +00:00
1 parent 0e2214b6bd
commit fda5a241b2
3 files changed
+56 -6

No files matched your search

+9 -4
View File
@@ -3425,12 +3425,17 @@ def _apply_sidebar_state_db_override_metadata(sessions: list[dict], metadata: di
state_last = float(state_db_last_message_at or 0)
except (TypeError, ValueError):
state_last = 0.0
# ``current_last`` intentionally includes ``updated_at``: if a
# sidecar metadata-only write happened after the state.db append,
# keep the conservative anti-resurrection guard and wait for a
# newer settled state.db message before overlaying counts again.
if state_count > current_count and (state_last <= 0 or state_last > current_last):
try:
existing_actual = max(0, int(session.get('actual_message_count') or 0))
except (TypeError, ValueError):
existing_actual = 0
session['message_count'] = state_count
session['actual_message_count'] = max(
state_count,
int(session.get('actual_message_count') or 0) if str(session.get('actual_message_count') or '').isdigit() else 0,
)
session['actual_message_count'] = max(state_count, existing_actual)
if state_last > 0:
session['last_message_at'] = max(float(session.get('last_message_at') or 0), state_last)
session['updated_at'] = max(float(session.get('updated_at') or 0), state_last)
+17 -2
View File
@@ -1,10 +1,23 @@
import threading
from types import SimpleNamespace
import pytest
import api.routes as routes
from api import session_events
@pytest.fixture(autouse=True)
def _isolated_session_list_cache_state():
routes._session_list_cache_clear()
with routes._SESSIONS_CACHE_LOCK:
routes._SESSIONS_CACHE_INFLIGHT.clear()
yield
routes._session_list_cache_clear()
with routes._SESSIONS_CACHE_LOCK:
routes._SESSIONS_CACHE_INFLIGHT.clear()
class _StageRecorder:
def __init__(self):
self.stages = []
@@ -74,8 +87,9 @@ def test_session_list_cache_key_separates_profile_and_all_profiles():
assert calls == ["default", "other", "default_all"]
def test_session_list_cache_singleflight_rebuild_once():
def test_session_list_cache_singleflight_rebuild_once(monkeypatch):
routes._session_list_cache_clear()
monkeypatch.setattr(routes, "_session_list_cache_source_stamp", lambda _key: ("stable",))
started = threading.Event()
release = threading.Event()
@@ -121,8 +135,9 @@ def test_session_list_cache_singleflight_rebuild_once():
assert calls == 1
def test_session_list_cache_follower_wait_stage_when_rebuild_inflight():
def test_session_list_cache_follower_wait_stage_when_rebuild_inflight(monkeypatch):
routes._session_list_cache_clear()
monkeypatch.setattr(routes, "_session_list_cache_source_stamp", lambda _key: ("stable",))
started = threading.Event()
release = threading.Event()
@@ -125,6 +125,36 @@ def _install_test_session(monkeypatch, tmp_path, sid, sidecar_messages):
return session
def test_sidebar_state_db_overlay_preserves_numeric_actual_count():
import api.models as models
sid = "webui_float_actual_count"
sessions = [
{
"session_id": sid,
"source_tag": "webui",
"message_count": 2,
"actual_message_count": 5.0,
"last_message_at": 1001.0,
"updated_at": 1001.0,
}
]
models._apply_sidebar_state_db_override_metadata(
sessions,
{
sid: {
"_state_db_source": "webui",
"_state_db_message_count": 4,
"_state_db_last_message_at": 1003.0,
}
},
)
assert sessions[0]["message_count"] == 4
assert sessions[0]["actual_message_count"] == 5
def test_tail_cancelled_partial_blocks_state_db_replay():
from api.models import merge_session_messages_append_only