use serde::Serialize;
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum ApiProvider {
FirstParty,
Bedrock,
Vertex,
Foundry,
}
#[derive(Debug, Clone)]
pub struct DeprecatedModelInfo {
pub model_name: String,
pub retirement_date: String,
}
struct DeprecationEntry {
model_name: String,
retirement_dates: HashMap<ApiProvider, Option<String>>,
}
fn deprecated_models() -> HashMap<&'static str, DeprecationEntry> {
HashMap::from([
(
"claude-3-opus",
DeprecationEntry {
model_name: "Claude 3 Opus".to_string(),
retirement_dates: HashMap::from([
(ApiProvider::FirstParty, Some("January 5, 2026".to_string())),
(ApiProvider::Bedrock, Some("January 15, 2026".to_string())),
(ApiProvider::Vertex, Some("January 5, 2026".to_string())),
(ApiProvider::Foundry, Some("January 5, 2026".to_string())),
]),
},
),
(
"claude-3-7-sonnet",
DeprecationEntry {
model_name: "Claude 3.7 Sonnet".to_string(),
retirement_dates: HashMap::from([
(ApiProvider::FirstParty, Some("February 19, 2026".to_string())),
(ApiProvider::Bedrock, Some("April 28, 2026".to_string())),
(ApiProvider::Vertex, Some("May 11, 2026".to_string())),
(ApiProvider::Foundry, Some("February 19, 2026".to_string())),
]),
},
),
(
"claude-3-5-haiku",
DeprecationEntry {
model_name: "Claude 3.5 Haiku".to_string(),
retirement_dates: HashMap::from([
(ApiProvider::FirstParty, Some("February 19, 2026".to_string())),
(ApiProvider::Bedrock, None),
(ApiProvider::Vertex, None),
(ApiProvider::Foundry, None),
]),
},
),
])
}
fn get_deprecated_model_info(model_id: &str) -> Option<DeprecatedModelInfo> {
let lowercase_model_id = model_id.to_lowercase();
let provider = get_api_provider();
for (key, entry) in deprecated_models() {
let retirement_date = entry.retirement_dates.get(&provider)?.clone()?;
if lowercase_model_id.contains(key) {
return Some(DeprecatedModelInfo {
model_name: entry.model_name,
retirement_date,
});
}
}
None
}
fn get_api_provider() -> ApiProvider {
if std::env::var("AI_CODE_USE_BEDROCK").is_ok() {
return ApiProvider::Bedrock;
}
if std::env::var("AI_CODE_USE_VERTEX").is_ok() {
return ApiProvider::Vertex;
}
if std::env::var("AI_CODE_USE_FOUNDRY").is_ok() {
return ApiProvider::Foundry;
}
ApiProvider::FirstParty
}
pub fn get_model_deprecation_warning(model_id: Option<&str>) -> Option<String> {
let model_id = model_id?;
let info = get_deprecated_model_info(model_id)?;
Some(format!(
"\u{26a0} {} will be retired on {}. Consider switching to a newer model.",
info.model_name, info.retirement_date
))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_model_deprecation_warning_none() {
assert!(get_model_deprecation_warning(None).is_none());
assert!(get_model_deprecation_warning(Some("unknown-model")).is_none());
}
}