fix(api): order session records by producer time so turns stop interleaving#5494
fix(api): order session records by producer time so turns stop interleaving#5494mmabrouk wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…eaving `get_records` ordered by (created_at, record_index). `record_index` restarts at 0 on every turn, and the ingest worker batches records from adjacent turns into one write, so those rows share a `created_at`. The tiebreak then sorted the NEXT turn's first record ahead of the PREVIOUS turn's later ones, and a conversation rebuilt from the log came back interleaved: a live three-turn run reconstructed as user, user, assistant, user with the replies in the wrong places. Order by the producer-stamped `timestamp` first. It is the only key monotonic across turns, and the runner already sets it on every record. Ingest time and the per-turn index stay as tiebreaks, and rows predating `timestamp` sort last within their batch rather than jumping the queue. Claude-Session: https://claude.ai/code/session_01KM69J7uHafgciiN5zfG7qR
8f19a97 to
f621400
Compare
293785a to
d4501e0
Compare
The problem
A conversation rebuilt from the record log came back with its turns interleaved. A three-turn run reconstructed as
user, user, assistant, user: the reply to the first question landed after the second question.get_recordsordered by(created_at, record_index). Two facts make that wrong:record_indexrestarts at 0 on every turn, so it only orders records within a turn.created_at.When both happen together the tiebreak sorts the next turn's first record ahead of the previous turn's later ones. Straight from the table, with turn 2's user record jumping ahead of turn 1's agent record:
Same
created_at, sorecord_index0 wins over 3, and turn 2's question sorts before turn 1's answer.This ordering predates the last-message-only work. It did not matter while records fed a viewer. It matters now that the model's context is rebuilt from them.
The fix
Order by the producer-stamped
timestampfirst. The runner already sets it on every record, and unlike the per-turn index it is monotonic across turns. Ingest time and the per-turn index stay as tiebreaks, and rows written beforetimestampexisted sort last within their batch rather than jumping the queue.Testing
Verified against the live table for a three-turn conversation: ordering by producer time reproduces the true conversation order, where the previous ordering did not. Found during the differential QA on #5486.
Known follow-up
This fixes the ordering. It also surfaced a separate issue that is not fixed here: the worker writes a turn's records to Postgres after the next turn has already read them, so the immediately preceding turn's reply can still be missing at reconstruction time. That is a read-after-write question about the ingest pipeline, and it needs its own decision.