fix: preserve DeepSeek V4 reasoning history#4948
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThis change extracts Claude "thinking" media parts into OpenAI ChangesClaude Thinking to OpenAI Reasoning Conversion
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 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
🤖 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 227-231: The guard in
shouldPreserveClaudeThinkingAsOpenAIReasoning uses info.ChannelMeta != nil but
then reads info.UpstreamModelName, causing mismatches; change the conditional to
check the same source field you use for the value (i.e., test info != nil &&
info.UpstreamModelName != "") so modelName is correctly set from
info.UpstreamModelName when present; ensure the rest of the function continues
to use modelName for downstream checks.
🪄 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: 1cff153c-370b-4aac-b813-8b716fe514d4
📒 Files selected for processing (2)
service/convert.goservice/convert_test.go
| func shouldPreserveClaudeThinkingAsOpenAIReasoning(info *relaycommon.RelayInfo, requestModel string) bool { | ||
| modelName := requestModel | ||
| if info != nil && info.ChannelMeta != nil && info.UpstreamModelName != "" { | ||
| modelName = info.UpstreamModelName | ||
| } |
There was a problem hiding this comment.
Use the same source field for guard and value when selecting upstream model.
Line 229 guards on info.ChannelMeta != nil but then reads info.UpstreamModelName. If UpstreamModelName is populated while ChannelMeta is nil, the helper incorrectly falls back to requestModel, which can skip DeepSeek V4 reasoning preservation on routed/mapped models.
Suggested fix
func shouldPreserveClaudeThinkingAsOpenAIReasoning(info *relaycommon.RelayInfo, requestModel string) bool {
modelName := requestModel
- if info != nil && info.ChannelMeta != nil && info.UpstreamModelName != "" {
+ if info != nil && info.UpstreamModelName != "" {
modelName = info.UpstreamModelName
}
return strings.HasPrefix(modelName, "deepseek-v4-")
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func shouldPreserveClaudeThinkingAsOpenAIReasoning(info *relaycommon.RelayInfo, requestModel string) bool { | |
| modelName := requestModel | |
| if info != nil && info.ChannelMeta != nil && info.UpstreamModelName != "" { | |
| modelName = info.UpstreamModelName | |
| } | |
| func shouldPreserveClaudeThinkingAsOpenAIReasoning(info *relaycommon.RelayInfo, requestModel string) bool { | |
| modelName := requestModel | |
| if info != nil && info.UpstreamModelName != "" { | |
| modelName = info.UpstreamModelName | |
| } | |
| return strings.HasPrefix(modelName, "deepseek-v4-") | |
| } |
🤖 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 227 - 231, The guard in
shouldPreserveClaudeThinkingAsOpenAIReasoning uses info.ChannelMeta != nil but
then reads info.UpstreamModelName, causing mismatches; change the conditional to
check the same source field you use for the value (i.e., test info != nil &&
info.UpstreamModelName != "") so modelName is correctly set from
info.UpstreamModelName when present; ensure the rest of the function continues
to use modelName for downstream checks.
📝 变更描述 / Description
DeepSeek V4 thinking 模式在多轮对话中要求把上一轮 assistant 的 reasoning 历史继续传给上游。Claude Code 这类 Anthropic 客户端会把这段内容保存为 Claude
thinkingcontent block;当前 Claude -> OpenAI 转换会跳过该 block,导致第二轮请求缺少reasoning_content,触发上游 400。本次改动在目标上游模型为
deepseek-v4-*时,将 Claudethinkingblock 保留为 OpenAI 消息的reasoning_content。其他模型继续丢弃 thinking block,避免影响普通 OpenAI-compatible 渠道。🚀 变更类型 / Type of change
🔗 关联任务 / Related Issue
reasoning_content报错 #4543✅ 提交前检查项 / Checklist
Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。📸 运行证明 / Proof of Work
Summary by CodeRabbit
New Features
Tests