65bb16c8ce
When a streaming response ends cleanly (HTTP 200) with no finish_reason after delivering text but no tool calls, the chunk collector silently stamps finish_reason='stop' and the conversation loop presents truncated text as a complete response. Three stream-drop paths now exist after chunk collection: 1. Zero-chunk → EmptyStreamError, retried (existing) 2. Tool-call in progress, no finish_reason → partial-stream-stub (existing) 3. Text-only, no finish_reason → partial-stream-stub (NEW — this fix) Path 3 routes through the same PARTIAL_STREAM_STUB_ID + FINISH_REASON_LENGTH machinery as path 2. The conversation loop shows 'Stream interrupted — requesting continuation' and injects a continue prompt, giving the model a chance to resume where the stream dropped. Observed with DeepSeek provider where CloudFront drops SSE streams mid-response after delivering partial text.