createSSEStream splits on "\n" and keeps the remainder, which only flush() parses. That call omitted targetFormat, so parseSSELine required a "data: " prefix and dropped whatever an NDJSON provider left without a closing newline. The !parsed.done guard compounded it: the SSE sentinel and an Ollama final chunk both carry done:true, but the latter is the real last chunk holding done_reason and the token counts. Pass targetFormat and scope the sentinel check to formats that emit one, so the tail reaches the translator. Accumulate its usage into state the same way the transform loop does, so finalizeStream logs those tokens instead of null.
3.6 KiB
3.6 KiB