Describe the bug
TurnCallIdRewriter repairs IDs recycled across turns and blank IDs, but leaves two nonblank identical IDs in the same response unchanged. The SDK then collapses distinct tool results in the next request's history. If the ID was seen in an earlier turn, both new calls receive the same replacement and still collide.
To Reproduce
Using the existing loopback provider gateway in tests/test_tool_call_ids_providers.py, add these scenarios:
"parallel-duplicate-ids": _Scenario(turns=(("dup", "dup"),)),
"parallel-duplicates-after-recycle": _Scenario(turns=(("dup",), ("dup", "dup"))),Run the existing provider-route test for these scenarios and openai/gpt-5.4, in streamed and non-streamed modes. All four cases fail on current main: the final history contains only one of two calls, or two of three calls, although the calls have different arguments and results. The provider endpoint is a local synthetic server; no OpenAI requests are made.
A smaller symptom is that TurnCallIdRewriter([]).rewrite_items() returns duplicate call_id values for two ResponseFunctionToolCall objects with distinct item IDs but the same nonblank call ID.
Expected behavior Assign unique IDs to distinct calls within the turn, while keeping each assignment stable across added/done/completed stream events and preserving the matching outputs. The first valid occurrence should retain its ID.
System Information:
- OS: macOS / Apple Silicon
- Strix commit:
98e3df14258cd58d8b26d6ba8d17014c6182f755(1.7.0) - Python: 3.12.14
- LLM: none; loopback HTTP fixture only
Additional context This extends the existing ID normalization from #976/#1355. I found no open fix for same-response duplicates; the active blank-name work in #1363 addresses a different field. A focused patch and regression coverage are being prepared.
Activity
0No activity yet.