mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-08-18 12:07:02 +08:00
fix(anthropic): apply thinking config on override path, symmetric with openai
AnthropicAdapter.Stream built thinking config (buildAnthropicThinkingConfig)
and wrote it into body only inside the `if len(body)==0` normal-construction
block. The RequestBodyOverride branch skipped it entirely — a disabled effort
on the override path left whatever thinking config the override body carried,
violating user intent and diverging from openai.go, where
applyOpenAIThinkingDisable runs unconditionally after both branches.
Also, on the normal path, disabled only wrote thinking:{type:disabled} but
left a stale output_config (set by a prior adaptive turn or by
AnthropicExtraParams) in place — an explicitly disabled request could still
carry output_config.effort=high, a contradictory payload.
Fix:
- Extract applyAnthropicThinkingConfig(body, req), called unconditionally
after the override/normal block, mirroring openai.go:1860.
- disabled: force thinking:{type:"disabled"}, delete output_config, set
thinking_disabled_provider_param=thinking.type knob.
- adaptive (AnthropicThinkingEffort non-empty): write
thinking:{type:adaptive,display:summarized} + output_config.
- empty effort: no-op.
- buildAnthropicThinkingConfig retained for stable-message-count / message
normalization signals inside the normal block.
Tests: anthropic_thinking_disable_test.go covers all three branches, alias
normalization (off→disabled), disabled overriding existing adaptive config,
and the override-path symmetry scenario.
This commit is contained in:
@@ -261,18 +261,17 @@ func (adapter *AnthropicAdapter) Stream(ctx context.Context, req StreamRequest,
|
||||
body["tools"] = tools
|
||||
}
|
||||
body["system"] = anthropicProviderSystemBlocks(systemParts)
|
||||
if thinkingConfig != nil {
|
||||
body["thinking"] = thinkingConfig
|
||||
if normalizeRuntimeThinkingEffort(req.ThinkingEffort) != "disabled" {
|
||||
body["output_config"] = buildAnthropicOutputConfig(req)
|
||||
}
|
||||
}
|
||||
frontier := buildAnthropicCacheFrontier(body, stableMessageCount)
|
||||
req.RequestKnobs = annotateAnthropicRequestKnobs(req.RequestKnobs, body, frontier)
|
||||
body = cloneRequestBodyOverride(body)
|
||||
applyAnthropicCacheBreakpoints(body, frontier.BreakpointPositions)
|
||||
frontier.BreakpointCount = len(frontier.BreakpointPositions)
|
||||
}
|
||||
// applyAnthropicThinkingConfig 在 override 块之外无条件调用,确保 RequestBodyOverride
|
||||
// 路径与正常构造路径行为一致:disabled 时强制 thinking:{type:disabled} 并清理冲突字段,
|
||||
// 非 disabled 时按 AnthropicThinkingEffort 写 adaptive 配置。与 openai.go 的
|
||||
// applyOpenAIThinkingDisable 对称——后者也是无条件在两条路径之后调用。
|
||||
applyAnthropicThinkingConfig(body, req)
|
||||
if err := ApplyAnthropicExtraParams(body, req.AnthropicExtraParamsEnabled, req.AnthropicExtraParamsJSON); err != nil {
|
||||
finishedAt = time.Now().UTC()
|
||||
recordLLMSummaryArtifact(req, buildLLMSummaryPayload(req, "anthropic", modelID, startedAt, time.Time{}, finishedAt, "", 0, 0, 0, 0, err))
|
||||
@@ -1367,6 +1366,34 @@ func buildAnthropicThinkingConfig(req StreamRequest) map[string]any {
|
||||
}
|
||||
}
|
||||
|
||||
// applyAnthropicThinkingConfig 在请求体构造完成后(含 RequestBodyOverride 路径)无条件调用,
|
||||
// 与 openai.go 的 applyOpenAIThinkingDisable 对称。它把 thinking 配置写入 body 并在 disabled
|
||||
// 时清理与之冲突的字段,确保两条构造路径行为一致:
|
||||
// - disabled: 强制 thinking:{type:"disabled"},删除 output_config / 残留 thinking adaptive 配置,
|
||||
// 记录 thinking_disabled_provider_param=thinking.type knob
|
||||
// - adaptive: 按 AnthropicThinkingEffort 写 thinking:{type:adaptive,display:summarized} + output_config
|
||||
//
|
||||
// 在 override 路径下,上层若已在 override body 里塞了 thinking/output_config,disabled 时会被正确覆盖。
|
||||
func applyAnthropicThinkingConfig(body map[string]any, req StreamRequest) {
|
||||
if len(body) == 0 {
|
||||
return
|
||||
}
|
||||
if normalizeRuntimeThinkingEffort(req.ThinkingEffort) != "disabled" {
|
||||
if strings.TrimSpace(req.AnthropicThinkingEffort) == "" {
|
||||
return
|
||||
}
|
||||
body["thinking"] = map[string]any{
|
||||
"type": "adaptive",
|
||||
"display": "summarized",
|
||||
}
|
||||
body["output_config"] = buildAnthropicOutputConfig(req)
|
||||
return
|
||||
}
|
||||
body["thinking"] = map[string]any{"type": "disabled"}
|
||||
delete(body, "output_config")
|
||||
setRequestKnob(req, "thinking_disabled_provider_param", "thinking.type")
|
||||
}
|
||||
|
||||
func buildAnthropicOutputConfig(req StreamRequest) map[string]any {
|
||||
return map[string]any{
|
||||
"effort": anthropicThinkingEffort(req),
|
||||
|
||||
Reference in New Issue
Block a user