fix: avoid double-counting logprobs in streamed chat completions (#2444)
- [x] I understand that this repository is auto-generated and my pull
request may not be merged
## Changes being requested
`#accumulateChatCompletion` seeds a new choice with the chunk's
`logprobs` by reference, so on that same iteration `choice.logprobs ===
logprobs` and `choice.logprobs.content.push(...content)` pushes the
array into itself. One streamed token arrives as two entries in
`finalChatCompletion().choices[0].logprobs.content` and in the
`logprobs.content.done` payload.
The initialise branch then does `choice.logprobs = { ...logprobs }`, one
level deep, so the snapshot keeps the caller's array and the next
chunk's `push` appends into the chunk the caller passed in.
Current tests miss both: the fixture's first logprobs-bearing chunk is
`{"content":[],"refusal":null}`, so `push(...[])` is a no-op, and
nothing streams two chunks that each carry logprobs.
Fix: seed `logprobs: null`, and copy the arrays when initialising.
## Additional context & links
- Three added tests cover the content path, the refusal path and
cross-chunk accumulation; all three fail on `main`.
- `npx vitest run --config vitest.config.mts
tests/lib/ChatCompletionStream.test.ts` -> 38 passed. `oxlint` and
`oxfmt --check` pass.
Co-authored-by: Hayden <hayden@openai.com> D
dfedoryshchev committed
ddf99223c43f7f42851c8a155120da10572f4bfb
Parent: 1cae4cb
Committed by GitHub <noreply@github.com>
on 8/25/2026, 5:29:41 PM