use super::super::AnthropicAdapter;
use super::*;
use crate::adapter::{Adapter, AdapterKind, ServiceType};
use crate::chat::{ChatOptions, ChatOptionsSet, ChatRequest, ReasoningEffort};
use crate::resolver::AuthData;
use crate::{ModelIden, ServiceTarget};
use serde_json::json;
#[test]
fn test_anthropic_opus_4_7_uses_adaptive_thinking() {
let chat_options = ChatOptions {
reasoning_effort: Some(ReasoningEffort::Medium),
..Default::default()
};
let options_set = ChatOptionsSet::default().with_chat_options(Some(&chat_options));
let target = ServiceTarget {
endpoint: AnthropicAdapter::default_endpoint(AdapterKind::Anthropic),
auth: AuthData::from_single("test-key"),
model: ModelIden::new(AdapterKind::Anthropic, "claude-opus-4-7"),
};
let web_req =
AnthropicAdapter::to_web_request_data(target, ServiceType::Chat, ChatRequest::from_user("hello"), options_set)
.expect("to_web_request_data should succeed");
assert_eq!(web_req.payload["thinking"], json!({"type": "adaptive"}));
assert_eq!(web_req.payload["output_config"]["effort"], json!("medium"));
}
#[test]
fn test_anthropic_sonnet_5_uses_adaptive_thinking() {
let chat_options = ChatOptions::default().with_reasoning_effort(ReasoningEffort::High);
let options_set = ChatOptionsSet::default().with_chat_options(Some(&chat_options));
let target = ServiceTarget {
endpoint: AnthropicAdapter::default_endpoint(AdapterKind::Anthropic),
auth: AuthData::from_single("test-key"),
model: ModelIden::new(AdapterKind::Anthropic, "claude-sonnet-5"),
};
let web_req =
AnthropicAdapter::to_web_request_data(target, ServiceType::Chat, ChatRequest::from_user("hello"), options_set)
.expect("to_web_request_data should succeed");
assert_eq!(web_req.payload["thinking"], json!({"type": "adaptive"}));
assert_eq!(web_req.payload["output_config"]["effort"], json!("high"));
}
#[test]
fn test_anthropic_opus_4_7_reasoning_zero_omits_thinking() {
let chat_options = ChatOptions::default().with_reasoning_effort(ReasoningEffort::Zero);
let options_set = ChatOptionsSet::default().with_chat_options(Some(&chat_options));
let target = ServiceTarget {
endpoint: AnthropicAdapter::default_endpoint(AdapterKind::Anthropic),
auth: AuthData::from_single("test-key"),
model: ModelIden::new(AdapterKind::Anthropic, "claude-opus-4-7"),
};
let web_req =
AnthropicAdapter::to_web_request_data(target, ServiceType::Chat, ChatRequest::from_user("hello"), options_set)
.expect("to_web_request_data should succeed");
assert_eq!(web_req.payload.get("thinking"), None, "thinking must be omitted");
assert_eq!(
web_req.payload.get("output_config"),
None,
"output_config.effort must be omitted"
);
}
#[test]
fn test_anthropic_sonnet_5_reasoning_zero_disables_thinking() {
let chat_options = ChatOptions::default().with_reasoning_effort(ReasoningEffort::Zero);
let options_set = ChatOptionsSet::default().with_chat_options(Some(&chat_options));
let target = ServiceTarget {
endpoint: AnthropicAdapter::default_endpoint(AdapterKind::Anthropic),
auth: AuthData::from_single("test-key"),
model: ModelIden::new(AdapterKind::Anthropic, "claude-sonnet-5"),
};
let web_req =
AnthropicAdapter::to_web_request_data(target, ServiceType::Chat, ChatRequest::from_user("hello"), options_set)
.expect("to_web_request_data should succeed");
assert_eq!(web_req.payload["thinking"], json!({"type": "disabled"}));
assert_eq!(
web_req.payload.get("output_config"),
None,
"output_config.effort must be omitted"
);
}
#[test]
fn test_anthropic_reasoning_zero_model_name_suffix() {
for suffix in ["none", "zero"] {
let target = ServiceTarget {
endpoint: AnthropicAdapter::default_endpoint(AdapterKind::Anthropic),
auth: AuthData::from_single("test-key"),
model: ModelIden::new(AdapterKind::Anthropic, format!("claude-sonnet-5-{suffix}")),
};
let web_req = AnthropicAdapter::to_web_request_data(
target,
ServiceType::Chat,
ChatRequest::from_user("hello"),
ChatOptionsSet::default(),
)
.expect("to_web_request_data should succeed");
assert_eq!(
web_req.payload["model"],
json!("claude-sonnet-5"),
"suffix -{suffix} must be stripped"
);
assert_eq!(web_req.payload["thinking"], json!({"type": "disabled"}));
}
}
#[test]
fn test_anthropic_reasoning_zero_other_models_omit_thinking() {
for model in ["claude-sonnet-4-5", "claude-opus-4-6", "claude-fable-5"] {
let chat_options = ChatOptions::default().with_reasoning_effort(ReasoningEffort::Zero);
let options_set = ChatOptionsSet::default().with_chat_options(Some(&chat_options));
let target = ServiceTarget {
endpoint: AnthropicAdapter::default_endpoint(AdapterKind::Anthropic),
auth: AuthData::from_single("test-key"),
model: ModelIden::new(AdapterKind::Anthropic, model),
};
let web_req = AnthropicAdapter::to_web_request_data(
target,
ServiceType::Chat,
ChatRequest::from_user("hello"),
options_set,
)
.expect("to_web_request_data should succeed");
assert_eq!(
web_req.payload.get("thinking"),
None,
"thinking must be omitted for {model}"
);
assert_eq!(
web_req.payload.get("output_config"),
None,
"output_config.effort must be omitted for {model}"
);
}
}
#[test]
fn test_anthropic_opus_5_uses_effort_not_legacy_budget_tokens() {
let chat_options = ChatOptions::default().with_reasoning_effort(ReasoningEffort::High);
let options_set = ChatOptionsSet::default().with_chat_options(Some(&chat_options));
let target = ServiceTarget {
endpoint: AnthropicAdapter::default_endpoint(AdapterKind::Anthropic),
auth: AuthData::from_single("test-key"),
model: ModelIden::new(AdapterKind::Anthropic, "claude-opus-5"),
};
let web_req =
AnthropicAdapter::to_web_request_data(target, ServiceType::Chat, ChatRequest::from_user("hello"), options_set)
.expect("to_web_request_data should succeed");
assert_eq!(web_req.payload["output_config"]["effort"], json!("high"));
assert_eq!(web_req.payload["thinking"], json!({"type": "adaptive"}));
}
#[test]
fn test_anthropic_future_opus_generation_uses_effort() {
for model in ["claude-opus-6", "claude-opus-5-1", "claude-opus-5-20260101"] {
let chat_options = ChatOptions::default().with_reasoning_effort(ReasoningEffort::Medium);
let options_set = ChatOptionsSet::default().with_chat_options(Some(&chat_options));
let target = ServiceTarget {
endpoint: AnthropicAdapter::default_endpoint(AdapterKind::Anthropic),
auth: AuthData::from_single("test-key"),
model: ModelIden::new(AdapterKind::Anthropic, model),
};
let web_req = AnthropicAdapter::to_web_request_data(
target,
ServiceType::Chat,
ChatRequest::from_user("hello"),
options_set,
)
.expect("to_web_request_data should succeed");
assert_eq!(
web_req.payload["output_config"]["effort"],
json!("medium"),
"for {model}"
);
assert_eq!(web_req.payload["thinking"], json!({"type": "adaptive"}), "for {model}");
}
}
#[test]
fn test_anthropic_pre_4_7_models_still_use_budget_tokens() {
for model in [
"claude-opus-4-0",
"claude-opus-4-1",
"claude-opus-4-20250514",
"claude-sonnet-4-5",
] {
let chat_options = ChatOptions::default().with_reasoning_effort(ReasoningEffort::High);
let options_set = ChatOptionsSet::default().with_chat_options(Some(&chat_options));
let target = ServiceTarget {
endpoint: AnthropicAdapter::default_endpoint(AdapterKind::Anthropic),
auth: AuthData::from_single("test-key"),
model: ModelIden::new(AdapterKind::Anthropic, model),
};
let web_req = AnthropicAdapter::to_web_request_data(
target,
ServiceType::Chat,
ChatRequest::from_user("hello"),
options_set,
)
.expect("to_web_request_data should succeed");
assert_eq!(
web_req.payload["thinking"],
json!({"type": "enabled", "budget_tokens": REASONING_HIGH}),
"for {model}"
);
assert_eq!(web_req.payload.get("output_config"), None, "for {model}");
}
}
#[test]
fn test_anthropic_fable_and_mythos_support_xhigh() {
for model in ["claude-fable-5", "claude-mythos-5"] {
let chat_options = ChatOptions::default().with_reasoning_effort(ReasoningEffort::XHigh);
let options_set = ChatOptionsSet::default().with_chat_options(Some(&chat_options));
let target = ServiceTarget {
endpoint: AnthropicAdapter::default_endpoint(AdapterKind::Anthropic),
auth: AuthData::from_single("test-key"),
model: ModelIden::new(AdapterKind::Anthropic, model),
};
let web_req = AnthropicAdapter::to_web_request_data(
target,
ServiceType::Chat,
ChatRequest::from_user("hello"),
options_set,
)
.expect("to_web_request_data should succeed");
assert_eq!(
web_req.payload["output_config"]["effort"],
json!("xhigh"),
"for {model}"
);
}
}
#[test]
fn test_anthropic_opus_5_reasoning_zero_disables_thinking() {
let chat_options = ChatOptions::default().with_reasoning_effort(ReasoningEffort::Zero);
let options_set = ChatOptionsSet::default().with_chat_options(Some(&chat_options));
let target = ServiceTarget {
endpoint: AnthropicAdapter::default_endpoint(AdapterKind::Anthropic),
auth: AuthData::from_single("test-key"),
model: ModelIden::new(AdapterKind::Anthropic, "claude-opus-5"),
};
let web_req =
AnthropicAdapter::to_web_request_data(target, ServiceType::Chat, ChatRequest::from_user("hello"), options_set)
.expect("to_web_request_data should succeed");
assert_eq!(web_req.payload["thinking"], json!({"type": "disabled"}));
assert_eq!(
web_req.payload.get("output_config"),
None,
"output_config.effort must be omitted"
);
}