Skip to content

fix: emit terminal Done when the model stream ends without a done marker#212

Merged
quiet-node merged 1 commit into
mainfrom
fix/stream-terminal-on-abnormal-end
Jun 9, 2026
Merged

fix: emit terminal Done when the model stream ends without a done marker#212
quiet-node merged 1 commit into
mainfrom
fix/stream-terminal-on-abnormal-end

Conversation

@quiet-node

Copy link
Copy Markdown
Owner

Overview

Chat (and the in-place transforms like /rewrite) could hang with the spinner stuck forever when the local model's stream ended without Ollama's terminal done:true line. This happens when a small model degenerates on pathological input (for example, trying to reproduce a long, mostly-zero hex address verbatim) and the runner closes the connection without sending its usual final marker.

Root cause

stream_ollama_chat emitted the terminal Done chunk only when it observed done:true. When the stream ended any other way (the connection closing mid-generation, or an empty response body), the loop returned without emitting any terminal chunk. The frontend clears its streaming state only on a terminal event, so it spun forever.

How it works

The stream loop now tracks whether a terminal Done was already emitted and emits one when the stream ends without a done:true line. The frontend finalizes the turn on Done, so the spinner stops and any partial content is kept. Normal completion is unchanged: the done:true path still emits exactly one Done, with no duplicate on stream end.

Testing

  • New test: a stream that ends without done:true still produces exactly one terminal Done.
  • Updated the empty-body test, which previously asserted no terminal event at all (the same latent hang); it now expects a single Done.
  • bun run test:all:coverage and bun run validate-build both pass; backend stays at 100% line coverage.

Note: this fixes the hang only. For inputs a small model cannot reproduce verbatim (long hex strings or IDs), the rewritten text may still be truncated or imperfect; that output-quality issue is a model limitation tracked separately and is best addressed by masking verbatim zones before generation.

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
@quiet-node quiet-node merged commit df09b2a into main Jun 9, 2026
3 checks passed
@quiet-node quiet-node deleted the fix/stream-terminal-on-abnormal-end branch June 9, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant