mirror of
https://github.com/block/goose.git
synced 2026-06-02 06:19:33 +02:00
fix(anthropic): legacy budget maps adaptive-only models to adaptive
Address codex review (new P1) on #9484: thinking_type() returned Enabled whenever only a legacy ANTHROPIC_THINKING_BUDGET / CLAUDE_THINKING_BUDGET was set, before checking is_adaptive_model. For adaptive-only Opus 4.7/4.8 that produced thinking: {"type":"enabled","budget_tokens":...}, which Anthropic rejects with HTTP 400. Now the legacy-budget path maps adaptive models to the adaptive payload while non-adaptive models keep the enabled/budget behavior. Adds a test covering the legacy-budget-without-effort path. Signed-off-by: Michael Neale <michael.neale@gmail.com>
This commit is contained in:
@@ -92,7 +92,13 @@ pub fn thinking_type(model_config: &ModelConfig) -> ThinkingType {
|
||||
let effort = model_config.thinking_effort();
|
||||
|
||||
if effort.is_none() && legacy_thinking_budget_tokens().is_some() {
|
||||
return ThinkingType::Enabled;
|
||||
// Adaptive-only models reject manual budget_tokens, so a legacy budget
|
||||
// setting must still map to the adaptive payload rather than enabled.
|
||||
return if is_adaptive_model {
|
||||
ThinkingType::Adaptive
|
||||
} else {
|
||||
ThinkingType::Enabled
|
||||
};
|
||||
}
|
||||
|
||||
match effort.unwrap_or(ThinkingEffort::Off) {
|
||||
@@ -1616,6 +1622,36 @@ mod tests {
|
||||
assert_eq!(thinking_budget_tokens(&config), 8192);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_legacy_budget_maps_adaptive_models_to_adaptive() {
|
||||
let _guard = env_lock::lock_env([
|
||||
("GOOSE_THINKING_EFFORT", None::<&str>),
|
||||
// Set to an unrecognized value so env (read first) shadows any
|
||||
// CLAUDE_THINKING_TYPE in the developer's config file, leaving
|
||||
// thinking_effort() as None so the legacy-budget branch is exercised.
|
||||
("CLAUDE_THINKING_TYPE", Some("unset")),
|
||||
("CLAUDE_THINKING_ENABLED", None::<&str>),
|
||||
("ANTHROPIC_THINKING_BUDGET", Some("8192")),
|
||||
("CLAUDE_THINKING_BUDGET", None::<&str>),
|
||||
]);
|
||||
|
||||
// Adaptive-only models must use the adaptive payload even when only a
|
||||
// legacy budget env var is set (no thinking_effort configured).
|
||||
for model in ["claude-opus-4-6", "claude-opus-4-7", "claude-opus-4-8"] {
|
||||
assert_eq!(
|
||||
thinking_type(&cfg(model)),
|
||||
ThinkingType::Adaptive,
|
||||
"model {model}"
|
||||
);
|
||||
}
|
||||
|
||||
// Non-adaptive models keep the legacy enabled/budget payload.
|
||||
assert_eq!(
|
||||
thinking_type(&cfg("claude-3-7-sonnet-20250219")),
|
||||
ThinkingType::Enabled
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_thinking_type_non_claude_always_disabled() {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user