fix(ui): prevent UI from dropping partial chunks during stream tail parsing

Added a catch-all parsing step at the very end of the streaming loop, and within the flushed chunk loop, so any straggler text that wasn't accompanied by a finish_reason chunk or was buffered in streamDecoder.flush() is properly parsed into visible content before the DB insert.
This commit is contained in:
Evandro Fonseca Junior committed 2026-04-04 02:31:40 -03:00
1 parent e2cc7e1c26
commit c6df5d350f
1 file changed
+13
+13
View File
@@ -478,6 +478,7 @@ interface Props {
try {
const chunk = JSON.parse(data);
const delta = chunk.choices?.[0]?.delta?.content;
const finishReason = chunk.choices?.[0]?.finish_reason;
if (typeof delta === "string") {
const sanitizedDelta = sanitizeMessageText(delta);
tokenCount++;
@@ -485,12 +486,24 @@ interface Props {
fullContent += sanitizedDelta.text;
streamContentAccRef.current = fullContent;
}
if (finishReason) {
const parsed = parseAssistantResponse(fullContent);
setStreamContent(parsed.content);
setStreamReasoning(parsed.reasoning);
setStreamThinkingOpen(parsed.thinkingOpen);
}
if (chunk.usage) usage = chunk.usage;
} catch (chunkErr) {
devLog.logStreamChunk(line, null, null, `Parse error: ${chunkErr}`);
}
}
}
// Final safety parsing step to ensure UI states match DB right before saving
const parsed = parseAssistantResponse(fullContent);
setStreamContent(parsed.content);
setStreamReasoning(parsed.reasoning);
setStreamThinkingOpen(parsed.thinkingOpen);
} else {
const data = await res.json();
const rawNonStream = data.choices?.[0]?.message?.content || "";