mirror of
https://github.com/turnstonelabs/turnstone.git
synced 2026-08-12 23:12:23 -06:00
fix(sse): coerce non-int ui._event_id to None when stamping saves
When the active UI is a MagicMock test double, _ui_event_id() returned
the auto-vivified _event_id mock (getattr finds it, so the None default
never applies). That mock reached the conversations INSERT and failed
to bind ("type 'MagicMock' is not supported"), so save_message raised,
the row was dropped, and tests on the real-storage + mock-UI path broke
(CI: test_session_attachments::test_db_row_stores_text_only).
Coerce a non-int _event_id to None so mock UIs -- and counterless
CLI/eval/placeholder UIs -- stamp NULL (the synthetic-snapshot floor),
matching the documented contract. Production UIs always carry an int,
so behaviour there is unchanged.
Also drop two redundant local `import json` in the new /history
integration tests; the module-level import already covers them.
This commit is contained in:
@@ -1304,8 +1304,6 @@ class TestHistoryInteractive:
|
||||
``cursor`` = the resolved boundary's event_id. The client opens
|
||||
its initial SSE with that cursor so the delta rebuilds the turn.
|
||||
"""
|
||||
import json
|
||||
|
||||
ws_id = "ws-cursor"
|
||||
_inject_storage.register_workstream(ws_id, kind="interactive", user_id="test-user")
|
||||
_inject_storage.save_message(ws_id, "user", "kick off", event_id=10)
|
||||
@@ -1340,8 +1338,6 @@ class TestHistoryInteractive:
|
||||
rendered block) and returns ``cursor: null`` — the client connects
|
||||
fresh to the synthetic-snapshot floor, never leaving the turn
|
||||
unrenderable."""
|
||||
import json
|
||||
|
||||
ws_id = "ws-cursor-reload"
|
||||
_inject_storage.register_workstream(ws_id, kind="interactive", user_id="test-user")
|
||||
_inject_storage.save_message(ws_id, "user", "kick off", event_id=10)
|
||||
|
||||
@@ -2134,12 +2134,15 @@ class ChatSession:
|
||||
"""Current per-ws SSE ring-buffer high-water mark for stamping
|
||||
saved messages with the ``Last-Event-ID`` resume cursor.
|
||||
|
||||
Returns ``getattr(self.ui, "_event_id", None)`` — ``None`` for
|
||||
UIs without the counter (CLI / eval / placeholder), whose rows
|
||||
then stay NULL and are treated by ``/history`` as "no
|
||||
fast-forward cursor available" (the synthetic-snapshot floor).
|
||||
``None`` for UIs without an integer counter — CLI / eval /
|
||||
placeholder UIs (no ``_event_id``), and test doubles whose
|
||||
``self.ui`` is a ``MagicMock`` (a non-int ``_event_id`` would
|
||||
otherwise reach the INSERT and fail to bind). Those rows stay
|
||||
NULL and are treated by ``/history`` as "no fast-forward cursor
|
||||
available" (the synthetic-snapshot floor).
|
||||
"""
|
||||
return getattr(self.ui, "_event_id", None)
|
||||
eid = getattr(self.ui, "_event_id", None)
|
||||
return eid if isinstance(eid, int) else None
|
||||
|
||||
def _remaining_token_budget(self) -> int:
|
||||
"""Estimate how many tokens are available for new content.
|
||||
|
||||
Reference in New Issue
Block a user