fix: reasoning_content is missing in assistant tool call message#259
fix: reasoning_content is missing in assistant tool call message#259Malpl3naInk wants to merge 7 commits intoGitlawb:mainfrom
Conversation
…easoning content support - Added `reasoning_content` field to `OpenAIMessage` and `OpenAIStreamChunk` interfaces for improved API compatibility. - Implemented extraction of reasoning content from thinking blocks in `convertMessages` function. - Updated `openaiStreamToAnthropic` to handle reasoning content during streaming, converting it to thinking blocks. - Ensured reasoning content is included in the final message structure for better interaction with the API.
auriti
left a comment
There was a problem hiding this comment.
Good addition — reasoning_content is a legitimate extension in the OpenAI-compat ecosystem (DeepSeek, Moonshot, and others use it), and the bidirectional mapping (outgoing: thinking → reasoning_content, incoming: reasoning_content → thinking) is the right approach. The streaming path handles block lifecycle correctly.
Two things to address:
1. redacted_thinking blocks are not filtered
The content filter only excludes thinking:
const thinkingContent = content.filter((b: { type?: string }) => b.type === 'thinking')
const textContent = content.filter(
(b: { type?: string }) => b.type !== 'tool_use' && b.type !== 'thinking',
)redacted_thinking blocks will fall through to textContent and get serialized as text. These should be excluded from textContent (and can be safely dropped — there's no useful content to forward):
const textContent = content.filter(
(b: { type?: string }) =>
b.type !== 'tool_use' && b.type !== 'thinking' && b.type !== 'redacted_thinking',
)2. Missing tests
The changes are testable with the existing test infrastructure in openaiShim.test.ts. At minimum:
- Non-streaming: verify
reasoning_contentin response →thinkingcontent block in output - Streaming: verify
delta.reasoning_content→thinking_deltaevents - Outgoing: verify
thinkingblocks in assistant messages →reasoning_contentfield in request body
Note: this PR is complementary to #258 (which strips residual thinking blocks in convertContentBlocks()). No conflicts — they operate at different layers.
|
How can I use the kimi-k2.5 with openclaude? I have the api key already |
You can type |
- Added tests for non-streaming and streaming scenarios to verify conversion of reasoning_content to thinking blocks and vice versa. - Implemented checks for filtering out redacted_thinking blocks from text content. - Updated the convertMessages function to exclude redacted_thinking types from text content extraction.
|
Updated. Sorry I'm not sure my tests is correct or not, just tell me if there anything I need to do. |
|
@Malpl3naInk check all conflicts |
gnanam1990
left a comment
There was a problem hiding this comment.
The non-streaming reasoning-content handling looks like a step in the right direction, but I think the streaming behavior is still incorrect.
In the streaming path, a thinking block can be started for reasoning_content and then later text or tool blocks are emitted without clearly closing that thinking block first. That risks emitting invalid or overlapping Anthropic-format content blocks.
Please fix the streaming block lifecycle and add a test for a single assistant message that contains both reasoning content and a tool call.
… fix/reasoning-content-missing
…ent handling - Implemented tests to verify the lifecycle of thinking and tool use blocks during streaming. - Enhanced the openaiStreamToAnthropic function to handle null and empty content from DeepSeek, ensuring proper block closure and event emission. - Added checks for reasoning content and tool call references in the streaming response.
|
fix conflict |
… fix/reasoning-content-missing
|
Please fix conflicts |
Summary
Fix compatibility with Moonshot AI's kimi-k2.5 model when reasoning/thinking is enabled. The model returns content in
a separate
reasoning_contentfield and requires this field to be preserved in subsequent requests with tool calls.Fixes the error:
thinking is enabled but reasoning_content is missing in assistant tool call messageChanges
OpenAIMessageinterface: Added optionalreasoning_contentfield for outgoing requestsconvertMessages(): Extractsthinkingcontent blocks from assistant messages and maps them toreasoning_contentfor API compatibilityOpenAIStreamChunkinterface: Addedreasoning_contentto delta type for streaming responsesopenaiStreamToAnthropic(): Handles streamingreasoning_contentby converting it to Anthropicthinking_deltaevents; properly closes thinking blocks on finish_convertNonStreamingResponse(): Extractsreasoning_contentfrom non-streaming responses and converts to Anthropicthinkingcontent blocksTesting
bun test src/services/api/openaiShim.test.ts- passedVerify thinking features with Moonshot API, kimi-k2.5 - passed
Verify thinking features with DeepSeek API, deepseek-reasoner - passed