GH-5806: Merge streaming tool call chunks in MessageAggregator#5854
Open
suryateja-g13 wants to merge 1 commit intospring-projects:mainfrom
Open
GH-5806: Merge streaming tool call chunks in MessageAggregator#5854suryateja-g13 wants to merge 1 commit intospring-projects:mainfrom
suryateja-g13 wants to merge 1 commit intospring-projects:mainfrom
Conversation
…gregator When streaming, models emit tool calls across multiple chunks: the first chunk carries the id and name while subsequent chunks carry partial arguments with an empty id. The previous addAll() approach collected every chunk as a separate ToolCall, producing incomplete entries with empty arguments that caused IllegalArgumentException during execution. mergeToolCallChunk() now inspects each incoming chunk: if it has a non-empty id it starts a new entry; otherwise it appends its arguments to the most recently started call. This handles single calls split across N chunks as well as multiple sequential tool calls. Fixes spring-projectsGH-5806 (spring-projects#5806) Signed-off-by: Gorre Surya <sgorre92@gmail.com>
anuragg-saxenaa
approved these changes
Apr 22, 2026
anuragg-saxenaa
left a comment
There was a problem hiding this comment.
LGTM. The fix changes addAll to a mergeToolCallChunk() loop that correctly handles partial tool call chunks: chunks with a non-empty id start a new entry, while empty-id chunks append arguments to the last entry. The logic correctly reconstructs streamed tool calls across multiple chunks.
The new MessageAggregatorTests has good coverage: merging sequential chunks, passing through complete tool calls, handling multiple parallel tool calls, and null arguments. Edge case handling looks solid.
One minor observation: the code uses StringUtils.hasText(chunk.id()) for the empty-id check. Since id is a String record component, this is safe — empty string or null both return false from hasText. ✅
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.
Summary
idandname, subsequent chunks carry partialargumentswith an emptyidMessageAggregatorwas callingaddAll()on every chunk, producing a list of incompleteToolCallentries with emptyarguments, ultimately causingIllegalArgumentException: toolInput cannot be null or emptyduring executionmergeToolCallChunk()helper: chunks with a non-emptyidstart a new entry; chunks with an emptyidappend theirargumentsto the most recently started callTest plan
MessageAggregatorTests#should_merge_tool_call_chunks_into_single_complete_tool_call— replicates the exact streaming pattern from the issue report (4 chunks, first with id+name, rest with empty id and partial arguments)MessageAggregatorTests#should_pass_through_complete_tool_call_unchanged— single complete tool call (no merging needed) still worksMessageAggregatorTests#should_merge_multiple_parallel_tool_calls— two sequential tool calls each split across two chunks produce two distinct merged entriesMessageAggregatorTests#should_handle_chunk_with_null_arguments— null arguments in first chunk handled without NPEFixes GH-5806 (#5806)
🤖 Generated with Claude Code