Repository navigation
fix(openai,openrouter,huggingface): keep streamed tool calls apart when the provider omits index - #2641
Merged
Luca Forstner (lforst) merged 3 commits intoOct 20, 2026
Conversation
…ndex aggregateChatCompletionChunks keyed streamed tool calls by delta.index. Some OpenAI-compatible providers send tool call deltas without an index, so every call landed under the key `undefined`: the second call overwrote the id of the first and the arguments of all calls were concatenated. Resolve a missing index from the latest call: a delta with an id that differs from the latest call's id starts the next call, a delta without an id continues it. Deltas that carry an index behave as before. Tests cover id-less continuation fragments and several unindexed calls in one chunk; both failed before the change. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ndex Same shape as the OpenAI plugin fix. Both aggregators fell back to slot 0 when a tool call delta had no index: OpenRouter replaced slot 0 when a new id arrived (losing the first call), Hugging Face kept the first call's id and name and concatenated the arguments of every call. A missing index is now resolved from the latest call: a delta with an id that differs from the latest id starts the next call, a delta without an id continues it. Deltas with an index behave as before. Tests for both aggregators failed before the change. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Luca Forstner (lforst)
approved these changes
Oct 20, 2026
Member
|
released with https://github.com/braintrustdata/braintrust-sdk-javascript/releases/tag/braintrust%403.39.0 - thanks for the PR alexcastgonz (@pcbeingused333) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The chat stream aggregators of the OpenAI, OpenRouter and Hugging Face plugins group streamed tool call deltas by
delta.index. Some providers (Gemini's OpenAI-compatible endpoint, for example) send each parallel call whole in its own chunk and leaveindexunset. Without an index the calls end up in one slot (the OpenAI aggregator keys them underundefined; OpenRouter and Hugging Face fall back to slot 0): a new id overwrites or replaces the previous call and the arguments are concatenated, so the logged output shows one broken call instead of several.Change
When
indexis missing, it is resolved from the latest call: a delta with an id that differs from the latest call's id starts the next call, and a delta without an id continues the latest one (so argument fragments still merge). Deltas that carry an index behave exactly as before. The same rule is applied in the three aggregators. Adds a patch changeset.Tests
Two new cases in
openai-plugin.test.ts(id-less continuation fragments followed by a second call, and several calls without index in one chunk) plus one case each inopenrouter-plugin.test.tsandhuggingface-plugin.test.ts. All four fail on main (the OpenAI chunk case losescall_1entirely) and pass with the change; the other tests in those three files still pass (102 in total).prettier --checkandtsc --noEmitare clean. These are unit tests of the aggregation functions, so they need no recorded API calls.This PR was made with Claude Code (Anthropic); the tests above were run on main and on this branch.