use serde::{Deserialize, Serialize};
#[derive(
Debug,
Default,
Clone,
Copy,
Serialize,
Deserialize,
PartialEq,
Eq,
PartialOrd,
Ord,
)]
#[serde(rename_all = "snake_case")]
pub enum Model {
#[serde(rename = "claude-3-5-sonnet-latest")]
Sonnet35,
#[serde(rename = "claude-3-5-sonnet-20240620")]
Sonnet35_20240620,
#[serde(rename = "claude-3-5-sonnet-20241022")]
Sonnet35_20241022,
#[serde(rename = "claude-3-opus-latest")]
Opus30,
#[serde(rename = "claude-3-opus-20240229")]
Opus30_20240229,
#[serde(rename = "claude-3-sonnet-20240229")]
Sonnet30,
#[serde(rename = "claude-3-5-haiku-latest")]
Haiku35,
#[serde(rename = "claude-3-5-haiku-20241022")]
Haiku35_20241022,
#[default]
#[serde(
rename = "claude-3-haiku-20240307",
alias = "claude-3-haiku-latest"
)]
Haiku30,
}
impl Model {
pub const ALL: &'static [Model] = &[
Model::Sonnet35,
Model::Sonnet35_20240620,
Model::Sonnet35_20241022,
Model::Opus30,
Model::Opus30_20240229,
Model::Sonnet30,
Model::Haiku35,
Model::Haiku35_20241022,
Model::Haiku30,
];
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{prompt::message::Role, Client, Prompt};
const CRATE_ROOT: &str = env!("CARGO_MANIFEST_DIR");
fn load_api_key() -> Option<String> {
use std::fs::File;
use std::io::Read;
use std::path::Path;
let mut file =
File::open(Path::new(CRATE_ROOT).join("api.key")).ok()?;
let mut key = String::new();
file.read_to_string(&mut key).unwrap();
Some(key.trim().to_string())
}
#[tokio::test]
#[ignore = "This test requires a real API key."]
async fn test_models_are_valid() {
let key = load_api_key().expect("API key not found");
let client = Client::new(key).unwrap();
let mut prompt = Prompt::default()
.add_message((Role::User, "Respond with just the parrot emoji."));
for &model in Model::ALL {
prompt.model = model;
let response = client.message(&prompt).await.unwrap();
if !serde_json::to_string(&model).unwrap().contains("latest") {
assert_eq!(response.model, model);
}
}
}
}