Skip to content

fix(convert): forward Claude output_config.effort as reasoning_effort to OpenAI-format upstreams - #5993

Open
fengshao1227 wants to merge 1 commit into
QuantumNous:mainfrom
fengshao1227:fix/claude-effort-to-openai-reasoning-effort
Open

fix(convert): forward Claude output_config.effort as reasoning_effort to OpenAI-format upstreams#5993
fengshao1227 wants to merge 1 commit into
QuantumNous:mainfrom
fengshao1227:fix/claude-effort-to-openai-reasoning-effort

Conversation

@fengshao1227

@fengshao1227 fengshao1227 commented Jul 7, 2026

Copy link
Copy Markdown

⚠️ 提交说明 / PR Notice

Important

  • 本描述为人工整理的简洁摘要,未直接粘贴未经整理的 AI 输出。
  • AI 辅助声明:本 PR 的代码与描述由 AI(Claude Code)辅助生成,提交者 git 身份不属于仓库历史核心开发者。

📝 变更描述 / Description

修复 #5922:Claude 格式客户端设置 reasoning effort(请求体中的 output_config.effort,如 high)后,经 OpenAI 类型渠道转发时该参数被静默丢弃,上游收不到 reasoning_effort

根因:service/convert.goClaudeToOpenAIRequest 中,claudeRequest.GetEfforts()(解析 output_config.effort)只在 OpenRouter 分支被消费;非 OpenRouter 的通用分支(即 OpenAI 类型渠道走的路径)完全没有读取 effort,转换后的 GeneralOpenAIRequest.ReasoningEffort 恒为空。

修复:在通用分支中把 effort 赋给 openAIRequest.ReasoningEffort(一行改动)。之所以只需要改这一处:OpenAI 渠道 adaptor 的 ConvertClaudeRequest 会把转换结果继续送入 ConvertOpenAIRequestrelay/channel/openai/adaptor.go),后者对 request.ReasoningEffort 已有完整的下游处理链(o 系列 / gpt-5 的模型后缀与参数适配、OpenRouter 的 reasoning JSON 映射、info.ReasoningEffort 日志记录),本次填上字段后即可复用全部既有逻辑。OpenRouter 分支的 effort 映射行为保持不变。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

新增回归测试 service/convert_effort_test.go(testify,三个场景):

=== RUN   TestClaudeToOpenAIRequestForwardsEffortAsReasoningEffort
--- PASS: TestClaudeToOpenAIRequestForwardsEffortAsReasoningEffort (0.00s)
=== RUN   TestClaudeToOpenAIRequestWithoutEffortLeavesReasoningEffortEmpty
--- PASS: TestClaudeToOpenAIRequestWithoutEffortLeavesReasoningEffortEmpty (0.00s)
=== RUN   TestClaudeToOpenAIRequestOpenRouterEffortMappingUnchanged
--- PASS: TestClaudeToOpenAIRequestOpenRouterEffortMappingUnchanged (0.00s)
PASS
ok      github.com/QuantumNous/new-api/service  0.025s
  • OpenAI 渠道 + output_config: {"effort": "high"} → 转换结果含 "reasoning_effort":"high"(对应 issue 复现场景)。
  • output_configreasoning_effort 不出现(omitempty,不污染无推理需求的请求)。
  • OpenRouter 渠道 → effort 仍走原有 Verbosity 映射,不会重复产生 reasoning_effort 字段。

全量回归:go test ./service/... ./relay/... 全部通过,go vet ./service/ 无告警。

Summary by CodeRabbit

  • Bug Fixes

    • Request conversions now carry effort settings through correctly for standard channels, so upstream requests can include the expected reasoning level.
    • Requests without an effort setting continue to omit that field.
    • OpenRouter behavior remains unchanged, preserving the existing effort-to-verbosity handling.
  • Tests

    • Added regression coverage for effort forwarding, missing-effort behavior, and OpenRouter compatibility.

… to OpenAI-format upstreams

When a Claude-format request carrying output_config.effort (e.g.
reasoning effort high from Claude clients) is converted for a
non-OpenRouter OpenAI-format channel, the effort value was silently
dropped: ClaudeToOpenAIRequest only consumed GetEfforts() in the
OpenRouter branch, so the upstream request never contained
reasoning_effort.

Populate GeneralOpenAIRequest.ReasoningEffort in the generic branch.
The OpenAI channel adaptor already handles this field downstream
(o-series/gpt-5 suffix handling, OpenRouter reasoning mapping), so no
adaptor changes are needed. OpenRouter conversion behavior is
unchanged.

Closes QuantumNous#5922
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 336dc72d-ccda-46d0-9a76-a4ab72df07dd

📥 Commits

Reviewing files that changed from the base of the PR and between 8bc4bf1 and be30703.

📒 Files selected for processing (2)
  • service/convert.go
  • service/convert_effort_test.go

Walkthrough

ClaudeToOpenAIRequest now maps non-empty Claude effort values to ReasoningEffort for non-OpenRouter channels, fixing a gap where this mapping previously only applied to OpenRouter via Verbosity. Three new tests validate forwarding, absence handling, and unchanged OpenRouter behavior.

Changes

Effort Mapping Fix and Tests

Layer / File(s) Summary
Map Claude effort to ReasoningEffort
service/convert.go
Non-OpenRouter branch of ClaudeToOpenAIRequest now sets openAIRequest.ReasoningEffort from claudeRequest.GetEfforts() when non-empty.
Regression tests for effort forwarding
service/convert_effort_test.go
Adds tests verifying effort is forwarded as reasoning_effort for OpenAI channels, remains absent when unset, and OpenRouter's Verbosity mapping stays unchanged.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

  • QuantumNous/new-api#1577: Modifies how ReasoningEffort is handled for OpenRouter vs non-OpenRouter requests, directly related to this mapping fix.
  • QuantumNous/new-api#3120: Introduces/uses ClaudeRequest.GetEfforts() and updates service/convert.go to map Claude effort into OpenAI reasoning fields.
  • QuantumNous/new-api#2863: Adds logic to derive/set effort in Claude requests via OutputConfig, which feeds into the effort forwarded by this PR.

Suggested reviewers: seefs001

Poem

A hop, a skip, an effort set free,
"high" now travels from Claude to me,
ReasoningEffort finally in place,
No more lost fields in outer space,
Tests confirm it — carrot in hand! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main fix: forwarding Claude effort to OpenAI-format upstreams.
Linked Issues check ✅ Passed The change forwards Claude reasoning effort to non-OpenRouter OpenAI requests and preserves OpenRouter behavior, matching #5922.
Out of Scope Changes check ✅ Passed The added test coverage and code changes stay within the effort-forwarding bug fix and don't introduce unrelated behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Calcium-Ion
Calcium-Ion force-pushed the main branch 2 times, most recently from 51fdfc5 to 2b6f1df Compare August 30, 2026 15:03
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.

[Bug] reasoning_effort=high from Claude client is not forwarded to upstream OpenAI channel

1 participant