chore: opus5 support (including adaptive thinking) (#10686)

Co-authored-by: Michael Neale <14976+michaelneale@users.noreply.github.com>
This commit is contained in:
Michael Neale
2026-07-27 10:37:18 +10:00
committed by GitHub
parent 2855b87a65
commit 305849b717
5 changed files with 693 additions and 0 deletions
@@ -115,4 +115,14 @@ mod tests {
assert!(canonical.cost.input.is_some());
assert!(canonical.cost.output.is_some());
}
#[test]
fn anthropic_opus_5_resolves() {
let canonical = maybe_get_canonical_model("anthropic", "claude-opus-5")
.expect("claude-opus-5 should resolve");
assert_eq!(canonical.limit.context, 1_000_000);
assert_eq!(canonical.limit.output, Some(128_000));
assert!(canonical.cost.input.is_some());
assert!(canonical.cost.output.is_some());
}
}
@@ -14161,6 +14161,39 @@
"output": 128000
}
},
{
"id": "amazon-bedrock/anthropic.claude-opus-5",
"name": "Claude Opus 5",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "amazon-bedrock/anthropic.claude-sonnet-4.5-20250929-v1:0",
"name": "Claude Sonnet 4.5",
@@ -14359,6 +14392,39 @@
"output": 128000
}
},
{
"id": "amazon-bedrock/au.anthropic.claude-opus-5",
"name": "Claude Opus 5 (AU)",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "amazon-bedrock/au.anthropic.claude-sonnet-4.5-20250929-v1:0",
"name": "Claude Sonnet 4.5 (AU)",
@@ -14743,6 +14809,39 @@
"output": 128000
}
},
{
"id": "amazon-bedrock/eu.anthropic.claude-opus-5",
"name": "Claude Opus 5 (EU)",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.5,
"output": 27.5,
"cache_read": 0.55,
"cache_write": 6.875
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "amazon-bedrock/eu.anthropic.claude-sonnet-4.5-20250929-v1:0",
"name": "Claude Sonnet 4.5 (EU)",
@@ -15040,6 +15139,39 @@
"output": 128000
}
},
{
"id": "amazon-bedrock/global.anthropic.claude-opus-5",
"name": "Claude Opus 5 (Global)",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "amazon-bedrock/global.anthropic.claude-sonnet-4.5-20250929-v1:0",
"name": "Claude Sonnet 4.5 (Global)",
@@ -15327,6 +15459,39 @@
"output": 128000
}
},
{
"id": "amazon-bedrock/jp.anthropic.claude-opus-5",
"name": "Claude Opus 5 (JP)",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "amazon-bedrock/jp.anthropic.claude-sonnet-4.5-20250929-v1:0",
"name": "Claude Sonnet 4.5 (JP)",
@@ -16848,6 +17013,39 @@
"output": 128000
}
},
{
"id": "amazon-bedrock/us.anthropic.claude-opus-5",
"name": "Claude Opus 5 (US)",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "amazon-bedrock/us.anthropic.claude-sonnet-4.5-20250929-v1:0",
"name": "Claude Sonnet 4.5 (US)",
@@ -17724,6 +17922,40 @@
"output": 128000
}
},
{
"id": "anthropic/claude-opus-5",
"name": "Claude Opus 5",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"thinking_mode": "adaptive",
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "anthropic/claude-sonnet-4.5",
"name": "Claude Sonnet 4.5 (latest)",
@@ -19433,6 +19665,39 @@
"output": 128000
}
},
{
"id": "azure-cognitive-services/claude-opus-5",
"name": "Claude Opus 5",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "azure-cognitive-services/claude-sonnet-4.5",
"name": "Claude Sonnet 4.5",
@@ -22330,6 +22595,39 @@
"output": 128000
}
},
{
"id": "azure/claude-opus-5",
"name": "Claude Opus 5",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "azure/claude-sonnet-4.5",
"name": "Claude Sonnet 4.5",
@@ -44959,6 +45257,39 @@
"output": 64000
}
},
{
"id": "github-copilot/claude-opus-5",
"name": "Claude Opus 5",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 64000
}
},
{
"id": "github-copilot/claude-sonnet-4",
"name": "Claude Sonnet 4 (latest)",
@@ -48613,6 +48944,39 @@
"output": 128000
}
},
{
"id": "google-vertex-anthropic/claude-opus-5@default",
"name": "Claude Opus 5",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "google-vertex-anthropic/claude-sonnet-4",
"name": "Claude Sonnet 4",
@@ -49009,6 +49373,39 @@
"output": 128000
}
},
{
"id": "google-vertex/claude-opus-5@default",
"name": "Claude Opus 5",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "google-vertex/claude-sonnet-4",
"name": "Claude Sonnet 4",
@@ -69652,6 +70049,39 @@
"output": 128000
}
},
{
"id": "llmgateway/claude-opus-5",
"name": "Claude Opus 5",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "llmgateway/claude-sonnet-4.5",
"name": "Claude Sonnet 4.5 (latest)",
@@ -110215,6 +110645,39 @@
"output": 128000
}
},
{
"id": "opencode/claude-opus-5",
"name": "Claude Opus 5",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "opencode/claude-sonnet-4",
"name": "Claude Sonnet 4",
@@ -113201,6 +113664,72 @@
"output": 128000
}
},
{
"id": "openrouter/anthropic/claude-opus-5",
"name": "Claude Opus 5",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": true,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "openrouter/anthropic/claude-opus-5-fast",
"name": "Claude Opus 5 (Fast)",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 10.0,
"output": 50.0,
"cache_read": 1.0,
"cache_write": 12.5
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "openrouter/anthropic/claude-sonnet-4",
"name": "Claude Sonnet 4",
@@ -146916,6 +147445,70 @@
"output": 128000
}
},
{
"id": "venice/claude-opus-5",
"name": "Claude Opus 5",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-23",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 6.0,
"output": 30.0,
"cache_read": 0.6,
"cache_write": 7.5
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "venice/claude-opus-5-fast",
"name": "Claude Opus 5 Fast",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": false,
"knowledge": "2026-05",
"release_date": "2026-07-23",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 12.0,
"output": 60.0,
"cache_read": 1.2,
"cache_write": 15.0
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "venice/claude-sonnet-4.5",
"name": "Claude Sonnet 4.5",
@@ -150800,6 +151393,72 @@
"output": 128000
}
},
{
"id": "vercel/anthropic/claude-opus-5",
"name": "Claude Opus 5",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": true,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 5.0,
"output": 25.0,
"cache_read": 0.5,
"cache_write": 6.25
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "vercel/anthropic/claude-opus-5-fast",
"name": "Claude Opus 5 (Fast)",
"family": "claude-opus",
"attachment": true,
"reasoning": true,
"tool_call": true,
"temperature": true,
"knowledge": "2026-05",
"release_date": "2026-07-24",
"last_updated": "2026-07-24",
"modalities": {
"input": [
"text",
"image",
"pdf"
],
"output": [
"text"
]
},
"open_weights": false,
"cost": {
"input": 10.0,
"output": 50.0,
"cache_read": 1.0,
"cache_write": 12.5
},
"limit": {
"context": 1000000,
"output": 128000
}
},
{
"id": "vercel/anthropic/claude-sonnet-4",
"name": "Claude Sonnet 4",
@@ -1388,6 +1388,28 @@ mod tests {
Ok(())
}
#[test]
fn test_create_request_adaptive_thinking_for_opus_5() -> Result<()> {
// Claude 5 models reject the legacy thinking.type=enabled shape and
// require thinking.type=adaptive + output_config.effort.
let _guard = env_lock::lock_env([("GOOSE_THINKING_EFFORT", None::<&str>)]);
let mut params = std::collections::HashMap::new();
params.insert("thinking_effort".to_string(), json!("high"));
let mut config = cfg("claude-opus-5");
config.max_tokens = Some(4096);
config.request_params = Some(params);
let messages = vec![Message::user().with_text("Hello")];
let payload = create_request_with_default_options(&config, "system", &messages, &[])?;
assert_eq!(payload["thinking"]["type"], "adaptive");
assert_eq!(payload["output_config"]["effort"], "high");
assert!(payload["thinking"].get("budget_tokens").is_none());
Ok(())
}
#[test]
fn test_create_request_enabled_thinking_with_budget() -> Result<()> {
let _guard = env_lock::lock_env([
+1
View File
@@ -28,6 +28,7 @@ use rmcp::model::Tool;
pub const ANTHROPIC_DEFAULT_MODEL: &str = "claude-sonnet-4-5";
pub const ANTHROPIC_DEFAULT_FAST_MODEL: &str = "claude-haiku-4-5";
const ANTHROPIC_KNOWN_MODELS: &[&str] = &[
"claude-opus-5",
"claude-opus-4-8",
"claude-opus-4-7",
// Claude 4.6 models
@@ -357,6 +357,7 @@ fn get_thinking_mode(canonical_id: &str, value: &Value) -> Option<ThinkingMode>
fn inferred_thinking_mode(canonical_id: &str) -> Option<ThinkingMode> {
match canonical_id {
"anthropic/claude-fable-5" => Some(ThinkingMode::AlwaysOnAdaptive),
"anthropic/claude-opus-5" => Some(ThinkingMode::Adaptive),
"anthropic/claude-opus-4.6" => Some(ThinkingMode::Adaptive),
"anthropic/claude-opus-4.7" => Some(ThinkingMode::Adaptive),
"anthropic/claude-opus-4.8" => Some(ThinkingMode::Adaptive),