Skip to content

Fix OpenAI streaming tool call chunk merging#6525

Open
liushenling2001 wants to merge 2 commits into
spring-projects:mainfrom
liushenling2001:codex/fix-openai-empty-tool-calls
Open

Fix OpenAI streaming tool call chunk merging#6525
liushenling2001 wants to merge 2 commits into
spring-projects:mainfrom
liushenling2001:codex/fix-openai-empty-tool-calls

Conversation

@liushenling2001

Copy link
Copy Markdown
Contributor

Summary

Fix OpenAI streaming tool call chunk merging for OpenAI-compatible providers.

Some OpenAI-compatible servers, observed with vLLM-backed endpoints, stream one logical tool call across multiple chunks. The tool call id, function name, and function arguments can arrive in separate chunks, and some providers repeat the same tool call id on later chunks.

The previous ChunkMerger appended every chunk that contained a tool call id as a new tool call. That could split one logical tool call into multiple incomplete tool calls. In practice this caused stream aggregation or downstream tool execution failures, including errors like:

  • NoSuchElementException / aggregation errors while converting merged chunks
  • toolName cannot be null or empty when an incomplete merged tool call reached tool execution
  • No ToolCallback found when the logical function metadata was split incorrectly across chunks

Changes

  • Merge streaming tool call chunks by tool call index or repeated id instead of appending every id-bearing chunk.
  • Preserve the first available function name.
  • Concatenate streamed function argument fragments.
  • Keep conversion strict so a final merged tool call must still contain id/function/name.
  • Add regression tests for:
    • id, function.name, and function.arguments arriving in separate chunks
    • providers repeating the same tool call id across chunks

Verification

Ran:

mvn -pl models/spring-ai-openai -Dtest=OpenAiChatModelTests test

Result: Tests run: 24, Failures: 0, Errors: 0, Skipped: 0.

OpenAI-compatible providers such as vLLM can stream a single tool call across multiple chunks, with id, function name, and function arguments arriving separately. Some providers also repeat the same tool call id on later chunks.

The previous merger appended chunks whenever an id was present, which could split one logical tool call into multiple incomplete calls. That led to stream aggregation failures and later tool execution errors such as missing or empty tool names.

Merge tool call chunks by index/id, preserve the first function name, concatenate argument fragments, and add regression coverage for split fields and repeated ids.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants