Fix streamed tool call accumulation: omit id on argument delta chunks#3
Merged
khasinski merged 1 commit intokhasinski:mainfrom Mar 18, 2026
Merged
Conversation
Prevent StreamAccumulator from creating duplicate entries when argument delta events carry the same call_id as the initial output_item.added event and set id to nil on nameless delta chunks so accumulator appends arguments to the existing tool call instead of overwriting it.
|
Confirming the fix works! |
Owner
|
Thanks, merged :) |
|
Thank you both! |
noelblaschke
pushed a commit
to noelblaschke/ruby_llm-responses_api
that referenced
this pull request
Mar 26, 2026
- Fix streamed tool call accumulation: argument deltas no longer overwrite the tool name (khasinski#3 by @shllg) - Fix gem file permissions from 600 to 644 (khasinski#2) - Extract streaming unit tests to dedicated spec file
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.
Problem
When streaming tool calls via the Responses API,
StreamAccumulatorfails to correctly reconstruct tool calls. This causesNoMethodError: undefined method 'to_sym' for nilwhenChat#execute_tooltries to look up the tool by name.Root cause
The OpenAI Responses API emits two types of events for a tool call:
response.output_item.addedwhich passescall_idandname(e.g."get_weather")response.function_call_arguments.deltawhich passes argument fragments and acall_id, but nonamebuild_streaming_tool_callcurrently setsid: call_idon every delta chunk.StreamAccumulator#accumulate_tool_callstreats any chunk with a non-nilidas a new tool call entry, replacing whatever was stored at that key. This means:call_idmatches the added event'scall_id: each delta overwrites the entry, replacingname: "get_weather"withname: niland discarding previously accumulated arguments.call_iddiffers from the added event'scall_id(which happens in practice — the added event usesitem.call_idwhile deltas use a separate function call ID): the delta creates an entirely new entry withname: nil.In both cases, the final
tool_callshash contains entries withname: nil, andChat#execute_toolcrashes attool_call.name.to_sym.Reproduction
Fix
One-line change in
build_streaming_tool_call: setid: nilon argument delta chunks (whendata['name']is absent). This makesStreamAccumulatorroute the chunk through its "append to latest tool call" path instead of creating/overwriting an entry.The hash key (
call_id =>) is unchanged and doesn't affect accumulator behavior — only theToolCall#idattribute matters for the accumulator's branching logic.