Repository navigation
fix(anthropic): map thinking to reasoning_effort — upstream only honours that spelling - #7
Merged
Merged
Conversation
…urs that spelling
The previous opt-in mapped Anthropic `thinking:{type:"enabled"}` straight through as an
OpenAI-side `thinking` object. Measured against the real CNB upstream on 2026-10-16, that
spelling does NOT trigger the thinking variant, so `/v1/messages` stayed thinking-less even
with `CNB2API_ALLOW_THINKING=1`:
param reasoning_content
reasoning_effort: high/low/medium > 0 (triggers)
reasoning: {effort} 0
enable_thinking: true 0
thinking: {type:"enabled"} 0
thinking: {type:"enabled",budget} 0
thinking: true 0
(no param, control) 0
Re-verified with a hard prompt, and `enable_thinking` / `thinking` behave exactly like the
no-param control. `reasoning_effort` is the only switch the upstream honours.
Change:
- anthropic.mjs: emit `reasoning_effort` instead of `thinking`; derive the level from
Anthropic `budget_tokens` (<=4096 low, <=16384 medium, else high; missing/invalid -> high,
since too low lets reasoning eat the whole max_tokens). A client-supplied
`reasoning_effort` still wins.
- proxy.mjs: correct the strip-table comment — it claimed all four spellings route to the
thinking variant; only `reasoning_effort` does. The strip list itself is unchanged
(extra stripping is harmless and guards against future spelling changes).
- tests: assert the mapping targets reasoning_effort, cover the budget->level ladder,
and add an E2E that pins `/v1/messages` -> upstream `reasoning_effort`.
Verified end to end against the live CNB upstream (local patched proxy -> deployed cnb2api
-> CNB): `thinking:{enabled,budget_tokens:31999}` now returns a `thinking` block (3114 chars)
plus the answer (1268 chars), stop_reason `end_turn`; the no-thinking control returns text only.
Tests: 79/79.
godx999
force-pushed
the
fix/anthropic-thinking-effort
branch
from
October 16, 2026 06:26
f98d039 to
572b671
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
上一个 PR(#6)加了
CNB2API_ALLOW_THINKING开关,但 Anthropic 路径仍然拿不到思考。实测(直连 cnb2api,绕开 new-api,硬 prompt):
/v1/messages+thinking:{type:"enabled"}/v1/chat/completions+reasoning_effort:high说明开关本身生效了(OpenAI 路径能出思考),问题出在映射用了上游不认的拼写。
根因:上游只认
reasoning_effort逐个拼写打到真实 CNB 上游(每次只改一个参数,同一 prompt):
reasoning_effort: 'high'reasoning_effort: 'low'reasoning_effort: 'medium'reasoning: { effort: 'high' }enable_thinking: truethinking: { type: 'enabled' }thinking: { type: 'enabled', budget_tokens: 8000 }thinking: true用硬 prompt 复核,
enable_thinking/thinking的表现与"不带任何参数"完全一致。改动
src/anthropic.mjs— 开启 opt-in 时不再输出thinking,改输出reasoning_effort;档位由 Anthropic 的
budget_tokens折算(<=4096low /<=16384medium / 其余 high,缺失或非法值取 high —— 取低会让推理吃穿
max_tokens)。客户端显式给了reasoning_effort时以它为准。
src/proxy.mjs— 修正剥除表的注释,与实际行为对齐。test/anthropic.test.mjs— 断言映射目标是reasoning_effort(并显式断言不输出thinking)、覆盖 budget→档位 的阶梯、新增两条 E2E 钉住
/v1/messages→ 上游reasoning_effort。端到端验证(走真实 CNB 上游)
本地运行本分支的 cnb2api,上游指向已部署的 cnb2api(它再访问真实 CNB):
测试