Add Claude Opus 4.1 (#35653)

Richard Feldman and Marshall Bowers created

<img width="348" height="427" alt="Screenshot 2025-08-05 at 1 55 35 PM"
src="https://github.com/user-attachments/assets/52af17a5-0095-4ad9-9afe-ff27aab90e03"
/>

Release Notes:

- Added support for Claude Opus 4.1

Co-authored-by: Marshall Bowers <git@maxdeviant.com>

Change summary

crates/anthropic/src/anthropic.rs | 30 ++++++++++++++++++++++
crates/bedrock/src/models.rs      | 44 +++++++++++++++++++++++++++-----
2 files changed, 67 insertions(+), 7 deletions(-)

Detailed changes

crates/anthropic/src/anthropic.rs 🔗

@@ -36,11 +36,18 @@ pub enum AnthropicModelMode {
 pub enum Model {
     #[serde(rename = "claude-opus-4", alias = "claude-opus-4-latest")]
     ClaudeOpus4,
+    #[serde(rename = "claude-opus-4-1", alias = "claude-opus-4-1-latest")]
+    ClaudeOpus4_1,
     #[serde(
         rename = "claude-opus-4-thinking",
         alias = "claude-opus-4-thinking-latest"
     )]
     ClaudeOpus4Thinking,
+    #[serde(
+        rename = "claude-opus-4-1-thinking",
+        alias = "claude-opus-4-1-thinking-latest"
+    )]
+    ClaudeOpus4_1Thinking,
     #[default]
     #[serde(rename = "claude-sonnet-4", alias = "claude-sonnet-4-latest")]
     ClaudeSonnet4,
@@ -91,10 +98,18 @@ impl Model {
     }
 
     pub fn from_id(id: &str) -> Result<Self> {
+        if id.starts_with("claude-opus-4-1-thinking") {
+            return Ok(Self::ClaudeOpus4_1Thinking);
+        }
+
         if id.starts_with("claude-opus-4-thinking") {
             return Ok(Self::ClaudeOpus4Thinking);
         }
 
+        if id.starts_with("claude-opus-4-1") {
+            return Ok(Self::ClaudeOpus4_1);
+        }
+
         if id.starts_with("claude-opus-4") {
             return Ok(Self::ClaudeOpus4);
         }
@@ -141,7 +156,9 @@ impl Model {
     pub fn id(&self) -> &str {
         match self {
             Self::ClaudeOpus4 => "claude-opus-4-latest",
+            Self::ClaudeOpus4_1 => "claude-opus-4-1-latest",
             Self::ClaudeOpus4Thinking => "claude-opus-4-thinking-latest",
+            Self::ClaudeOpus4_1Thinking => "claude-opus-4-1-thinking-latest",
             Self::ClaudeSonnet4 => "claude-sonnet-4-latest",
             Self::ClaudeSonnet4Thinking => "claude-sonnet-4-thinking-latest",
             Self::Claude3_5Sonnet => "claude-3-5-sonnet-latest",
@@ -159,6 +176,7 @@ impl Model {
     pub fn request_id(&self) -> &str {
         match self {
             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::Claude3_5Sonnet => "claude-3-5-sonnet-latest",
             Self::Claude3_7Sonnet | Self::Claude3_7SonnetThinking => "claude-3-7-sonnet-latest",
@@ -173,7 +191,9 @@ impl Model {
     pub fn display_name(&self) -> &str {
         match self {
             Self::ClaudeOpus4 => "Claude Opus 4",
+            Self::ClaudeOpus4_1 => "Claude Opus 4.1",
             Self::ClaudeOpus4Thinking => "Claude Opus 4 Thinking",
+            Self::ClaudeOpus4_1Thinking => "Claude Opus 4.1 Thinking",
             Self::ClaudeSonnet4 => "Claude Sonnet 4",
             Self::ClaudeSonnet4Thinking => "Claude Sonnet 4 Thinking",
             Self::Claude3_7Sonnet => "Claude 3.7 Sonnet",
@@ -192,7 +212,9 @@ impl Model {
     pub fn cache_configuration(&self) -> Option<AnthropicModelCacheConfiguration> {
         match self {
             Self::ClaudeOpus4
+            | Self::ClaudeOpus4_1
             | Self::ClaudeOpus4Thinking
+            | Self::ClaudeOpus4_1Thinking
             | Self::ClaudeSonnet4
             | Self::ClaudeSonnet4Thinking
             | Self::Claude3_5Sonnet
@@ -215,7 +237,9 @@ impl Model {
     pub fn max_token_count(&self) -> u64 {
         match self {
             Self::ClaudeOpus4
+            | Self::ClaudeOpus4_1
             | Self::ClaudeOpus4Thinking
+            | Self::ClaudeOpus4_1Thinking
             | Self::ClaudeSonnet4
             | Self::ClaudeSonnet4Thinking
             | Self::Claude3_5Sonnet
@@ -232,7 +256,9 @@ impl Model {
     pub fn max_output_tokens(&self) -> u64 {
         match self {
             Self::ClaudeOpus4
+            | Self::ClaudeOpus4_1
             | Self::ClaudeOpus4Thinking
+            | Self::ClaudeOpus4_1Thinking
             | Self::ClaudeSonnet4
             | Self::ClaudeSonnet4Thinking
             | Self::Claude3_5Sonnet
@@ -249,7 +275,9 @@ impl Model {
     pub fn default_temperature(&self) -> f32 {
         match self {
             Self::ClaudeOpus4
+            | Self::ClaudeOpus4_1
             | Self::ClaudeOpus4Thinking
+            | Self::ClaudeOpus4_1Thinking
             | Self::ClaudeSonnet4
             | Self::ClaudeSonnet4Thinking
             | Self::Claude3_5Sonnet
@@ -269,6 +297,7 @@ impl Model {
     pub fn mode(&self) -> AnthropicModelMode {
         match self {
             Self::ClaudeOpus4
+            | Self::ClaudeOpus4_1
             | Self::ClaudeSonnet4
             | Self::Claude3_5Sonnet
             | Self::Claude3_7Sonnet
@@ -277,6 +306,7 @@ impl Model {
             | Self::Claude3Sonnet
             | Self::Claude3Haiku => AnthropicModelMode::Default,
             Self::ClaudeOpus4Thinking
+            | Self::ClaudeOpus4_1Thinking
             | Self::ClaudeSonnet4Thinking
             | Self::Claude3_7SonnetThinking => AnthropicModelMode::Thinking {
                 budget_tokens: Some(4_096),

crates/bedrock/src/models.rs 🔗

@@ -32,11 +32,18 @@ pub enum Model {
     ClaudeSonnet4Thinking,
     #[serde(rename = "claude-opus-4", alias = "claude-opus-4-latest")]
     ClaudeOpus4,
+    #[serde(rename = "claude-opus-4-1", alias = "claude-opus-4-1-latest")]
+    ClaudeOpus4_1,
     #[serde(
         rename = "claude-opus-4-thinking",
         alias = "claude-opus-4-thinking-latest"
     )]
     ClaudeOpus4Thinking,
+    #[serde(
+        rename = "claude-opus-4-1-thinking",
+        alias = "claude-opus-4-1-thinking-latest"
+    )]
+    ClaudeOpus4_1Thinking,
     #[serde(rename = "claude-3-5-sonnet-v2", alias = "claude-3-5-sonnet-latest")]
     Claude3_5SonnetV2,
     #[serde(rename = "claude-3-7-sonnet", alias = "claude-3-7-sonnet-latest")]
@@ -147,7 +154,9 @@ impl Model {
             Model::ClaudeSonnet4 => "claude-4-sonnet",
             Model::ClaudeSonnet4Thinking => "claude-4-sonnet-thinking",
             Model::ClaudeOpus4 => "claude-4-opus",
+            Model::ClaudeOpus4_1 => "claude-4-opus-1",
             Model::ClaudeOpus4Thinking => "claude-4-opus-thinking",
+            Model::ClaudeOpus4_1Thinking => "claude-4-opus-1-thinking",
             Model::Claude3_5SonnetV2 => "claude-3-5-sonnet-v2",
             Model::Claude3_5Sonnet => "claude-3-5-sonnet",
             Model::Claude3Opus => "claude-3-opus",
@@ -208,6 +217,9 @@ impl Model {
             Model::ClaudeOpus4 | Model::ClaudeOpus4Thinking => {
                 "anthropic.claude-opus-4-20250514-v1:0"
             }
+            Model::ClaudeOpus4_1 | Model::ClaudeOpus4_1Thinking => {
+                "anthropic.claude-opus-4-1-20250805-v1:0"
+            }
             Model::Claude3_5SonnetV2 => "anthropic.claude-3-5-sonnet-20241022-v2:0",
             Model::Claude3_5Sonnet => "anthropic.claude-3-5-sonnet-20240620-v1:0",
             Model::Claude3Opus => "anthropic.claude-3-opus-20240229-v1:0",
@@ -266,7 +278,9 @@ impl Model {
             Self::ClaudeSonnet4 => "Claude Sonnet 4",
             Self::ClaudeSonnet4Thinking => "Claude Sonnet 4 Thinking",
             Self::ClaudeOpus4 => "Claude Opus 4",
+            Self::ClaudeOpus4_1 => "Claude Opus 4.1",
             Self::ClaudeOpus4Thinking => "Claude Opus 4 Thinking",
+            Self::ClaudeOpus4_1Thinking => "Claude Opus 4.1 Thinking",
             Self::Claude3_5SonnetV2 => "Claude 3.5 Sonnet v2",
             Self::Claude3_5Sonnet => "Claude 3.5 Sonnet",
             Self::Claude3Opus => "Claude 3 Opus",
@@ -330,8 +344,10 @@ impl Model {
             | Self::Claude3_7Sonnet
             | Self::ClaudeSonnet4
             | Self::ClaudeOpus4
+            | Self::ClaudeOpus4_1
             | Self::ClaudeSonnet4Thinking
-            | Self::ClaudeOpus4Thinking => 200_000,
+            | Self::ClaudeOpus4Thinking
+            | Self::ClaudeOpus4_1Thinking => 200_000,
             Self::AmazonNovaPremier => 1_000_000,
             Self::PalmyraWriterX5 => 1_000_000,
             Self::PalmyraWriterX4 => 128_000,
@@ -348,7 +364,9 @@ impl Model {
             | Self::ClaudeSonnet4
             | Self::ClaudeSonnet4Thinking
             | Self::ClaudeOpus4
-            | Model::ClaudeOpus4Thinking => 128_000,
+            | Model::ClaudeOpus4Thinking
+            | Self::ClaudeOpus4_1
+            | Model::ClaudeOpus4_1Thinking => 128_000,
             Self::Claude3_5SonnetV2 | Self::PalmyraWriterX4 | Self::PalmyraWriterX5 => 8_192,
             Self::Custom {
                 max_output_tokens, ..
@@ -366,6 +384,8 @@ impl Model {
             | Self::Claude3_7Sonnet
             | Self::ClaudeOpus4
             | Self::ClaudeOpus4Thinking
+            | Self::ClaudeOpus4_1
+            | Self::ClaudeOpus4_1Thinking
             | Self::ClaudeSonnet4
             | Self::ClaudeSonnet4Thinking => 1.0,
             Self::Custom {
@@ -387,6 +407,8 @@ impl Model {
             | Self::Claude3_7SonnetThinking
             | Self::ClaudeOpus4
             | Self::ClaudeOpus4Thinking
+            | Self::ClaudeOpus4_1
+            | Self::ClaudeOpus4_1Thinking
             | Self::ClaudeSonnet4
             | Self::ClaudeSonnet4Thinking
             | Self::Claude3_5Haiku => true,
@@ -420,7 +442,9 @@ impl Model {
             | Self::ClaudeSonnet4
             | Self::ClaudeSonnet4Thinking
             | Self::ClaudeOpus4
-            | Self::ClaudeOpus4Thinking => true,
+            | Self::ClaudeOpus4Thinking
+            | Self::ClaudeOpus4_1
+            | Self::ClaudeOpus4_1Thinking => true,
 
             // Custom models - check if they have cache configuration
             Self::Custom {
@@ -440,7 +464,9 @@ impl Model {
             | Self::ClaudeSonnet4
             | Self::ClaudeSonnet4Thinking
             | Self::ClaudeOpus4
-            | Self::ClaudeOpus4Thinking => Some(BedrockModelCacheConfiguration {
+            | Self::ClaudeOpus4Thinking
+            | Self::ClaudeOpus4_1
+            | Self::ClaudeOpus4_1Thinking => Some(BedrockModelCacheConfiguration {
                 max_cache_anchors: 4,
                 min_total_token: 1024,
             }),
@@ -467,9 +493,11 @@ impl Model {
             Model::ClaudeSonnet4Thinking => BedrockModelMode::Thinking {
                 budget_tokens: Some(4096),
             },
-            Model::ClaudeOpus4Thinking => BedrockModelMode::Thinking {
-                budget_tokens: Some(4096),
-            },
+            Model::ClaudeOpus4Thinking | Model::ClaudeOpus4_1Thinking => {
+                BedrockModelMode::Thinking {
+                    budget_tokens: Some(4096),
+                }
+            }
             _ => BedrockModelMode::Default,
         }
     }
@@ -518,6 +546,8 @@ impl Model {
                 | Model::ClaudeSonnet4Thinking
                 | Model::ClaudeOpus4
                 | Model::ClaudeOpus4Thinking
+                | Model::ClaudeOpus4_1
+                | Model::ClaudeOpus4_1Thinking
                 | Model::Claude3Haiku
                 | Model::Claude3Opus
                 | Model::Claude3Sonnet