Found while writing end-to-end coverage for LibreChat-AI#16615. The behavior reproduces on canary (Recoil queue atoms) and with LibreChat-AI#16615 (Jotai queue atoms) alike, so it predates that change.
Steps (mock harness): in an existing conversation, start a slow run, queue a follow-up with Cmd/Ctrl+Enter, navigate in-app to a new chat, wait until the server has finished the run, then go back to the conversation.
Expected, per the useQueueDrain contract ("Park the signal under ITS conversation ... and drain when the user returns"): the queued follow-up sends as the next turn.
Actual: the finished reply loads from history, but the follow-up stays in the queue rail until the user sends it by hand. Navigating away detaches the pane's stream, so no terminal event writes runEndByIndex and nothing is parked under pendingRunEndByConvoId; the resume-on-load path that reloads the finished run does not publish a run end either.
The unit specs cover parking when the terminal event does arrive while another conversation is active (useQueueDrain.spec: "parks a mismatched signal", "drains a parked signal when the user returns"). The missing piece is a run end for a run that finished while its stream was detached. A scenario for this was drafted as parked-run-end-drains-on-return and dropped from LibreChat-AI#16615 because canary does not meet it.
Found while writing end-to-end coverage for LibreChat-AI#16615. The behavior reproduces on canary (Recoil queue atoms) and with LibreChat-AI#16615 (Jotai queue atoms) alike, so it predates that change.
Steps (mock harness): in an existing conversation, start a slow run, queue a follow-up with Cmd/Ctrl+Enter, navigate in-app to a new chat, wait until the server has finished the run, then go back to the conversation.
Expected, per the
useQueueDraincontract ("Park the signal under ITS conversation ... and drain when the user returns"): the queued follow-up sends as the next turn.Actual: the finished reply loads from history, but the follow-up stays in the queue rail until the user sends it by hand. Navigating away detaches the pane's stream, so no terminal event writes
runEndByIndexand nothing is parked underpendingRunEndByConvoId; the resume-on-load path that reloads the finished run does not publish a run end either.The unit specs cover parking when the terminal event does arrive while another conversation is active (
useQueueDrain.spec: "parks a mismatched signal", "drains a parked signal when the user returns"). The missing piece is a run end for a run that finished while its stream was detached. A scenario for this was drafted asparked-run-end-drains-on-returnand dropped from LibreChat-AI#16615 because canary does not meet it.