diff --git a/crates/goose/src/providers/formats/anthropic.rs b/crates/goose/src/providers/formats/anthropic.rs index da7f6b2251..af7371ae78 100644 --- a/crates/goose/src/providers/formats/anthropic.rs +++ b/crates/goose/src/providers/formats/anthropic.rs @@ -504,13 +504,12 @@ pub fn thinking_effort(model_config: &ModelConfig) -> ThinkingEffort { } fn adaptive_effort_value(model_config: &ModelConfig) -> &'static str { - match thinking_effort(model_config) { - ThinkingEffort::Off => "high", - ThinkingEffort::Low => "low", - ThinkingEffort::Medium => "medium", - ThinkingEffort::High => "high", - ThinkingEffort::Max if is_claude_opus_47(&model_config.model_name) => "xhigh", - ThinkingEffort::Max => "max", + match model_config.thinking_effort() { + Some(ThinkingEffort::Low) => "low", + Some(ThinkingEffort::Medium) => "medium", + Some(ThinkingEffort::Max) if is_claude_opus_47(&model_config.model_name) => "xhigh", + Some(ThinkingEffort::Max) => "max", + Some(ThinkingEffort::Off | ThinkingEffort::High) | None => "high", } } @@ -1245,6 +1244,43 @@ mod tests { Ok(()) } + #[test] + fn test_create_request_preserved_opus_47_context_defaults_to_high_effort() -> Result<()> { + let _guard = env_lock::lock_env([ + ("GOOSE_THINKING_EFFORT", None::<&str>), + ("CLAUDE_THINKING_TYPE", None::<&str>), + ("CLAUDE_THINKING_ENABLED", None::<&str>), + ("ANTHROPIC_THINKING_BUDGET", None::<&str>), + ("CLAUDE_THINKING_BUDGET", None::<&str>), + ("ANTHROPIC_PRESERVE_THINKING_CONTEXT", None::<&str>), + ("ANTHROPIC_PRESERVE_UNSIGNED_THINKING", None::<&str>), + ]); + + let mut config = cfg("claude-opus-4-7"); + config.max_tokens = Some(4096); + let messages = vec![ + Message::assistant().with_content(MessageContent::thinking("internal", "")), + Message::user().with_text("Continue"), + ]; + + let payload = create_request_with_options( + &config, + "system", + &messages, + &[], + AnthropicFormatOptions { + preserve_unsigned_thinking: true, + preserve_thinking_context: true, + }, + )?; + + assert_eq!(payload["thinking"]["type"], "adaptive"); + assert_eq!(payload["output_config"]["effort"], "high"); + assert_eq!(payload["max_tokens"], 4096); + + Ok(()) + } + #[test] fn test_create_request_omits_temperature_for_opus_47() -> Result<()> { let _guard = env_lock::lock_env([("GOOSE_THINKING_EFFORT", None::<&str>)]);