Skip to content

Merge duplicate indexed tool call deltas#3234

Open
parsa-faraji wants to merge 2 commits into
openai:mainfrom
parsa-faraji:fix-duplicate-tool-call-deltas
Open

Merge duplicate indexed tool call deltas#3234
parsa-faraji wants to merge 2 commits into
openai:mainfrom
parsa-faraji:fix-duplicate-tool-call-deltas

Conversation

@parsa-faraji
Copy link
Copy Markdown

Fixes #3203.

This updates the streaming delta accumulators to route initial list values through the same index-aware merge path used for later chunks. That prevents duplicate tool_calls entries with the same index in the first chunk from being stored as separate list entries.

The chat completion initial snapshot path now also normalizes choice.delta through accumulate_delta, so the first streamed chunk gets the same merge behavior as subsequent chunks.

Tests added:

  • duplicate indexed list entries with both missing and None accumulator values
  • primitive list deltas with both missing and None accumulator values
  • chat stream state first-chunk duplicate tool call regression

Verification:

  • uv run --with pytest --with pytest-asyncio python -m pytest -o addopts='' tests/lib/test_streaming_deltas.py
  • uv run --with ruff ruff check src/openai/lib/streaming/_deltas.py src/openai/lib/streaming/_assistants.py src/openai/lib/streaming/chat/_completions.py tests/lib/test_streaming_deltas.py

@parsa-faraji parsa-faraji requested a review from a team as a code owner May 13, 2026 06:53
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 421986a73b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

choices[choice.index] = {
**choice.model_dump(exclude_unset=True, exclude={"delta"}),
"message": choice.delta.to_dict(),
"message": accumulate_delta({}, choice.delta.to_dict()),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize first chunks for choices added later

This only applies the duplicate-index merge to choices present in the stream's very first chunk. If a multi-choice stream first sees a choice through the except IndexError path in _accumulate_chunk (for example, the first SSE has choice 0 and a later SSE first introduces choice 1) and that choice's first delta contains duplicate tool_calls entries with the same index, line 418 still stores choice.delta.to_dict() directly, so the duplicate entries remain and subsequent chunks merge into only one of them. Please route that new-choice path through accumulate_delta({}, choice.delta.to_dict()) as well.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

accumulate_delta drops tool_call fragments when one chunk has multiple entries at the same index

1 participant