Skip to content

fix(openai): emit reasoning_content in Chat Completions streaming#2159

Open
石岳峰 (syf2211) wants to merge 1 commit into
JetBrains:developfrom
syf2211:fix/2148-streaming-reasoning-content
Open

fix(openai): emit reasoning_content in Chat Completions streaming#2159
石岳峰 (syf2211) wants to merge 1 commit into
JetBrains:developfrom
syf2211:fix/2148-streaming-reasoning-content

Conversation

@syf2211

Copy link
Copy Markdown

Summary

Emit StreamFrame.ReasoningDelta / ReasoningComplete when OpenAI Chat Completions streaming returns choices[].delta.reasoning_content, aligning streaming behavior with the existing non-streaming path.

Fixes #2148

Motivation

Providers such as DeepSeek and OpenAI-compatible gateways return chain-of-thought in streaming deltas as reasoning_content. The non-streaming Chat Completions path already maps this field to MessagePart.Reasoning, but the streaming path ignored it entirely—so switching from execute() to executeStreaming() silently dropped reasoning output.

Changes

  • OpenAIStreamDelta: add optional reasoningContent field (JSON: reasoning_content via SnakeCase naming)
  • OpenAILLMClient.processStreamingResponse: emit ReasoningDelta when delta.reasoningContent is non-blank
  • ABI dumps: update OpenAIStreamDelta public API references
  • Tests: streaming frame emission + JSON chunk deserialization regression tests

Tests

./gradlew :prompt:prompt-executor:prompt-executor-clients:prompt-executor-openai-client:jvmTest \
  --tests "ai.koog.prompt.executor.clients.openai.OpenAIChatCompletionLLMClientTest"

Result: BUILD SUCCESSFUL (4 tests, all pass)

Notes

  • Responses API streaming already handles reasoning via separate events; unchanged.
  • Other OpenAI-compatible clients (DeepSeek, Dashscope, Mistral) still override processStreamingResponse without reasoning emission—a potential follow-up outside this issue's scope.

Parse delta.reasoning_content on OpenAIStreamDelta and emit
StreamFrame.ReasoningDelta during Chat Completions streaming, matching
the non-streaming path that already maps reasoningContent to
MessagePart.Reasoning.

Update ABI dumps for OpenAIStreamDelta.reasoningContent.

Fixes JetBrains#2148
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.

OpenAI Chat Completions streaming drops reasoning (delta.reasoning_content is never emitted as a StreamFrame)

1 participant