You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
chore(chat): backfill assistant turns into sessions damaged before #13214 #13293
#13214 (PR #13291) fixes the code path: streamed assistant replies are now persisted to the GUI-facing store. It does not repair sessions damaged before the fix.
This carries forward item 4 of #13214, which would otherwise be lost when that issue closes.
Scope
Every conversation held before the fix landed reads back as a monologue of user turns in the GUI. The replies are not lost — the workflow store still holds them:
damaged store: chat:session:<id> (chat_history/session.py:84) — user turns only
intact store: chat:conversation:<id> (chat_workflow/conversation.py:33) — {user, assistant} pairs per turn
Suggested work
A one-shot repair that, for each affected session, walks the chat:conversation:* turns and inserts the missing assistant turns into the chat-history session in order, matched to their user turn.
Requirements:
idempotent — re-running must not duplicate turns (dedupe on sender + normalized text, matching _get_message_signature in api/chat.py:201)
never drops or rewrites existing entries (no data loss on repair)
writes through add_messages_batch / save_session, not raw Redis
dry-run mode reporting counts before writing
Note the two stores use different message shapes (text/messageType from _build_message_dict vs content/type from _to_persisted_message); the repair must emit the shape the session store already uses.
Acceptance: a session known to be damaged reads back with its assistant turns after the repair, and a second run is a no-op.
A backfilled turn cannot match that shape. compute_backfilled_messages only fires when a turn window has zero assistant entries, and its source (chat:conversation:* pairs, or the durable transcript file) carries one combined assistant string per exchange with no per-iteration breakdown to interleave. So a repaired turn reads user, system(tool output), assistant(combined) — the pre-#13295 shape.
The insertion point (turn_end) is unaffected and needs no change; review confirmed this independently. The inconsistency is unavoidable given the source data, and is recorded here rather than left silent.
This issue still cannot close: the module has never been run against real damaged sessions with before/after evidence, which is the operator step.
Activity
fix(chat): address review blockers on #13303 - revert bad ordering fi…
fix(chat): reload fidelity for streamed replies — model/sources, turn…
mrveiss commentedon Aug 3, 2026
Ordering note from PR #13334 (merged as
53d455ea6), so a repaired turn is never later misread as evidence that fix regressed.#13295 changed freshly-persisted turns to interleave per-iteration:
user, assistant(prose1), system(tool output), assistant(prose2).A backfilled turn cannot match that shape.
compute_backfilled_messagesonly fires when a turn window has zero assistant entries, and its source (chat:conversation:*pairs, or the durable transcript file) carries one combined assistant string per exchange with no per-iteration breakdown to interleave. So a repaired turn readsuser, system(tool output), assistant(combined)— the pre-#13295 shape.The insertion point (
turn_end) is unaffected and needs no change; review confirmed this independently. The inconsistency is unavoidable given the source data, and is recorded here rather than left silent.This issue still cannot close: the module has never been run against real damaged sessions with before/after evidence, which is the operator step.