@@ -39,21 +39,33 @@ pub async fn stream_completion(
.model_id(request.model.clone())
.set_messages(request.messages.into());
- if let Some(Thinking::Enabled {
- budget_tokens: Some(budget_tokens),
- }) = request.thinking
- {
- let thinking_config = HashMap::from([
- ("type".to_string(), Document::String("enabled".to_string())),
- (
- "budget_tokens".to_string(),
- Document::Number(AwsNumber::PosInt(budget_tokens)),
- ),
- ]);
- response = response.additional_model_request_fields(Document::Object(HashMap::from([(
- "thinking".to_string(),
- Document::from(thinking_config),
- )])));
+ match request.thinking {
+ Some(Thinking::Enabled {
+ budget_tokens: Some(budget_tokens),
+ }) => {
+ let thinking_config = HashMap::from([
+ ("type".to_string(), Document::String("enabled".to_string())),
+ (
+ "budget_tokens".to_string(),
+ Document::Number(AwsNumber::PosInt(budget_tokens)),
+ ),
+ ]);
+ response =
+ response.additional_model_request_fields(Document::Object(HashMap::from([(
+ "thinking".to_string(),
+ Document::from(thinking_config),
+ )])));
+ }
+ Some(Thinking::Adaptive { effort: _ }) => {
+ let thinking_config =
+ HashMap::from([("type".to_string(), Document::String("adaptive".to_string()))]);
+ response =
+ response.additional_model_request_fields(Document::Object(HashMap::from([(
+ "thinking".to_string(),
+ Document::from(thinking_config),
+ )])));
+ }
+ _ => {}
}
if request.tools.as_ref().is_some_and(|t| !t.tools.is_empty()) {
@@ -145,7 +157,12 @@ pub fn value_to_aws_document(value: &Value) -> Document {
#[derive(Debug, Serialize, Deserialize)]
pub enum Thinking {
- Enabled { budget_tokens: Option<u64> },
+ Enabled {
+ budget_tokens: Option<u64>,
+ },
+ Adaptive {
+ effort: BedrockAdaptiveThinkingEffort,
+ },
}
#[derive(Debug)]
@@ -1,6 +1,27 @@
use serde::{Deserialize, Serialize};
use strum::EnumIter;
+#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
+#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq)]
+pub enum BedrockAdaptiveThinkingEffort {
+ Low,
+ Medium,
+ #[default]
+ High,
+ Max,
+}
+
+impl BedrockAdaptiveThinkingEffort {
+ pub fn as_str(&self) -> &'static str {
+ match self {
+ Self::Low => "low",
+ Self::Medium => "medium",
+ Self::High => "high",
+ Self::Max => "max",
+ }
+ }
+}
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
pub enum BedrockModelMode {
@@ -9,6 +30,9 @@ pub enum BedrockModelMode {
Thinking {
budget_tokens: Option<u64>,
},
+ AdaptiveThinking {
+ effort: BedrockAdaptiveThinkingEffort,
+ },
}
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
@@ -58,6 +82,13 @@ pub enum Model {
alias = "claude-opus-4-5-thinking-latest"
)]
ClaudeOpus4_5Thinking,
+ #[serde(rename = "claude-opus-4-6", alias = "claude-opus-4-6-latest")]
+ ClaudeOpus4_6,
+ #[serde(
+ rename = "claude-opus-4-6-thinking",
+ alias = "claude-opus-4-6-thinking-latest"
+ )]
+ ClaudeOpus4_6Thinking,
#[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")]
@@ -148,7 +179,11 @@ impl Model {
}
pub fn from_id(id: &str) -> anyhow::Result<Self> {
- if id.starts_with("claude-opus-4-5-thinking") {
+ if id.starts_with("claude-opus-4-6-thinking") {
+ Ok(Self::ClaudeOpus4_6Thinking)
+ } else if id.starts_with("claude-opus-4-6") {
+ Ok(Self::ClaudeOpus4_6)
+ } else if id.starts_with("claude-opus-4-5-thinking") {
Ok(Self::ClaudeOpus4_5Thinking)
} else if id.starts_with("claude-opus-4-5") {
Ok(Self::ClaudeOpus4_5)
@@ -199,6 +234,8 @@ impl Model {
Model::ClaudeOpus4_1Thinking => "claude-opus-4-1-thinking",
Model::ClaudeOpus4_5 => "claude-opus-4-5",
Model::ClaudeOpus4_5Thinking => "claude-opus-4-5-thinking",
+ Model::ClaudeOpus4_6 => "claude-opus-4-6",
+ Model::ClaudeOpus4_6Thinking => "claude-opus-4-6-thinking",
Model::Claude3_5SonnetV2 => "claude-3-5-sonnet-v2",
Model::Claude3_5Sonnet => "claude-3-5-sonnet",
Model::Claude3Opus => "claude-3-opus",
@@ -269,6 +306,7 @@ impl Model {
Model::ClaudeOpus4_5 | Model::ClaudeOpus4_5Thinking => {
"anthropic.claude-opus-4-5-20251101-v1:0"
}
+ Model::ClaudeOpus4_6 | Model::ClaudeOpus4_6Thinking => "anthropic.claude-opus-4-6-v1",
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",
@@ -335,6 +373,8 @@ impl Model {
Self::ClaudeOpus4_1Thinking => "Claude Opus 4.1 Thinking",
Self::ClaudeOpus4_5 => "Claude Opus 4.5",
Self::ClaudeOpus4_5Thinking => "Claude Opus 4.5 Thinking",
+ Self::ClaudeOpus4_6 => "Claude Opus 4.6",
+ Self::ClaudeOpus4_6Thinking => "Claude Opus 4.6 Thinking",
Self::Claude3_5SonnetV2 => "Claude 3.5 Sonnet v2",
Self::Claude3_5Sonnet => "Claude 3.5 Sonnet",
Self::Claude3Opus => "Claude 3 Opus",
@@ -407,7 +447,9 @@ impl Model {
| Self::ClaudeOpus4Thinking
| Self::ClaudeOpus4_1Thinking
| Self::ClaudeOpus4_5
- | Self::ClaudeOpus4_5Thinking => 200_000,
+ | Self::ClaudeOpus4_5Thinking
+ | Self::ClaudeOpus4_6
+ | Self::ClaudeOpus4_6Thinking => 200_000,
Self::AmazonNovaPremier => 1_000_000,
Self::PalmyraWriterX5 => 1_000_000,
Self::PalmyraWriterX4 => 128_000,
@@ -426,6 +468,7 @@ impl Model {
| Self::ClaudeHaiku4_5
| Self::ClaudeOpus4_5
| Self::ClaudeOpus4_5Thinking => 64_000,
+ Self::ClaudeOpus4_6 | Self::ClaudeOpus4_6Thinking => 128_000,
Self::ClaudeOpus4
| Self::ClaudeOpus4Thinking
| Self::ClaudeOpus4_1
@@ -452,6 +495,8 @@ impl Model {
| Self::ClaudeOpus4_1Thinking
| Self::ClaudeOpus4_5
| Self::ClaudeOpus4_5Thinking
+ | Self::ClaudeOpus4_6
+ | Self::ClaudeOpus4_6Thinking
| Self::ClaudeSonnet4
| Self::ClaudeSonnet4Thinking
| Self::ClaudeSonnet4_5
@@ -479,6 +524,8 @@ impl Model {
| Self::ClaudeOpus4_1Thinking
| Self::ClaudeOpus4_5
| Self::ClaudeOpus4_5Thinking
+ | Self::ClaudeOpus4_6
+ | Self::ClaudeOpus4_6Thinking
| Self::ClaudeSonnet4
| Self::ClaudeSonnet4Thinking
| Self::ClaudeSonnet4_5
@@ -522,7 +569,9 @@ impl Model {
| Self::ClaudeOpus4_1
| Self::ClaudeOpus4_1Thinking
| Self::ClaudeOpus4_5
- | Self::ClaudeOpus4_5Thinking => true,
+ | Self::ClaudeOpus4_5Thinking
+ | Self::ClaudeOpus4_6
+ | Self::ClaudeOpus4_6Thinking => true,
// Custom models - check if they have cache configuration
Self::Custom {
@@ -546,7 +595,9 @@ impl Model {
| Self::ClaudeOpus4_1
| Self::ClaudeOpus4_1Thinking
| Self::ClaudeOpus4_5
- | Self::ClaudeOpus4_5Thinking => Some(BedrockModelCacheConfiguration {
+ | Self::ClaudeOpus4_5Thinking
+ | Self::ClaudeOpus4_6
+ | Self::ClaudeOpus4_6Thinking => Some(BedrockModelCacheConfiguration {
max_cache_anchors: 4,
min_total_token: 1024,
}),
@@ -580,6 +631,9 @@ impl Model {
| Model::ClaudeOpus4_5Thinking => BedrockModelMode::Thinking {
budget_tokens: Some(4096),
},
+ Model::ClaudeOpus4_6Thinking => BedrockModelMode::AdaptiveThinking {
+ effort: BedrockAdaptiveThinkingEffort::default(),
+ },
_ => BedrockModelMode::Default,
}
}
@@ -597,6 +651,8 @@ impl Model {
self,
Model::ClaudeOpus4_5
| Model::ClaudeOpus4_5Thinking
+ | Model::ClaudeOpus4_6
+ | Model::ClaudeOpus4_6Thinking
| Model::ClaudeHaiku4_5
| Model::ClaudeSonnet4
| Model::ClaudeSonnet4Thinking
@@ -637,6 +693,8 @@ impl Model {
(
Model::ClaudeOpus4_5
| Model::ClaudeOpus4_5Thinking
+ | Model::ClaudeOpus4_6
+ | Model::ClaudeOpus4_6Thinking
| Model::ClaudeHaiku4_5
| Model::ClaudeSonnet4
| Model::ClaudeSonnet4Thinking
@@ -694,6 +752,8 @@ impl Model {
| Model::ClaudeOpus4_1Thinking
| Model::ClaudeOpus4_5
| Model::ClaudeOpus4_5Thinking
+ | Model::ClaudeOpus4_6
+ | Model::ClaudeOpus4_6Thinking
| Model::Claude3Haiku
| Model::Claude3Opus
| Model::Claude3Sonnet
@@ -728,6 +788,8 @@ impl Model {
| Model::ClaudeSonnet4
| Model::ClaudeSonnet4_5
| Model::ClaudeSonnet4_5Thinking
+ | Model::ClaudeOpus4_6
+ | Model::ClaudeOpus4_6Thinking
| Model::Claude3Haiku
| Model::Claude3Sonnet
| Model::MetaLlama321BInstructV1
@@ -146,6 +146,9 @@ pub enum ModelMode {
/// The maximum number of tokens to use for reasoning. Must be lower than the model's `max_output_tokens`.
budget_tokens: Option<u64>,
},
+ AdaptiveThinking {
+ effort: bedrock::BedrockAdaptiveThinkingEffort,
+ },
}
impl From<ModelMode> for BedrockModelMode {
@@ -153,6 +156,7 @@ impl From<ModelMode> for BedrockModelMode {
match value {
ModelMode::Default => BedrockModelMode::Default,
ModelMode::Thinking { budget_tokens } => BedrockModelMode::Thinking { budget_tokens },
+ ModelMode::AdaptiveThinking { effort } => BedrockModelMode::AdaptiveThinking { effort },
}
}
}
@@ -162,6 +166,7 @@ impl From<BedrockModelMode> for ModelMode {
match value {
BedrockModelMode::Default => ModelMode::Default,
BedrockModelMode::Thinking { budget_tokens } => ModelMode::Thinking { budget_tokens },
+ BedrockModelMode::AdaptiveThinking { effort } => ModelMode::AdaptiveThinking { effort },
}
}
}
@@ -932,10 +937,16 @@ pub fn into_bedrock(
max_tokens: max_output_tokens,
system: Some(system_message),
tools: Some(tool_config),
- thinking: if request.thinking_allowed
- && let BedrockModelMode::Thinking { budget_tokens } = mode
- {
- Some(bedrock::Thinking::Enabled { budget_tokens })
+ thinking: if request.thinking_allowed {
+ match mode {
+ BedrockModelMode::Thinking { budget_tokens } => {
+ Some(bedrock::Thinking::Enabled { budget_tokens })
+ }
+ BedrockModelMode::AdaptiveThinking { effort } => {
+ Some(bedrock::Thinking::Adaptive { effort })
+ }
+ BedrockModelMode::Default => None,
+ }
} else {
None
},