Watch
1
0
Fork
You've already forked souveraine
0

fix: preserve the full reply (not the streamed partial) on surface-drop

Revises the prior fix: the model's reply is already complete in
final_content before the paced stream loop, so truncating to
needlessly dropped the unstreamed tail. On SSE receiver-drop, stop
streaming but commit the FULL reply (interrupt flag skips the pointless
N+1 and marks the turn); the surface recovers the whole reply on resume.
This commit is contained in:
Fimeg 2026-07-30 15:22:12 -04:00
commit 4caca36859

View file

@ -473,17 +473,21 @@ pub(crate) async fn run_turn(
send_res = tx.send(Ok(BackendEvent::Token(s.clone()))) => { send_res = tx.send(Ok(BackendEvent::Token(s.clone()))) => {
if send_res.is_err() { if send_res.is_err() {
// The SSE receiver is gone (the surface // The SSE receiver is gone (the surface
// disconnected mid-reply). Do NOT return early: // disconnected mid-stream). The model's reply is
// that would skip the session commit below and // already complete in `final_content` — only the
// orphan this turn, leaving a user→user gap so // paced live-stream was cut, so do NOT truncate
// the next turn cannot link to the past — the // to `streamed`. Stop streaming to the dead
// model reads the follow-up with no preceding // receiver and let the turn commit the FULL
// reply and answers as if from nowhere. Commit // reply below; treating it as an interrupt also
// the partial text like an interrupt instead, so // skips the now-pointless N+1 pass and lands a
// the conversation thread stays intact even when // small marker so the next turn knows the live
// the surface vanishes. // tail was missed. Returning early here used to
// orphan the turn entirely — no commit — leaving
// a user→user gap so the next turn could not link
// to the past, and the model answered as if from
// nowhere ("whatever it was…"). The surface
// recovers the whole reply on its next resume.
interrupted = true; interrupted = true;
final_content = streamed;
break; break;
} }
dispatcher.emit_segment(&s); dispatcher.emit_segment(&s);