diff --git a/src/server/turn.rs b/src/server/turn.rs index e88b45c..ab67bf8 100644 --- a/src/server/turn.rs +++ b/src/server/turn.rs @@ -471,7 +471,21 @@ pub(crate) async fn run_turn( break; } send_res = tx.send(Ok(BackendEvent::Token(s.clone()))) => { - if send_res.is_err() { return Ok(()); } + if send_res.is_err() { + // The SSE receiver is gone (the surface + // disconnected mid-reply). Do NOT return early: + // that would skip the session commit below and + // orphan this turn, leaving a user→user gap so + // the next turn cannot link to the past — the + // model reads the follow-up with no preceding + // reply and answers as if from nowhere. Commit + // the partial text like an interrupt instead, so + // the conversation thread stays intact even when + // the surface vanishes. + interrupted = true; + final_content = streamed; + break; + } dispatcher.emit_segment(&s); streamed.push_str(&s); }