langchain
0b56c1bc - fix: tool call streaming bug with inconsistent indices from Qwen3 (#32160)

Commit
192 days ago
fix: tool call streaming bug with inconsistent indices from Qwen3 (#32160) Fixes a streaming bug where models like Qwen3 (using OpenAI interface) send tool call chunks with inconsistent indices, resulting in duplicate/erroneous tool calls instead of a single merged tool call. ## Problem When Qwen3 streams tool calls, it sends chunks with inconsistent `index` values: - First chunk: `index=1` with tool name and partial arguments - Subsequent chunks: `index=0` with `name=None`, `id=None` and argument continuation The existing `merge_lists` function only merges chunks when their `index` values match exactly, causing these logically related chunks to remain separate, resulting in multiple incomplete tool calls instead of one complete tool call. ```python # Before fix: Results in 1 valid + 1 invalid tool call chunk1 = AIMessageChunk(tool_call_chunks=[ {"name": "search", "args": '{"query":', "id": "call_123", "index": 1} ]) chunk2 = AIMessageChunk(tool_call_chunks=[ {"name": None, "args": ' "test"}', "id": None, "index": 0} ]) merged = chunk1 + chunk2 # Creates 2 separate tool calls # After fix: Results in 1 complete tool call merged = chunk1 + chunk2 # Creates 1 merged tool call: search({"query": "test"}) ``` ## Solution Enhanced the `merge_lists` function in `langchain_core/utils/_merge.py` with intelligent tool call chunk merging: 1. **Preserves existing behavior**: Same-index chunks still merge as before 2. **Adds special handling**: Tool call chunks with `name=None`/`id=None` that don't match any existing index are now merged with the most recent complete tool call chunk 3. **Maintains backward compatibility**: All existing functionality works unchanged 4. **Targeted fix**: Only affects tool call chunks, doesn't change behavior for other list items The fix specifically handles the pattern where: - A continuation chunk has `name=None` and `id=None` (indicating it's part of an ongoing tool call) - No matching index is found in existing chunks - There exists a recent tool call chunk with a valid name or ID to merge with ## Testing Added comprehensive test coverage including: - ✅ Qwen3-style chunks with different indices now merge correctly - ✅ Existing same-index behavior preserved - ✅ Multiple distinct tool calls remain separate - ✅ Edge cases handled (empty chunks, orphaned continuations) - ✅ Backward compatibility maintained Fixes #31511. <!-- START COPILOT CODING AGENT TIPS --> --- 💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click [here](https://survey.alchemer.com/s3/8343779/Copilot-Coding-agent) to start the survey. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mdrxy <61371264+mdrxy@users.noreply.github.com> Co-authored-by: Mason Daugherty <github@mdrxy.com> Co-authored-by: Mason Daugherty <mason@langchain.dev>
Author
Parents
Loading