After a reply finishes, the bubbles are no longer in the order they were sent.
Screenshots from the joke thread:
While the reply is generating, order is correct: "Tell me a joke", the joke, "I don't know", then the working status.
When the reply lands, order becomes: "I don't know", "Tell me a joke", the new answer, then the original joke. The action row sits on the joke, so the joke is treated as the last turn.
Same chat also fails to use the previous turn (backend). This ticket is the display order.
Why
GET conversation_details does not order prompts. The post-stream refetch (about 800ms after END) replaces the optimistic list with that unordered payload.
On START_OF_THE_STREAM, MessageContext copies conversationDetails from the websocket subscription closure into conversationRef. That closure can be the list from before the optimistic user turn. END then pops and appends on the short list.
Bubble keys are id || index. An optimistic row with no id can collide with a real id.
Fix
Sort turns oldest-first by created, then id, whenever the thread is written into state.
Keep conversationRef aligned with that state. Do not replace it from the websocket closure on START.
Give each optimistic turn a stable local key.
Backend prompt ordering is the matching chat_backend ticket.
## What happens
After a reply finishes, the bubbles are no longer in the order they were sent.
Screenshots from the joke thread:
- While the reply is generating, order is correct: "Tell me a joke", the joke, "I don't know", then the working status.
- When the reply lands, order becomes: "I don't know", "Tell me a joke", the new answer, then the original joke. The action row sits on the joke, so the joke is treated as the last turn.
Same chat also fails to use the previous turn (backend). This ticket is the display order.
## Why
- `GET conversation_details` does not order prompts. The post-stream refetch (about 800ms after END) replaces the optimistic list with that unordered payload.
- On `START_OF_THE_STREAM`, `MessageContext` copies `conversationDetails` from the websocket subscription closure into `conversationRef`. That closure can be the list from before the optimistic user turn. `END` then pops and appends on the short list.
- Bubble keys are `id || index`. An optimistic row with no id can collide with a real id.
## Fix
- Sort turns oldest-first by `created`, then id, whenever the thread is written into state.
- Keep `conversationRef` aligned with that state. Do not replace it from the websocket closure on START.
- Give each optimistic turn a stable local key.
Backend prompt ordering is the matching `chat_backend` ticket.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What happens
After a reply finishes, the bubbles are no longer in the order they were sent.
Screenshots from the joke thread:
Same chat also fails to use the previous turn (backend). This ticket is the display order.
Why
GET conversation_detailsdoes not order prompts. The post-stream refetch (about 800ms after END) replaces the optimistic list with that unordered payload.START_OF_THE_STREAM,MessageContextcopiesconversationDetailsfrom the websocket subscription closure intoconversationRef. That closure can be the list from before the optimistic user turn.ENDthen pops and appends on the short list.id || index. An optimistic row with no id can collide with a real id.Fix
created, then id, whenever the thread is written into state.conversationRefaligned with that state. Do not replace it from the websocket closure on START.Backend prompt ordering is the matching
chat_backendticket.Same-chat history and prompt ordering are chat_backend#84.