use std::fmt;
pub trait ModelInfo: Send + Sync + fmt::Debug + Clone + Copy {
fn context_window(&self) -> usize;
fn max_output_tokens(&self) -> usize;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Sonnet35Version {
V1,
V2,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Claude {
Sonnet35 { version: Sonnet35Version },
Sonnet37 { use_extended_thinking: bool },
Haiku35,
Haiku3,
Opus3,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Ollama {
Llama3 { size: OllamaModelSize },
Llava,
Mistral { size: OllamaModelSize },
Custom { name: &'static str },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OllamaModelSize {
_8B,
_7B,
_3B,
_1B,
}
impl Default for Claude {
fn default() -> Self {
Self::Opus3
}
}
impl ModelInfo for Claude {
fn context_window(&self) -> usize {
200_000
}
fn max_output_tokens(&self) -> usize {
match self {
Self::Sonnet37 {
use_extended_thinking: _,
} => 64_000,
Self::Sonnet35 { version: _ } | Self::Haiku35 => 8192,
Self::Haiku3 | Self::Opus3 => 4096,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Gemini {
Flash15,
Flash20,
Flash20Lite,
Flash25Preview,
}
impl ModelInfo for Gemini {
fn context_window(&self) -> usize {
1_048_576
}
fn max_output_tokens(&self) -> usize {
match self {
Self::Flash15 | Self::Flash20 | Self::Flash20Lite => 8_192,
Self::Flash25Preview => 65_536,
}
}
}
impl crate::provider::gemini::GeminiModelInfo for Gemini {
fn gemini_model_id(&self) -> String {
match self {
Self::Flash15 => "gemini-1.5-flash",
Self::Flash20 => "gemini-2.0-flash",
Self::Flash20Lite => "gemini-2.0-flash-lite",
Self::Flash25Preview => "gemini-2.5-flash-preview-04-17",
}
.to_string()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OpenAi {
GPT4o,
GPT4oMini,
GPT4Turbo,
GPT35Turbo,
O1,
O1Mini,
O1Pro,
O3,
O3Mini,
O4Mini,
}
impl ModelInfo for OpenAi {
fn context_window(&self) -> usize {
match self {
Self::O1Mini | Self::GPT4o | Self::GPT4oMini | Self::GPT4Turbo => 128_000,
Self::GPT35Turbo => 16_000,
_ => 200_000,
}
}
fn max_output_tokens(&self) -> usize {
match self {
Self::GPT4o | Self::GPT4oMini | Self::GPT4Turbo | Self::GPT35Turbo => 4_096,
Self::O1Mini => 65_536,
_ => 100_000,
}
}
}
impl crate::provider::openai::OpenAIModelInfo for OpenAi {
fn openai_model_id(&self) -> String {
match self {
Self::GPT4o => "gpt-4o",
Self::GPT4oMini => "gpt-4o-mini",
Self::GPT4Turbo => "gpt-4-turbo",
Self::GPT35Turbo => "gpt-3.5-turbo",
Self::O4Mini => "o4-mini-2025-04-16",
Self::O3 => "o3-2025-04-16",
Self::O3Mini => "o3-mini-2025-01-31",
Self::O1 => "o1-2024-12-17",
Self::O1Mini => "o1-mini-2024-09-12",
Self::O1Pro => "o1-pro-2025-03-19",
}
.to_string()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Mistral {
Large,
Small,
Nemo,
Codestral,
Embed,
}
impl ModelInfo for Mistral {
fn context_window(&self) -> usize {
match self {
Self::Large | Self::Small | Self::Nemo => 131_072, Self::Codestral => 262_144, Self::Embed => 8_192, }
}
fn max_output_tokens(&self) -> usize {
4_096
}
}
impl crate::provider::mistral::MistralModelInfo for Mistral {
fn mistral_model_id(&self) -> String {
match self {
Self::Large => "mistral-large-latest",
Self::Small => "mistral-small-latest",
Self::Nemo => "open-mistral-nemo",
Self::Codestral => "codestral-latest",
Self::Embed => "mistral-embed",
}
.to_string()
}
}
impl Default for Ollama {
fn default() -> Self {
Self::Llama3 { size: OllamaModelSize::_7B }
}
}
impl ModelInfo for Ollama {
fn context_window(&self) -> usize {
match self {
Self::Llama3 { size } => match size {
OllamaModelSize::_8B => 32_768,
OllamaModelSize::_7B => 32_768,
OllamaModelSize::_3B => 16_384,
OllamaModelSize::_1B => 8_192,
},
Self::Llava => 8_192,
Self::Mistral { size } => match size {
OllamaModelSize::_8B => 32_768,
OllamaModelSize::_7B => 16_384,
OllamaModelSize::_3B => 8_192,
OllamaModelSize::_1B => 4_096,
},
Self::Custom { .. } => 8_192, }
}
fn max_output_tokens(&self) -> usize {
match self {
Self::Llama3 { .. } => 4_096,
Self::Llava => 4_096,
Self::Mistral { .. } => 4_096,
Self::Custom { .. } => 4_096, }
}
}