Queue messages to a busy bot and send them when it settles (#220)
A message sent mid-turn used to bounce with a 409 and a 'try again later'. Now it lands in the transcript immediately — persisted, marked queued — and auto-sends when the bot settles: every queued message for the thread drains into ONE follow-up turn (texts joined), so a burst of steering notes costs one turn. Stop-then-steer is deliberate: an interrupted turn drains too, because these are the user's own words, not a bot's fan-out. The queue itself is memory-only on purpose — each queued message is already an ordinary persisted thread message, so a restart loses only the auto-send intent, never the words, and the client shows the queued affordance only while the bot is busy so a stranded flag is invisible rather than a false promise. Drained turns are plain attended turns: no automationSource, no unattended marking, no comms depth — exactly what typing the same words into an idle bot would run. Drain triggers on turn.completed and on the two settle paths that never emit it (dispatch failure, provider reload). 1:1 chats only; rooms keep their existing client-side hold-one behavior. branching.test.ts's 'second send while busy is 409' assertion encoded the old contract; it now asserts 202 + queued + still exactly one live turn, and stops the drained turn before the edit-fork half of the test. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
M
Milind Soni committed
0024d14ccdd9f970cebd95e50fcf4646b6897450
Parent: d129960
Committed by GitHub <noreply@github.com>
on 8/18/2026, 5:09:40 AM