fix(relay): preserve reasoning_content and thinking block in playground and Claude conversion - #5125
Conversation
…nd and Claude conversion Fixes DeepSeek reasoning_content 400 error in multi-turn conversations for both default/classic playgrounds and Claude-to-OpenAI relay path.
WalkthroughThis PR adds end-to-end support for reasoning content across the message handling pipeline. The ChangesReasoning content end-to-end support
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~5 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web/classic/src/hooks/playground/useSyncMessageAndCustomBody.js (1)
37-44:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
reasoning_contentis written, but reverse sync still reads the wrong key.You now serialize snake_case (
reasoning_content), butsyncCustomBodyToMessagestill reads camelCase at Line 125 (msg.reasoningContent). That drops reasoning on custom-body → message round trips.Proposed fix
- ...(msg.role === MESSAGE_ROLES.ASSISTANT && { - reasoningContent: msg.reasoningContent || '', + ...(msg.role === MESSAGE_ROLES.ASSISTANT && { + reasoningContent: msg.reasoning_content ?? msg.reasoningContent ?? '', isReasoningExpanded: false, }),Also applies to: 78-82
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web/classic/src/hooks/playground/useSyncMessageAndCustomBody.js` around lines 37 - 44, getMessageHash serializes the reasoning field as snake_case (reasoning_content) but syncCustomBodyToMessage still reads camelCase (reasoningContent), causing lost reasoning on round trips; update syncCustomBodyToMessage to accept both keys (e.g. use msg.reasoning_content ?? msg.reasoningContent) so it reads the serialized snake_case while remaining backward-compatible, and make the other mapping that sets reasoning_content (the second occurrence where messages are mapped to custom body) consistent or likewise tolerant.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@service/convert.go`:
- Around line 152-155: The code maps Claude "thinking" into
openAIMessage.ReasoningContent but the append/filter that pushes openAIMessage
into the messages slice (the guard around the append near the current append
location) only checks for Content or ToolCall and therefore drops messages that
only contain ReasoningContent; update that append guard to also accept messages
where openAIMessage.ReasoningContent is non-nil/non-empty (or mediaMsg.Thinking
was set) so reasoning-only messages are preserved when appending the
openAIMessage.
---
Outside diff comments:
In `@web/classic/src/hooks/playground/useSyncMessageAndCustomBody.js`:
- Around line 37-44: getMessageHash serializes the reasoning field as snake_case
(reasoning_content) but syncCustomBodyToMessage still reads camelCase
(reasoningContent), causing lost reasoning on round trips; update
syncCustomBodyToMessage to accept both keys (e.g. use msg.reasoning_content ??
msg.reasoningContent) so it reads the serialized snake_case while remaining
backward-compatible, and make the other mapping that sets reasoning_content (the
second occurrence where messages are mapped to custom body) consistent or
likewise tolerant.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3da1069c-7f42-4143-8643-832c69dc3ec4
📒 Files selected for processing (5)
service/convert.goweb/classic/src/helpers/utils.jsxweb/classic/src/hooks/playground/useSyncMessageAndCustomBody.jsweb/default/src/features/playground/lib/message-utils.tsweb/default/src/features/playground/types.ts
| case "thinking": | ||
| if mediaMsg.Thinking != nil { | ||
| openAIMessage.ReasoningContent = mediaMsg.Thinking | ||
| } |
There was a problem hiding this comment.
Reasoning-only Claude messages can still be dropped.
This mapping is correct, but the append guard at Line 213 only keeps messages with content/tool calls. If a message has only thinking, ReasoningContent is lost.
Proposed fix
- if len(openAIMessage.ParseContent()) > 0 || len(openAIMessage.ToolCalls) > 0 {
+ if len(openAIMessage.ParseContent()) > 0 || len(openAIMessage.ToolCalls) > 0 || openAIMessage.ReasoningContent != nil {
openAIMessages = append(openAIMessages, openAIMessage)
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@service/convert.go` around lines 152 - 155, The code maps Claude "thinking"
into openAIMessage.ReasoningContent but the append/filter that pushes
openAIMessage into the messages slice (the guard around the append near the
current append location) only checks for Content or ToolCall and therefore drops
messages that only contain ReasoningContent; update that append guard to also
accept messages where openAIMessage.ReasoningContent is non-nil/non-empty (or
mediaMsg.Thinking was set) so reasoning-only messages are preserved when
appending the openAIMessage.
|
重复PR,提交PR请遵守PR模版进行事项确认。 |
哪个PR修复这个问题了?我现在是 v1.0.0-rc.8 问题依旧。 |
可以看issue关联的PR。 |
|
好的,我看到后端 Claude 格式的转换问题已经在 PR #4591 和 #4497 中有了更全面的修复。 |
Playground理论上是没有这个问题的,要触发这个问题需要tool call,现在Playground还没这么健全 |
1、我不是项目的核心贡献者,不可能和你一样了解项目; |
open的那个确实 也没有合并 ,所以并没有修复 。 |


Fixes DeepSeek reasoning_content 400 error in multi-turn conversations for both default/classic playgrounds and Claude-to-OpenAI relay path. Closes #4543. Resolves #4543
Summary by CodeRabbit
Release Notes
New Features