From 4fc4707cfc379ff9708c1afb044599c740124174 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Mon, 29 Sep 2025 14:21:58 -0400 Subject: [PATCH] Add Sonnet 4.5 support (#39127) Release Notes: - Added support for Claude Sonnet 4.5 for Bring-Your-Own-Key (BYOK) --- crates/anthropic/src/anthropic.rs | 30 +++++++++++++++++ crates/bedrock/src/models.rs | 53 ++++++++++++++++++++++++++++--- 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/crates/anthropic/src/anthropic.rs b/crates/anthropic/src/anthropic.rs index a9a4fbb6340b59cafe3bbc555efb6ad5c9e11806..3949fa9853c24e14b2eeed8662a7695acf3916c0 100644 --- a/crates/anthropic/src/anthropic.rs +++ b/crates/anthropic/src/anthropic.rs @@ -75,6 +75,13 @@ pub enum Model { alias = "claude-sonnet-4-thinking-latest" )] ClaudeSonnet4Thinking, + #[serde(rename = "claude-sonnet-4-5", alias = "claude-sonnet-4-5-latest")] + ClaudeSonnet4_5, + #[serde( + rename = "claude-sonnet-4-5-thinking", + alias = "claude-sonnet-4-5-thinking-latest" + )] + ClaudeSonnet4_5Thinking, #[serde(rename = "claude-3-7-sonnet", alias = "claude-3-7-sonnet-latest")] Claude3_7Sonnet, #[serde( @@ -133,6 +140,14 @@ impl Model { return Ok(Self::ClaudeOpus4); } + if id.starts_with("claude-sonnet-4-5-thinking") { + return Ok(Self::ClaudeSonnet4_5Thinking); + } + + if id.starts_with("claude-sonnet-4-5") { + return Ok(Self::ClaudeSonnet4_5); + } + if id.starts_with("claude-sonnet-4-thinking") { return Ok(Self::ClaudeSonnet4Thinking); } @@ -180,6 +195,8 @@ impl Model { Self::ClaudeOpus4_1Thinking => "claude-opus-4-1-thinking-latest", Self::ClaudeSonnet4 => "claude-sonnet-4-latest", Self::ClaudeSonnet4Thinking => "claude-sonnet-4-thinking-latest", + Self::ClaudeSonnet4_5 => "claude-sonnet-4-5-latest", + Self::ClaudeSonnet4_5Thinking => "claude-sonnet-4-5-thinking-latest", Self::Claude3_5Sonnet => "claude-3-5-sonnet-latest", Self::Claude3_7Sonnet => "claude-3-7-sonnet-latest", Self::Claude3_7SonnetThinking => "claude-3-7-sonnet-thinking-latest", @@ -197,6 +214,7 @@ impl Model { Self::ClaudeOpus4 | Self::ClaudeOpus4Thinking => "claude-opus-4-20250514", Self::ClaudeOpus4_1 | Self::ClaudeOpus4_1Thinking => "claude-opus-4-1-20250805", Self::ClaudeSonnet4 | Self::ClaudeSonnet4Thinking => "claude-sonnet-4-20250514", + Self::ClaudeSonnet4_5 | Self::ClaudeSonnet4_5Thinking => "claude-sonnet-4-5-20250929", Self::Claude3_5Sonnet => "claude-3-5-sonnet-latest", Self::Claude3_7Sonnet | Self::Claude3_7SonnetThinking => "claude-3-7-sonnet-latest", Self::Claude3_5Haiku => "claude-3-5-haiku-latest", @@ -215,6 +233,8 @@ impl Model { Self::ClaudeOpus4_1Thinking => "Claude Opus 4.1 Thinking", Self::ClaudeSonnet4 => "Claude Sonnet 4", Self::ClaudeSonnet4Thinking => "Claude Sonnet 4 Thinking", + Self::ClaudeSonnet4_5 => "Claude Sonnet 4.5", + Self::ClaudeSonnet4_5Thinking => "Claude Sonnet 4.5 Thinking", Self::Claude3_7Sonnet => "Claude 3.7 Sonnet", Self::Claude3_5Sonnet => "Claude 3.5 Sonnet", Self::Claude3_7SonnetThinking => "Claude 3.7 Sonnet Thinking", @@ -236,6 +256,8 @@ impl Model { | Self::ClaudeOpus4_1Thinking | Self::ClaudeSonnet4 | Self::ClaudeSonnet4Thinking + | Self::ClaudeSonnet4_5 + | Self::ClaudeSonnet4_5Thinking | Self::Claude3_5Sonnet | Self::Claude3_5Haiku | Self::Claude3_7Sonnet @@ -261,6 +283,8 @@ impl Model { | Self::ClaudeOpus4_1Thinking | Self::ClaudeSonnet4 | Self::ClaudeSonnet4Thinking + | Self::ClaudeSonnet4_5 + | Self::ClaudeSonnet4_5Thinking | Self::Claude3_5Sonnet | Self::Claude3_5Haiku | Self::Claude3_7Sonnet @@ -280,6 +304,8 @@ impl Model { | Self::ClaudeOpus4_1Thinking | Self::ClaudeSonnet4 | Self::ClaudeSonnet4Thinking + | Self::ClaudeSonnet4_5 + | Self::ClaudeSonnet4_5Thinking | Self::Claude3_5Sonnet | Self::Claude3_7Sonnet | Self::Claude3_7SonnetThinking @@ -299,6 +325,8 @@ impl Model { | Self::ClaudeOpus4_1Thinking | Self::ClaudeSonnet4 | Self::ClaudeSonnet4Thinking + | Self::ClaudeSonnet4_5 + | Self::ClaudeSonnet4_5Thinking | Self::Claude3_5Sonnet | Self::Claude3_7Sonnet | Self::Claude3_7SonnetThinking @@ -318,6 +346,7 @@ impl Model { Self::ClaudeOpus4 | Self::ClaudeOpus4_1 | Self::ClaudeSonnet4 + | Self::ClaudeSonnet4_5 | Self::Claude3_5Sonnet | Self::Claude3_7Sonnet | Self::Claude3_5Haiku @@ -327,6 +356,7 @@ impl Model { Self::ClaudeOpus4Thinking | Self::ClaudeOpus4_1Thinking | Self::ClaudeSonnet4Thinking + | Self::ClaudeSonnet4_5Thinking | Self::Claude3_7SonnetThinking => AnthropicModelMode::Thinking { budget_tokens: Some(4_096), }, diff --git a/crates/bedrock/src/models.rs b/crates/bedrock/src/models.rs index c3a793d69d086a8a8c607d34debc5a7034f33f32..4566316aee7d1c235a9a246f0f0c519c7860c8b4 100644 --- a/crates/bedrock/src/models.rs +++ b/crates/bedrock/src/models.rs @@ -30,6 +30,13 @@ pub enum Model { alias = "claude-sonnet-4-thinking-latest" )] ClaudeSonnet4Thinking, + #[serde(rename = "claude-sonnet-4-5", alias = "claude-sonnet-4-5-latest")] + ClaudeSonnet4_5, + #[serde( + rename = "claude-sonnet-4-5-thinking", + alias = "claude-sonnet-4-5-thinking-latest" + )] + ClaudeSonnet4_5Thinking, #[serde(rename = "claude-opus-4", alias = "claude-opus-4-latest")] ClaudeOpus4, #[serde(rename = "claude-opus-4-1", alias = "claude-opus-4-1-latest")] @@ -144,6 +151,14 @@ impl Model { Ok(Self::Claude3_7Sonnet) } else if id.starts_with("claude-3-7-sonnet-thinking") { Ok(Self::Claude3_7SonnetThinking) + } else if id.starts_with("claude-sonnet-4-5-thinking") { + Ok(Self::ClaudeSonnet4_5Thinking) + } else if id.starts_with("claude-sonnet-4-5") { + Ok(Self::ClaudeSonnet4_5) + } else if id.starts_with("claude-sonnet-4-thinking") { + Ok(Self::ClaudeSonnet4Thinking) + } else if id.starts_with("claude-sonnet-4") { + Ok(Self::ClaudeSonnet4) } else { anyhow::bail!("invalid model id {id}"); } @@ -153,6 +168,8 @@ impl Model { match self { Model::ClaudeSonnet4 => "claude-sonnet-4", Model::ClaudeSonnet4Thinking => "claude-sonnet-4-thinking", + Model::ClaudeSonnet4_5 => "claude-sonnet-4-5", + Model::ClaudeSonnet4_5Thinking => "claude-sonnet-4-5-thinking", Model::ClaudeOpus4 => "claude-opus-4", Model::ClaudeOpus4_1 => "claude-opus-4-1", Model::ClaudeOpus4Thinking => "claude-opus-4-thinking", @@ -214,6 +231,9 @@ impl Model { Model::ClaudeSonnet4 | Model::ClaudeSonnet4Thinking => { "anthropic.claude-sonnet-4-20250514-v1:0" } + Model::ClaudeSonnet4_5 | Model::ClaudeSonnet4_5Thinking => { + "anthropic.claude-sonnet-4-5-20250929-v1:0" + } Model::ClaudeOpus4 | Model::ClaudeOpus4Thinking => { "anthropic.claude-opus-4-20250514-v1:0" } @@ -277,6 +297,8 @@ impl Model { match self { Self::ClaudeSonnet4 => "Claude Sonnet 4", Self::ClaudeSonnet4Thinking => "Claude Sonnet 4 Thinking", + Self::ClaudeSonnet4_5 => "Claude Sonnet 4.5", + Self::ClaudeSonnet4_5Thinking => "Claude Sonnet 4.5 Thinking", Self::ClaudeOpus4 => "Claude Opus 4", Self::ClaudeOpus4_1 => "Claude Opus 4.1", Self::ClaudeOpus4Thinking => "Claude Opus 4 Thinking", @@ -346,6 +368,8 @@ impl Model { | Self::ClaudeOpus4 | Self::ClaudeOpus4_1 | Self::ClaudeSonnet4Thinking + | Self::ClaudeSonnet4_5 + | Self::ClaudeSonnet4_5Thinking | Self::ClaudeOpus4Thinking | Self::ClaudeOpus4_1Thinking => 200_000, Self::AmazonNovaPremier => 1_000_000, @@ -361,6 +385,7 @@ impl Model { Self::Claude3Opus | Self::Claude3Sonnet | Self::Claude3_5Haiku => 4_096, Self::Claude3_7Sonnet | Self::Claude3_7SonnetThinking => 128_000, Self::ClaudeSonnet4 | Self::ClaudeSonnet4Thinking => 64_000, + Self::ClaudeSonnet4_5 | Self::ClaudeSonnet4_5Thinking => 64_000, Self::ClaudeOpus4 | Self::ClaudeOpus4Thinking | Self::ClaudeOpus4_1 @@ -385,7 +410,9 @@ impl Model { | Self::ClaudeOpus4_1 | Self::ClaudeOpus4_1Thinking | Self::ClaudeSonnet4 - | Self::ClaudeSonnet4Thinking => 1.0, + | Self::ClaudeSonnet4Thinking + | Self::ClaudeSonnet4_5 + | Self::ClaudeSonnet4_5Thinking => 1.0, Self::Custom { default_temperature, .. @@ -409,6 +436,8 @@ impl Model { | Self::ClaudeOpus4_1Thinking | Self::ClaudeSonnet4 | Self::ClaudeSonnet4Thinking + | Self::ClaudeSonnet4_5 + | Self::ClaudeSonnet4_5Thinking | Self::Claude3_5Haiku => true, // Amazon Nova models (all support tool use) @@ -439,6 +468,8 @@ impl Model { | Self::Claude3_7SonnetThinking | Self::ClaudeSonnet4 | Self::ClaudeSonnet4Thinking + | Self::ClaudeSonnet4_5 + | Self::ClaudeSonnet4_5Thinking | Self::ClaudeOpus4 | Self::ClaudeOpus4Thinking | Self::ClaudeOpus4_1 @@ -488,9 +519,11 @@ impl Model { Model::Claude3_7SonnetThinking => BedrockModelMode::Thinking { budget_tokens: Some(4096), }, - Model::ClaudeSonnet4Thinking => BedrockModelMode::Thinking { - budget_tokens: Some(4096), - }, + Model::ClaudeSonnet4Thinking | Model::ClaudeSonnet4_5Thinking => { + BedrockModelMode::Thinking { + budget_tokens: Some(4096), + } + } Model::ClaudeOpus4Thinking | Model::ClaudeOpus4_1Thinking => { BedrockModelMode::Thinking { budget_tokens: Some(4096), @@ -542,6 +575,8 @@ impl Model { | Model::Claude3_7SonnetThinking | Model::ClaudeSonnet4 | Model::ClaudeSonnet4Thinking + | Model::ClaudeSonnet4_5 + | Model::ClaudeSonnet4_5Thinking | Model::ClaudeOpus4 | Model::ClaudeOpus4Thinking | Model::ClaudeOpus4_1 @@ -575,6 +610,8 @@ impl Model { | Model::Claude3_7SonnetThinking | Model::ClaudeSonnet4 | Model::ClaudeSonnet4Thinking + | Model::ClaudeSonnet4_5 + | Model::ClaudeSonnet4_5Thinking | Model::Claude3Haiku | Model::Claude3Sonnet | Model::MetaLlama321BInstructV1 @@ -592,7 +629,9 @@ impl Model { | Model::Claude3_7Sonnet | Model::Claude3_7SonnetThinking | Model::ClaudeSonnet4 - | Model::ClaudeSonnet4Thinking, + | Model::ClaudeSonnet4Thinking + | Model::ClaudeSonnet4_5 + | Model::ClaudeSonnet4_5Thinking, "apac", ) => Ok(format!("{}.{}", region_group, model_id)), @@ -631,6 +670,10 @@ mod tests { Model::ClaudeSonnet4.cross_region_inference_id("eu-west-1")?, "eu.anthropic.claude-sonnet-4-20250514-v1:0" ); + assert_eq!( + Model::ClaudeSonnet4_5.cross_region_inference_id("eu-west-1")?, + "eu.anthropic.claude-sonnet-4-5-20250929-v1:0" + ); assert_eq!( Model::Claude3Sonnet.cross_region_inference_id("eu-west-1")?, "eu.anthropic.claude-3-sonnet-20240229-v1:0"