#[derive(Debug, Clone, PartialEq)]
pub struct Model {
pub name: &'static str,
pub family: &'static str,
pub version: &'static str,
pub anthropic_id: &'static str,
pub bedrock_id: Option<&'static str>,
pub bedrock_global_id: Option<&'static str>,
pub vertex_id: Option<&'static str>,
pub max_context_tokens: u32,
pub max_context_tokens_extended: Option<u32>,
pub max_output_tokens: u32,
pub supports_vision: bool,
pub supports_tools: bool,
pub supports_caching: bool,
pub supports_extended_thinking: bool,
pub supports_effort: bool,
pub cost_per_mtok_input: f64,
pub cost_per_mtok_output: f64,
pub description: &'static str,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BedrockRegion {
Standard,
Global,
US,
EU,
AsiaPacific,
}
impl BedrockRegion {
pub fn prefix(&self) -> &'static str {
match self {
BedrockRegion::Standard => "",
BedrockRegion::Global => "global.",
BedrockRegion::US => "us.",
BedrockRegion::EU => "eu.",
BedrockRegion::AsiaPacific => "ap.",
}
}
}
impl Model {
pub fn anthropic_id(&self) -> &'static str {
self.anthropic_id
}
pub fn bedrock_id(&self) -> Option<&'static str> {
self.bedrock_id
}
pub fn bedrock_id_for_region(&self, region: BedrockRegion) -> Option<String> {
self.bedrock_id.map(|id| {
let prefix = region.prefix();
if prefix.is_empty() {
id.to_string()
} else {
format!("{}{}", prefix, id)
}
})
}
pub fn bedrock_global_id(&self) -> Option<&'static str> {
self.bedrock_global_id
}
pub fn vertex_id(&self) -> Option<&'static str> {
self.vertex_id
}
pub fn supports_extended_context(&self) -> bool {
self.max_context_tokens_extended.is_some()
}
pub fn max_extended_context(&self) -> Option<u32> {
self.max_context_tokens_extended
}
pub fn validate_request(
&self,
max_tokens: u32,
use_extended_context: bool,
) -> Result<(), String> {
if max_tokens > self.max_output_tokens {
return Err(format!(
"Requested max_tokens ({}) exceeds model limit ({})",
max_tokens, self.max_output_tokens
));
}
if use_extended_context && !self.supports_extended_context() {
return Err(format!(
"Model {} does not support extended context",
self.name
));
}
Ok(())
}
pub fn estimate_cost(&self, input_tokens: u32, output_tokens: u32) -> f64 {
(input_tokens as f64 / 1_000_000.0) * self.cost_per_mtok_input
+ (output_tokens as f64 / 1_000_000.0) * self.cost_per_mtok_output
}
}
pub const CLAUDE_SONNET_4_5: Model = Model {
name: "Claude Sonnet 4.5",
family: "sonnet",
version: "2025-09-29",
anthropic_id: "claude-sonnet-4-5-20250929",
bedrock_id: Some("anthropic.claude-sonnet-4-5-20250929-v1:0"),
bedrock_global_id: Some("global.anthropic.claude-sonnet-4-5-20250929-v1:0"),
vertex_id: Some("claude-sonnet-4-5@20250929"),
max_context_tokens: 200_000,
max_context_tokens_extended: Some(1_000_000),
max_output_tokens: 64_000,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: false,
cost_per_mtok_input: 3.0,
cost_per_mtok_output: 15.0,
description: "Smart model for complex agents and coding",
};
pub const CLAUDE_HAIKU_4_5: Model = Model {
name: "Claude Haiku 4.5",
family: "haiku",
version: "2025-10-01",
anthropic_id: "claude-haiku-4-5-20251001",
bedrock_id: Some("anthropic.claude-haiku-4-5-20251001-v1:0"),
bedrock_global_id: Some("global.anthropic.claude-haiku-4-5-20251001-v1:0"),
vertex_id: Some("claude-haiku-4-5@20251001"),
max_context_tokens: 200_000,
max_context_tokens_extended: None,
max_output_tokens: 64_000,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: false,
cost_per_mtok_input: 1.0,
cost_per_mtok_output: 5.0,
description: "Fastest model with near-frontier intelligence",
};
pub const CLAUDE_OPUS_4_5: Model = Model {
name: "Claude Opus 4.5",
family: "opus",
version: "2025-11-01",
anthropic_id: "claude-opus-4-5-20251101",
bedrock_id: Some("anthropic.claude-opus-4-5-20251101-v1:0"),
bedrock_global_id: Some("global.anthropic.claude-opus-4-5-20251101-v1:0"),
vertex_id: Some("claude-opus-4-5@20251101"),
max_context_tokens: 200_000,
max_context_tokens_extended: None,
max_output_tokens: 64_000,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: true, cost_per_mtok_input: 5.0,
cost_per_mtok_output: 25.0,
description: "Maximum intelligence with practical performance",
};
pub const CLAUDE_SONNET_4_6: Model = Model {
name: "Claude Sonnet 4.6",
family: "sonnet",
version: "2026-01-15",
anthropic_id: "claude-sonnet-4-6-20260115",
bedrock_id: Some("anthropic.claude-sonnet-4-6-20260115-v1:0"),
bedrock_global_id: Some("global.anthropic.claude-sonnet-4-6-20260115-v1:0"),
vertex_id: Some("claude-sonnet-4-6@20260115"),
max_context_tokens: 200_000,
max_context_tokens_extended: Some(1_000_000),
max_output_tokens: 64_000,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: false,
cost_per_mtok_input: 3.0,
cost_per_mtok_output: 15.0,
description: "Best balance of speed and intelligence",
};
pub const CLAUDE_OPUS_4_6: Model = Model {
name: "Claude Opus 4.6",
family: "opus",
version: "2026-02-01",
anthropic_id: "claude-opus-4-6-20260201",
bedrock_id: Some("anthropic.claude-opus-4-6-20260201-v1:0"),
bedrock_global_id: Some("global.anthropic.claude-opus-4-6-20260201-v1:0"),
vertex_id: Some("claude-opus-4-6@20260201"),
max_context_tokens: 200_000,
max_context_tokens_extended: None,
max_output_tokens: 64_000,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: true,
cost_per_mtok_input: 5.0,
cost_per_mtok_output: 25.0,
description: "Frontier intelligence for long-running agents and coding",
};
pub const CLAUDE_OPUS_4_7: Model = Model {
name: "Claude Opus 4.7",
family: "opus",
version: "2026-03-01",
anthropic_id: "claude-opus-4-7-20260301",
bedrock_id: Some("anthropic.claude-opus-4-7-20260301-v1:0"),
bedrock_global_id: Some("global.anthropic.claude-opus-4-7-20260301-v1:0"),
vertex_id: Some("claude-opus-4-7@20260301"),
max_context_tokens: 200_000,
max_context_tokens_extended: None,
max_output_tokens: 64_000,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: true,
cost_per_mtok_input: 5.0,
cost_per_mtok_output: 25.0,
description: "Frontier intelligence for long-running agents and coding",
};
pub const CLAUDE_OPUS_4_8: Model = Model {
name: "Claude Opus 4.8",
family: "opus",
version: "2026-04-01",
anthropic_id: "claude-opus-4-8-20260401",
bedrock_id: Some("anthropic.claude-opus-4-8-20260401-v1:0"),
bedrock_global_id: Some("global.anthropic.claude-opus-4-8-20260401-v1:0"),
vertex_id: Some("claude-opus-4-8@20260401"),
max_context_tokens: 200_000,
max_context_tokens_extended: None,
max_output_tokens: 64_000,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: true,
cost_per_mtok_input: 5.0,
cost_per_mtok_output: 25.0,
description: "Frontier intelligence for long-running agents and coding",
};
pub const CLAUDE_FABLE_5: Model = Model {
name: "Claude Fable 5",
family: "fable",
version: "2026-06-01",
anthropic_id: "claude-fable-5-20260601",
bedrock_id: Some("anthropic.claude-fable-5-20260601-v1:0"),
bedrock_global_id: Some("global.anthropic.claude-fable-5-20260601-v1:0"),
vertex_id: Some("claude-fable-5@20260601"),
max_context_tokens: 200_000,
max_context_tokens_extended: Some(1_000_000),
max_output_tokens: 64_000,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: false,
cost_per_mtok_input: 3.0,
cost_per_mtok_output: 15.0,
description: "Next generation for hardest knowledge work and coding",
};
pub const CLAUDE_MYTHOS_5: Model = Model {
name: "Claude Mythos 5",
family: "mythos",
version: "2026-06-15",
anthropic_id: "claude-mythos-5-20260615",
bedrock_id: Some("anthropic.claude-mythos-5-20260615-v1:0"),
bedrock_global_id: Some("global.anthropic.claude-mythos-5-20260615-v1:0"),
vertex_id: Some("claude-mythos-5@20260615"),
max_context_tokens: 200_000,
max_context_tokens_extended: Some(1_000_000),
max_output_tokens: 64_000,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: false,
cost_per_mtok_input: 5.0,
cost_per_mtok_output: 25.0,
description: "Most capable for cybersecurity and biology research",
};
pub const CLAUDE_OPUS_4_1: Model = Model {
name: "Claude Opus 4.1",
family: "opus",
version: "2025-08-05",
anthropic_id: "claude-opus-4-1-20250805",
bedrock_id: Some("anthropic.claude-opus-4-1-20250805-v1:0"),
bedrock_global_id: None,
vertex_id: Some("claude-opus-4-1@20250805"),
max_context_tokens: 200_000,
max_context_tokens_extended: None,
max_output_tokens: 32_000,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: false,
cost_per_mtok_input: 15.0,
cost_per_mtok_output: 75.0,
description: "Previous generation powerful model",
};
pub const CLAUDE_SONNET_4: Model = Model {
name: "Claude Sonnet 4",
family: "sonnet",
version: "2025-05-14",
anthropic_id: "claude-sonnet-4-20250514",
bedrock_id: Some("anthropic.claude-sonnet-4-20250514-v1:0"),
bedrock_global_id: None,
vertex_id: Some("claude-sonnet-4@20250514"),
max_context_tokens: 200_000,
max_context_tokens_extended: Some(1_000_000),
max_output_tokens: 64_000,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: false,
cost_per_mtok_input: 3.0,
cost_per_mtok_output: 15.0,
description: "Previous generation balanced model",
};
pub const CLAUDE_SONNET_3_7: Model = Model {
name: "Claude Sonnet 3.7",
family: "sonnet",
version: "2025-02-19",
anthropic_id: "claude-3-7-sonnet-20250219",
bedrock_id: Some("anthropic.claude-3-7-sonnet-20250219-v1:0"),
bedrock_global_id: None,
vertex_id: Some("claude-3-7-sonnet@20250219"),
max_context_tokens: 200_000,
max_context_tokens_extended: None,
max_output_tokens: 64_000, supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: false,
cost_per_mtok_input: 3.0,
cost_per_mtok_output: 15.0,
description: "Claude 3.7 balanced model",
};
pub const CLAUDE_OPUS_4: Model = Model {
name: "Claude Opus 4",
family: "opus",
version: "2025-05-14",
anthropic_id: "claude-opus-4-20250514",
bedrock_id: Some("anthropic.claude-opus-4-20250514-v1:0"),
bedrock_global_id: None,
vertex_id: Some("claude-opus-4@20250514"),
max_context_tokens: 200_000,
max_context_tokens_extended: None,
max_output_tokens: 32_000,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: true,
supports_effort: false,
cost_per_mtok_input: 15.0,
cost_per_mtok_output: 75.0,
description: "Claude 4 powerful model",
};
pub const CLAUDE_HAIKU_3_5: Model = Model {
name: "Claude Haiku 3.5",
family: "haiku",
version: "2024-10-22",
anthropic_id: "claude-3-5-haiku-20241022",
bedrock_id: Some("anthropic.claude-3-5-haiku-20241022-v1:0"),
bedrock_global_id: None,
vertex_id: Some("claude-3-5-haiku@20241022"),
max_context_tokens: 200_000,
max_context_tokens_extended: None,
max_output_tokens: 8_192,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: false,
supports_effort: false,
cost_per_mtok_input: 0.80,
cost_per_mtok_output: 4.0,
description: "Fast and efficient model",
};
pub const CLAUDE_HAIKU_3: Model = Model {
name: "Claude Haiku 3",
family: "haiku",
version: "2024-03-07",
anthropic_id: "claude-3-haiku-20240307",
bedrock_id: Some("anthropic.claude-3-haiku-20240307-v1:0"),
bedrock_global_id: None,
vertex_id: Some("claude-3-haiku@20240307"),
max_context_tokens: 200_000,
max_context_tokens_extended: None,
max_output_tokens: 4_096,
supports_vision: true,
supports_tools: true,
supports_caching: true,
supports_extended_thinking: false,
supports_effort: false,
cost_per_mtok_input: 0.25,
cost_per_mtok_output: 1.25,
description: "Original fast model",
};
pub const ALL_MODELS: &[&Model] = &[
&CLAUDE_MYTHOS_5,
&CLAUDE_FABLE_5,
&CLAUDE_OPUS_4_8,
&CLAUDE_OPUS_4_7,
&CLAUDE_OPUS_4_6,
&CLAUDE_SONNET_4_6,
&CLAUDE_SONNET_4_5,
&CLAUDE_HAIKU_4_5,
&CLAUDE_OPUS_4_5,
&CLAUDE_OPUS_4_1,
&CLAUDE_SONNET_4,
&CLAUDE_SONNET_3_7,
&CLAUDE_OPUS_4,
&CLAUDE_HAIKU_3_5,
&CLAUDE_HAIKU_3,
];
pub fn get_model_by_anthropic_id(id: &str) -> Option<&'static Model> {
ALL_MODELS.iter().find(|m| m.anthropic_id == id).copied()
}
pub fn get_model_by_bedrock_id(id: &str) -> Option<&'static Model> {
if let Some(model) = ALL_MODELS
.iter()
.find(|m| m.bedrock_id == Some(id) || m.bedrock_global_id == Some(id))
{
return Some(*model);
}
let base_id = id
.strip_prefix("global.")
.or_else(|| id.strip_prefix("us."))
.or_else(|| id.strip_prefix("eu."))
.or_else(|| id.strip_prefix("ap."))
.unwrap_or(id);
ALL_MODELS
.iter()
.find(|m| m.bedrock_id == Some(base_id))
.copied()
}
pub fn get_model_by_vertex_id(id: &str) -> Option<&'static Model> {
ALL_MODELS.iter().find(|m| m.vertex_id == Some(id)).copied()
}
pub fn get_model(id: &str) -> Option<&'static Model> {
get_model_by_anthropic_id(id)
.or_else(|| get_model_by_bedrock_id(id))
.or_else(|| get_model_by_vertex_id(id))
}
#[cfg(test)]
#[allow(clippy::assertions_on_constants)]
mod tests {
use super::*;
#[test]
fn test_model_constants() {
assert_eq!(CLAUDE_SONNET_4_5.anthropic_id, "claude-sonnet-4-5-20250929");
assert_eq!(
CLAUDE_SONNET_4_5.bedrock_id,
Some("anthropic.claude-sonnet-4-5-20250929-v1:0")
);
assert_eq!(
CLAUDE_SONNET_4_5.bedrock_global_id,
Some("global.anthropic.claude-sonnet-4-5-20250929-v1:0")
);
assert_eq!(
CLAUDE_SONNET_4_5.max_context_tokens_extended,
Some(1_000_000)
);
}
#[test]
fn test_model_lookup_anthropic() {
let model = get_model_by_anthropic_id("claude-sonnet-4-5-20250929");
assert!(model.is_some());
assert_eq!(model.unwrap().name, "Claude Sonnet 4.5");
}
#[test]
fn test_model_lookup_bedrock_regional() {
let model = get_model_by_bedrock_id("anthropic.claude-sonnet-4-5-20250929-v1:0");
assert!(model.is_some());
assert_eq!(model.unwrap().name, "Claude Sonnet 4.5");
}
#[test]
fn test_model_lookup_bedrock_global() {
let model = get_model_by_bedrock_id("global.anthropic.claude-sonnet-4-5-20250929-v1:0");
assert!(model.is_some());
assert_eq!(model.unwrap().name, "Claude Sonnet 4.5");
}
#[test]
fn test_model_lookup_bedrock_us() {
let model = get_model_by_bedrock_id("us.anthropic.claude-sonnet-4-5-20250929-v1:0");
assert!(model.is_some());
assert_eq!(model.unwrap().name, "Claude Sonnet 4.5");
}
#[test]
fn test_model_lookup_bedrock_eu() {
let model = get_model_by_bedrock_id("eu.anthropic.claude-sonnet-4-5-20250929-v1:0");
assert!(model.is_some());
assert_eq!(model.unwrap().name, "Claude Sonnet 4.5");
}
#[test]
fn test_model_lookup_bedrock_ap() {
let model = get_model_by_bedrock_id("ap.anthropic.claude-sonnet-4-5-20250929-v1:0");
assert!(model.is_some());
assert_eq!(model.unwrap().name, "Claude Sonnet 4.5");
}
#[test]
fn test_bedrock_id_for_region() {
let regional = CLAUDE_SONNET_4_5.bedrock_id_for_region(BedrockRegion::Standard);
assert_eq!(
regional.as_deref(),
Some("anthropic.claude-sonnet-4-5-20250929-v1:0")
);
let global = CLAUDE_SONNET_4_5.bedrock_id_for_region(BedrockRegion::Global);
assert_eq!(
global.as_deref(),
Some("global.anthropic.claude-sonnet-4-5-20250929-v1:0")
);
let us = CLAUDE_SONNET_4_5.bedrock_id_for_region(BedrockRegion::US);
assert_eq!(
us.as_deref(),
Some("us.anthropic.claude-sonnet-4-5-20250929-v1:0")
);
let eu = CLAUDE_SONNET_4_5.bedrock_id_for_region(BedrockRegion::EU);
assert_eq!(
eu.as_deref(),
Some("eu.anthropic.claude-sonnet-4-5-20250929-v1:0")
);
let ap = CLAUDE_SONNET_4_5.bedrock_id_for_region(BedrockRegion::AsiaPacific);
assert_eq!(
ap.as_deref(),
Some("ap.anthropic.claude-sonnet-4-5-20250929-v1:0")
);
}
#[test]
fn test_model_lookup_any() {
assert!(get_model("claude-sonnet-4-5-20250929").is_some());
assert!(get_model("anthropic.claude-sonnet-4-5-20250929-v1:0").is_some());
assert!(get_model("global.anthropic.claude-sonnet-4-5-20250929-v1:0").is_some());
assert!(get_model("us.anthropic.claude-sonnet-4-5-20250929-v1:0").is_some());
assert!(get_model("eu.anthropic.claude-sonnet-4-5-20250929-v1:0").is_some());
assert!(get_model("ap.anthropic.claude-sonnet-4-5-20250929-v1:0").is_some());
}
#[test]
fn test_validate_request() {
assert!(CLAUDE_SONNET_4_5.validate_request(1024, false).is_ok());
assert!(CLAUDE_SONNET_4_5.validate_request(64_000, false).is_ok());
assert!(CLAUDE_SONNET_4_5.validate_request(100_000, false).is_err());
assert!(CLAUDE_SONNET_4_5.validate_request(1024, true).is_ok());
assert!(CLAUDE_HAIKU_4_5.validate_request(1024, true).is_err()); }
#[test]
fn test_extended_context_support() {
assert!(CLAUDE_SONNET_4_5.supports_extended_context());
assert_eq!(CLAUDE_SONNET_4_5.max_extended_context(), Some(1_000_000));
assert!(CLAUDE_SONNET_4.supports_extended_context());
assert!(!CLAUDE_HAIKU_4_5.supports_extended_context());
assert_eq!(CLAUDE_HAIKU_4_5.max_extended_context(), None);
assert!(!CLAUDE_OPUS_4_5.supports_extended_context());
}
#[test]
fn test_bedrock_global_endpoints() {
assert!(CLAUDE_SONNET_4_5.bedrock_global_id().is_some());
assert!(CLAUDE_HAIKU_4_5.bedrock_global_id().is_some());
assert!(CLAUDE_OPUS_4_5.bedrock_global_id().is_some());
assert!(CLAUDE_SONNET_4.bedrock_global_id().is_none());
assert!(CLAUDE_HAIKU_3_5.bedrock_global_id().is_none());
}
#[test]
fn test_estimate_cost() {
let cost = CLAUDE_SONNET_4_5.estimate_cost(1000, 500);
assert!((cost - 0.0105).abs() < 0.0001);
}
#[test]
fn test_all_models_have_unique_ids() {
let mut ids = std::collections::HashSet::new();
for model in ALL_MODELS {
assert!(ids.insert(model.anthropic_id));
}
}
#[test]
fn test_claude_sonnet_4_6_exists() {
assert_eq!(CLAUDE_SONNET_4_6.name, "Claude Sonnet 4.6");
assert_eq!(CLAUDE_SONNET_4_6.family, "sonnet");
assert_eq!(CLAUDE_SONNET_4_6.anthropic_id, "claude-sonnet-4-6-20260115");
assert!(CLAUDE_SONNET_4_6.supports_vision);
assert!(CLAUDE_SONNET_4_6.supports_tools);
assert!(CLAUDE_SONNET_4_6.supports_caching);
assert!(CLAUDE_SONNET_4_6.supports_extended_thinking);
assert!(!CLAUDE_SONNET_4_6.supports_effort);
assert!(CLAUDE_SONNET_4_6.bedrock_global_id.is_some());
}
#[test]
fn test_claude_sonnet_4_6_lookup() {
let model = get_model_by_anthropic_id("claude-sonnet-4-6-20260115");
assert!(model.is_some());
assert_eq!(model.unwrap().name, "Claude Sonnet 4.6");
let model = get_model("claude-sonnet-4-6-20260115");
assert!(model.is_some());
}
#[test]
fn test_claude_opus_4_6_exists() {
assert_eq!(CLAUDE_OPUS_4_6.name, "Claude Opus 4.6");
assert_eq!(CLAUDE_OPUS_4_6.family, "opus");
assert_eq!(CLAUDE_OPUS_4_6.anthropic_id, "claude-opus-4-6-20260201");
assert!(CLAUDE_OPUS_4_6.supports_vision);
assert!(CLAUDE_OPUS_4_6.supports_tools);
assert!(CLAUDE_OPUS_4_6.supports_caching);
assert!(CLAUDE_OPUS_4_6.supports_extended_thinking);
assert!(CLAUDE_OPUS_4_6.supports_effort);
assert!(CLAUDE_OPUS_4_6.bedrock_global_id.is_some());
}
#[test]
fn test_claude_opus_4_6_lookup() {
let model = get_model_by_anthropic_id("claude-opus-4-6-20260201");
assert!(model.is_some());
assert_eq!(model.unwrap().name, "Claude Opus 4.6");
let model = get_model("claude-opus-4-6-20260201");
assert!(model.is_some());
}
#[test]
fn test_claude_opus_4_7_exists() {
assert_eq!(CLAUDE_OPUS_4_7.name, "Claude Opus 4.7");
assert_eq!(CLAUDE_OPUS_4_7.family, "opus");
assert_eq!(CLAUDE_OPUS_4_7.anthropic_id, "claude-opus-4-7-20260301");
assert!(CLAUDE_OPUS_4_7.supports_vision);
assert!(CLAUDE_OPUS_4_7.supports_tools);
assert!(CLAUDE_OPUS_4_7.supports_caching);
assert!(CLAUDE_OPUS_4_7.supports_extended_thinking);
assert!(CLAUDE_OPUS_4_7.supports_effort);
assert!(CLAUDE_OPUS_4_7.bedrock_global_id.is_some());
}
#[test]
fn test_claude_opus_4_7_lookup() {
let model = get_model_by_anthropic_id("claude-opus-4-7-20260301");
assert!(model.is_some());
assert_eq!(model.unwrap().name, "Claude Opus 4.7");
let model = get_model("claude-opus-4-7-20260301");
assert!(model.is_some());
}
#[test]
fn test_claude_opus_4_8_exists() {
assert_eq!(CLAUDE_OPUS_4_8.name, "Claude Opus 4.8");
assert_eq!(CLAUDE_OPUS_4_8.family, "opus");
assert_eq!(CLAUDE_OPUS_4_8.anthropic_id, "claude-opus-4-8-20260401");
assert!(CLAUDE_OPUS_4_8.supports_vision);
assert!(CLAUDE_OPUS_4_8.supports_tools);
assert!(CLAUDE_OPUS_4_8.supports_caching);
assert!(CLAUDE_OPUS_4_8.supports_extended_thinking);
assert!(CLAUDE_OPUS_4_8.supports_effort);
assert!(CLAUDE_OPUS_4_8.bedrock_global_id.is_some());
}
#[test]
fn test_claude_opus_4_8_lookup() {
let model = get_model_by_anthropic_id("claude-opus-4-8-20260401");
assert!(model.is_some());
assert_eq!(model.unwrap().name, "Claude Opus 4.8");
let model = get_model("claude-opus-4-8-20260401");
assert!(model.is_some());
}
#[test]
fn test_claude_fable_5_exists() {
assert_eq!(CLAUDE_FABLE_5.name, "Claude Fable 5");
assert_eq!(CLAUDE_FABLE_5.family, "fable");
assert_eq!(CLAUDE_FABLE_5.anthropic_id, "claude-fable-5-20260601");
assert!(CLAUDE_FABLE_5.supports_vision);
assert!(CLAUDE_FABLE_5.supports_tools);
assert!(CLAUDE_FABLE_5.supports_caching);
assert!(CLAUDE_FABLE_5.supports_extended_thinking);
assert!(!CLAUDE_FABLE_5.supports_effort);
assert!(CLAUDE_FABLE_5.bedrock_global_id.is_some());
assert_eq!(CLAUDE_FABLE_5.max_context_tokens_extended, Some(1_000_000));
}
#[test]
fn test_claude_fable_5_lookup() {
let model = get_model_by_anthropic_id("claude-fable-5-20260601");
assert!(model.is_some());
assert_eq!(model.unwrap().name, "Claude Fable 5");
let model = get_model("claude-fable-5-20260601");
assert!(model.is_some());
}
#[test]
fn test_claude_mythos_5_exists() {
assert_eq!(CLAUDE_MYTHOS_5.name, "Claude Mythos 5");
assert_eq!(CLAUDE_MYTHOS_5.family, "mythos");
assert_eq!(CLAUDE_MYTHOS_5.anthropic_id, "claude-mythos-5-20260615");
assert!(CLAUDE_MYTHOS_5.supports_vision);
assert!(CLAUDE_MYTHOS_5.supports_tools);
assert!(CLAUDE_MYTHOS_5.supports_caching);
assert!(CLAUDE_MYTHOS_5.supports_extended_thinking);
assert!(!CLAUDE_MYTHOS_5.supports_effort);
assert!(CLAUDE_MYTHOS_5.bedrock_global_id.is_some());
assert_eq!(CLAUDE_MYTHOS_5.max_context_tokens_extended, Some(1_000_000));
}
#[test]
fn test_claude_mythos_5_lookup() {
let model = get_model_by_anthropic_id("claude-mythos-5-20260615");
assert!(model.is_some());
assert_eq!(model.unwrap().name, "Claude Mythos 5");
let model = get_model("claude-mythos-5-20260615");
assert!(model.is_some());
}
#[test]
fn test_new_models_in_all_models() {
let ids: Vec<&str> = ALL_MODELS.iter().map(|m| m.anthropic_id).collect();
assert!(ids.contains(&"claude-sonnet-4-6-20260115"));
assert!(ids.contains(&"claude-opus-4-6-20260201"));
assert!(ids.contains(&"claude-opus-4-7-20260301"));
assert!(ids.contains(&"claude-opus-4-8-20260401"));
assert!(ids.contains(&"claude-fable-5-20260601"));
assert!(ids.contains(&"claude-mythos-5-20260615"));
}
#[test]
fn test_new_models_bedrock_global_ids() {
assert!(CLAUDE_SONNET_4_6.bedrock_global_id().is_some());
assert!(CLAUDE_OPUS_4_6.bedrock_global_id().is_some());
assert!(CLAUDE_OPUS_4_7.bedrock_global_id().is_some());
assert!(CLAUDE_OPUS_4_8.bedrock_global_id().is_some());
assert!(CLAUDE_FABLE_5.bedrock_global_id().is_some());
assert!(CLAUDE_MYTHOS_5.bedrock_global_id().is_some());
}
}