Skip to content

reasoning_content from OpenAI compatible providers is lost in streaming responses #6484

Description

@Dhongli

Description

When using OpenAI-compatible providers that return reasoning content through streaming deltas, the reasoning data is lost during Spring AI's chunk aggregation process.

I reproduced this with DashScope Qwen3.6 Plus and deepseek-v4-flash.

The provider returns:

{
  "choices": [
    {
      "delta": {
        "reasoning_content": "thinking..."
      }
    }
  ]
}

The OpenAI Java SDK correctly parses it into:

cccc.delta()._additionalProperties()

Example:

Choice{
    delta=Delta{
        additionalProperties={
            reasoning_content='thinking...'
        }
    }
}

However, in:

ChunkMerger.chunkToChatCompletion(...)

only content, refusal and toolCalls are copied into ChatCompletionMessage.
The delta additional properties are discarded.
Current code:

ChatCompletionMessage.Builder msgBuilder =
    ChatCompletionMessage.builder()
        .content(cccc.delta().content())
        .refusal(cccc.delta().refusal());

Later Spring AI tries to read:

choice.message()._additionalProperties()

inside:

getReasoningContent(...)

but the properties are already lost.

Suggested Fix

Copy delta additional properties into ChatCompletionMessage.
Example:

cccc.delta()
    ._additionalProperties()
    .forEach(msgBuilder::putAdditionalProperty);

This allows existing reasoning_content support in:

getReasoningContent(...)

to work correctly.

Verified locally. After preserving delta additional properties,
reasoningContent is correctly populated.

Image Image Image

Version

** Spring AI 2.0.0-RC2**

I have already submitted a pull request containing the fix.
#6483

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions