Skip to content

fix(model): normalize malformed streaming tool call fragments#1223

Open
Alexxigang wants to merge 2 commits into
agentscope-ai:mainfrom
Alexxigang:fix/stream-toolcall-assembly
Open

fix(model): normalize malformed streaming tool call fragments#1223
Alexxigang wants to merge 2 commits into
agentscope-ai:mainfrom
Alexxigang:fix/stream-toolcall-assembly

Conversation

@Alexxigang

Copy link
Copy Markdown
Contributor

Summary

Why this fix

Some OpenAI-compatible APIs can return the final argument fragment with name set even though id is null. The previous parser treated any non-empty name as a new tool call, generated a synthetic streaming_ id, and prevented ToolCallsAccumulator from merging the closing fragment back into the original call. The parser now recognizes that malformed named chunk as a fragment so the original call keeps complete JSON arguments.

Validation

  • mvn -pl agentscope-core -Dtest=OpenAIChatFormatterTest,OpenAIStreamingToolCallTest,OpenAIResponseParserTest,ToolCallsAccumulatorTest,OpenAIChatModelTest test -q
  • mvn -pl agentscope-core spotless:check -q

Fixes #1216

@codecov

codecov Bot commented Apr 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 69.23077% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...pe/core/formatter/openai/OpenAIResponseParser.java 69.23% 1 Missing and 3 partials ⚠️

📢 Thoughts on this report? Let us know!

@Alexxigang

Copy link
Copy Markdown
Contributor Author

Friendly ping when maintainers have time. The change is ready on my side, and I'm happy to make any follow-up adjustments if review feedback comes in. Thanks!

@Alexxigang

Copy link
Copy Markdown
Contributor Author

Added targeted streaming edge-case coverage on top of this PR for missing-id first chunks, malformed complete JSON chunks, and thought-signature-only fragments.

Validation:

  • mvn -pl agentscope-core '-Dtest=OpenAIResponseParserTest,OpenAIStreamingToolCallTest,OpenAIChatFormatterTest' test

@LearningGp

Copy link
Copy Markdown
Member

The index field in the OpenAI streaming protocol is specifically designed to correlate multiple chunks of the same tool call. Wouldn't it be more appropriate to leverage this mechanism to address the issue?

@Alexxigang

Copy link
Copy Markdown
Contributor Author

Friendly ping when maintainers have time. The branch is still ready on my side, including the added regression coverage, and I'm happy to make any follow-up adjustments if review feedback comes in. Thanks!

@Alexxigang

Copy link
Copy Markdown
Contributor Author

Checked this against the current implementation before changing anything: index is already part of the correlation path in ToolCallsAccumulator.determineKey() as the last fallback after id, non-placeholder name, and lastToolCallKey.

The cases this PR is targeting are the ones where correlation alone still leaves us with a broken block:

  • first/only chunk has no stable id, so downstream still needs a generated tool-call id
  • the final assembled arguments string is malformed JSON, so we need to preserve raw content instead of dropping it on parse failure
  • Gemini-style thought-signature-only fragments add metadata without advancing the normal name/args fields

So I agree index is the right mechanism for chunk grouping, and the current accumulator already uses it. The remaining fix here is about making the assembled ToolUseBlock still usable when the provider sends incomplete or malformed fragments even after grouping.

@Alexxigang

Copy link
Copy Markdown
Contributor Author

Friendly follow-up on this one as well: the branch is still ready on my side with the regression coverage included, and I can adjust the implementation if you'd prefer a different direction around the streaming tool-call assembly path.

@LearningGp

Copy link
Copy Markdown
Member

PTAL @chickenlj

@AgentScopeJavaBot AgentScopeJavaBot added bug Something isn't working area/core/model Model providers and formatters labels May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core/model Model providers and formatters bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]:执行工具调用是,解析的参数发生异常(When executing the tool call, an exception occurred in the parsed parameters)

3 participants