Skip to content

fix: separate content across streaming tool turns - #1861

Draft
arnabnandy7 wants to merge 1 commit into
embabel:mainfrom
arnabnandy7:fix/streaming-tool-turn-boundary
Draft

fix: separate content across streaming tool turns#1861
arnabnandy7 wants to merge 1 commit into
embabel:mainfrom
arnabnandy7:fix/streaming-tool-turn-boundary

Conversation

@arnabnandy7

@arnabnandy7 arnabnandy7 commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Preserves native reasoning across streaming tool-call turns and prevents content from adjacent inference turns being merged into a single line.

This completes the native-thinking follow-up identified during #1826.

Fixes #1860.

Problem

The streaming tool loop flattened content from consecutive inference turns into a single Flux<String>.

This caused two related problems:

  1. If a tool-requesting turn ended without a newline, its final reasoning content was joined to the first chunk after tool execution:
reasoning before tool<think>reasoning after tool
  1. Spring AI identifies Anthropic native-thinking chunks using metadata["thinking"] = true, but the adapter converted every chunk into an ordinary LlmInferenceStreamEvent.Content. The text remained visible, but its native-thinking identity was lost.

Changes

  • Add provider-neutral LlmInferenceStreamEvent.Thinking.
  • Map Spring AI native-thinking metadata to the new event type.
  • Preserve native-thinking identity across tool execution and subsequent inference turns.
  • Emit native reasoning through the public StreamingEvent.Thinking stream.
  • Preserve incremental delivery without buffering complete reasoning blocks.
  • Insert a newline between inference turns only when the preceding turn is unterminated.
  • Keep the existing raw Flux<String> streaming contract compatible.
  • Document native-thinking and inference-turn boundary behavior.

Testing

Added focused coverage for:

  • Native-thinking metadata mapping in the Spring AI adapter.
  • Original raw streaming compatibility.
  • Native-thinking preservation before and after a tool call.
  • Unterminated content separation across tool turns.
  • Native thinking reaching the public structured-stream API.

Executed:

mvn -pl embabel-agent-api \
  -Dtest=StreamingToolLoopTest,SpringAiLlmMessageStreamerTest,StreamingLlmOperationsImplTest \
  test

Result:

Tests run: 14, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS

Signed-off-by: Arnab Nandy <arnab_nandy7@yahoo.com>
@arnabnandy7
arnabnandy7 force-pushed the fix/streaming-tool-turn-boundary branch from bcad081 to 8829434 Compare August 2, 2026 05:58
@igordayen

Copy link
Copy Markdown
Contributor

@arnabnandy7 ... think was not triggered by native thinking. Perhaps put on hold for now.

for thinking streaming mode, works as expected:

abc....xyx bla bla bla NL ==> StreamEvent.Think ==xyx
abc... blabla .....NL ==> blabla .....

I may consider new interceptor in futurure to give developer both ==> getting stream with existing events AND aggregate, but this aggregation will be totally separately will not touch streaming logic.

Thanks.

@arnabnandy7

Copy link
Copy Markdown
Contributor Author

@arnabnandy7 ... think was not triggered by native thinking. Perhaps put on hold for now.

for thinking streaming mode, works as expected:

abc....xyx bla bla bla NL ==> StreamEvent.Think ==xyx
abc... blabla .....NL ==> blabla .....

I may consider new interceptor in futurure to give developer both ==> getting stream with existing events AND aggregate, but this aggregation will be totally separately will not touch streaming logic.

Thanks.

Should I close the issue and PR/mark it as draft for now?

@igordayen

Copy link
Copy Markdown
Contributor

Should I close the issue and PR/mark it as draft for now?

@arnabnandy7 please keep as a draft this week, and I appreciate patience and cooperation. will resume streaming track after release. thanks

@arnabnandy7
arnabnandy7 marked this pull request as draft August 4, 2026 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

With NATIVE Thinking - requires attention:

2 participants