use super::{
DEFAULT_ARCEE_BASE_URL, DEFAULT_ARCEE_MODEL, DEFAULT_ATLASCLOUD_BASE_URL,
DEFAULT_ATLASCLOUD_MODEL, DEFAULT_DEEPSEEK_BASE_URL, DEFAULT_DEEPSEEK_MODEL,
DEFAULT_FIREWORKS_BASE_URL, DEFAULT_FIREWORKS_MODEL, DEFAULT_HUGGINGFACE_BASE_URL,
DEFAULT_HUGGINGFACE_MODEL, DEFAULT_MOONSHOT_BASE_URL, DEFAULT_MOONSHOT_MODEL,
DEFAULT_NOVITA_BASE_URL, DEFAULT_NOVITA_MODEL, DEFAULT_NVIDIA_NIM_BASE_URL,
DEFAULT_NVIDIA_NIM_MODEL, DEFAULT_OLLAMA_BASE_URL, DEFAULT_OLLAMA_MODEL,
DEFAULT_OPENAI_BASE_URL, DEFAULT_OPENAI_MODEL, DEFAULT_OPENROUTER_BASE_URL,
DEFAULT_OPENROUTER_MODEL, DEFAULT_SGLANG_BASE_URL, DEFAULT_SGLANG_MODEL,
DEFAULT_SILICONFLOW_BASE_URL, DEFAULT_SILICONFLOW_CN_BASE_URL, DEFAULT_SILICONFLOW_MODEL,
DEFAULT_VLLM_BASE_URL, DEFAULT_VLLM_MODEL, DEFAULT_VOLCENGINE_BASE_URL,
DEFAULT_VOLCENGINE_MODEL, DEFAULT_WANJIE_ARK_BASE_URL, DEFAULT_WANJIE_ARK_MODEL,
DEFAULT_XIAOMI_MIMO_BASE_URL, DEFAULT_XIAOMI_MIMO_MODEL, ProviderKind,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WireFormat {
ChatCompletions,
}
pub trait Provider: Send + Sync {
fn kind(&self) -> ProviderKind;
fn id(&self) -> &'static str {
self.kind().as_str()
}
fn display_name(&self) -> &'static str;
fn default_base_url(&self) -> &'static str;
fn default_model(&self) -> &'static str;
fn env_vars(&self) -> &'static [&'static str];
fn provider_config_key(&self) -> &'static str;
fn wire(&self) -> WireFormat {
WireFormat::ChatCompletions
}
}
macro_rules! provider {
(
$struct_name:ident,
$kind:ident,
$display_name:literal,
$base_url:ident,
$model:ident,
[$($env_var:literal),* $(,)?],
$config_key:literal
) => {
pub struct $struct_name;
impl Provider for $struct_name {
fn kind(&self) -> ProviderKind {
ProviderKind::$kind
}
fn display_name(&self) -> &'static str {
$display_name
}
fn default_base_url(&self) -> &'static str {
$base_url
}
fn default_model(&self) -> &'static str {
$model
}
fn env_vars(&self) -> &'static [&'static str] {
&[$($env_var),*]
}
fn provider_config_key(&self) -> &'static str {
$config_key
}
}
};
}
provider!(
Deepseek,
Deepseek,
"DeepSeek",
DEFAULT_DEEPSEEK_BASE_URL,
DEFAULT_DEEPSEEK_MODEL,
["DEEPSEEK_API_KEY"],
"deepseek"
);
provider!(
NvidiaNim,
NvidiaNim,
"NVIDIA NIM",
DEFAULT_NVIDIA_NIM_BASE_URL,
DEFAULT_NVIDIA_NIM_MODEL,
["NVIDIA_API_KEY", "NVIDIA_NIM_API_KEY", "DEEPSEEK_API_KEY"],
"nvidia_nim"
);
provider!(
Openai,
Openai,
"OpenAI-compatible",
DEFAULT_OPENAI_BASE_URL,
DEFAULT_OPENAI_MODEL,
["OPENAI_API_KEY"],
"openai"
);
provider!(
Atlascloud,
Atlascloud,
"AtlasCloud",
DEFAULT_ATLASCLOUD_BASE_URL,
DEFAULT_ATLASCLOUD_MODEL,
["ATLASCLOUD_API_KEY"],
"atlascloud"
);
provider!(
WanjieArk,
WanjieArk,
"Wanjie Ark",
DEFAULT_WANJIE_ARK_BASE_URL,
DEFAULT_WANJIE_ARK_MODEL,
[
"WANJIE_ARK_API_KEY",
"WANJIE_API_KEY",
"WANJIE_MAAS_API_KEY"
],
"wanjie_ark"
);
provider!(
Volcengine,
Volcengine,
"Volcengine Ark",
DEFAULT_VOLCENGINE_BASE_URL,
DEFAULT_VOLCENGINE_MODEL,
[
"VOLCENGINE_API_KEY",
"VOLCENGINE_ARK_API_KEY",
"ARK_API_KEY"
],
"volcengine"
);
provider!(
Openrouter,
Openrouter,
"OpenRouter",
DEFAULT_OPENROUTER_BASE_URL,
DEFAULT_OPENROUTER_MODEL,
["OPENROUTER_API_KEY"],
"openrouter"
);
provider!(
XiaomiMimo,
XiaomiMimo,
"Xiaomi MiMo",
DEFAULT_XIAOMI_MIMO_BASE_URL,
DEFAULT_XIAOMI_MIMO_MODEL,
[
"XIAOMI_MIMO_TOKEN_PLAN_API_KEY",
"MIMO_TOKEN_PLAN_API_KEY",
"XIAOMI_MIMO_API_KEY",
"XIAOMI_API_KEY",
"MIMO_API_KEY",
],
"xiaomi_mimo"
);
provider!(
Novita,
Novita,
"Novita",
DEFAULT_NOVITA_BASE_URL,
DEFAULT_NOVITA_MODEL,
["NOVITA_API_KEY"],
"novita"
);
provider!(
Fireworks,
Fireworks,
"Fireworks",
DEFAULT_FIREWORKS_BASE_URL,
DEFAULT_FIREWORKS_MODEL,
["FIREWORKS_API_KEY"],
"fireworks"
);
provider!(
Siliconflow,
Siliconflow,
"SiliconFlow",
DEFAULT_SILICONFLOW_BASE_URL,
DEFAULT_SILICONFLOW_MODEL,
["SILICONFLOW_API_KEY"],
"siliconflow"
);
provider!(
SiliconflowCN,
SiliconflowCN,
"SiliconFlow CN",
DEFAULT_SILICONFLOW_CN_BASE_URL,
DEFAULT_SILICONFLOW_MODEL,
["SILICONFLOW_API_KEY"],
"siliconflow"
);
provider!(
Arcee,
Arcee,
"Arcee",
DEFAULT_ARCEE_BASE_URL,
DEFAULT_ARCEE_MODEL,
["ARCEE_API_KEY"],
"arcee"
);
provider!(
Moonshot,
Moonshot,
"Moonshot",
DEFAULT_MOONSHOT_BASE_URL,
DEFAULT_MOONSHOT_MODEL,
["MOONSHOT_API_KEY", "KIMI_API_KEY"],
"moonshot"
);
provider!(
Sglang,
Sglang,
"SGLang",
DEFAULT_SGLANG_BASE_URL,
DEFAULT_SGLANG_MODEL,
["SGLANG_API_KEY"],
"sglang"
);
provider!(
Vllm,
Vllm,
"vLLM",
DEFAULT_VLLM_BASE_URL,
DEFAULT_VLLM_MODEL,
["VLLM_API_KEY"],
"vllm"
);
provider!(
Ollama,
Ollama,
"Ollama",
DEFAULT_OLLAMA_BASE_URL,
DEFAULT_OLLAMA_MODEL,
["OLLAMA_API_KEY"],
"ollama"
);
provider!(
Huggingface,
Huggingface,
"Hugging Face",
DEFAULT_HUGGINGFACE_BASE_URL,
DEFAULT_HUGGINGFACE_MODEL,
["HUGGINGFACE_API_KEY", "HF_TOKEN"],
"huggingface"
);
static DEEPSEEK: Deepseek = Deepseek;
static NVIDIA_NIM: NvidiaNim = NvidiaNim;
static OPENAI: Openai = Openai;
static ATLASCLOUD: Atlascloud = Atlascloud;
static WANJIE_ARK: WanjieArk = WanjieArk;
static VOLCENGINE: Volcengine = Volcengine;
static OPENROUTER: Openrouter = Openrouter;
static XIAOMI_MIMO: XiaomiMimo = XiaomiMimo;
static NOVITA: Novita = Novita;
static FIREWORKS: Fireworks = Fireworks;
static SILICONFLOW: Siliconflow = Siliconflow;
static SILICONFLOW_CN: SiliconflowCN = SiliconflowCN;
static ARCEE: Arcee = Arcee;
static MOONSHOT: Moonshot = Moonshot;
static SGLANG: Sglang = Sglang;
static VLLM: Vllm = Vllm;
static OLLAMA: Ollama = Ollama;
static HUGGINGFACE: Huggingface = Huggingface;
static PROVIDER_REGISTRY: [&dyn Provider; 18] = [
&DEEPSEEK,
&NVIDIA_NIM,
&OPENAI,
&ATLASCLOUD,
&WANJIE_ARK,
&VOLCENGINE,
&OPENROUTER,
&XIAOMI_MIMO,
&NOVITA,
&FIREWORKS,
&SILICONFLOW,
&SILICONFLOW_CN,
&ARCEE,
&MOONSHOT,
&SGLANG,
&VLLM,
&OLLAMA,
&HUGGINGFACE,
];
#[must_use]
pub fn all_providers() -> &'static [&'static dyn Provider] {
&PROVIDER_REGISTRY
}
#[must_use]
pub fn lookup_provider(id: &str) -> Option<&'static dyn Provider> {
let id = id.trim();
all_providers()
.iter()
.copied()
.find(|provider| provider.id() == id)
}
#[must_use]
pub fn resolve_provider(id_or_alias: &str) -> Option<&'static dyn Provider> {
ProviderKind::parse(id_or_alias).map(provider_for_kind)
}
#[must_use]
pub fn provider_for_kind(kind: ProviderKind) -> &'static dyn Provider {
match kind {
ProviderKind::Deepseek => &DEEPSEEK,
ProviderKind::NvidiaNim => &NVIDIA_NIM,
ProviderKind::Openai => &OPENAI,
ProviderKind::Atlascloud => &ATLASCLOUD,
ProviderKind::WanjieArk => &WANJIE_ARK,
ProviderKind::Volcengine => &VOLCENGINE,
ProviderKind::Openrouter => &OPENROUTER,
ProviderKind::XiaomiMimo => &XIAOMI_MIMO,
ProviderKind::Novita => &NOVITA,
ProviderKind::Fireworks => &FIREWORKS,
ProviderKind::Siliconflow => &SILICONFLOW,
ProviderKind::SiliconflowCN => &SILICONFLOW_CN,
ProviderKind::Arcee => &ARCEE,
ProviderKind::Moonshot => &MOONSHOT,
ProviderKind::Sglang => &SGLANG,
ProviderKind::Vllm => &VLLM,
ProviderKind::Ollama => &OLLAMA,
ProviderKind::Huggingface => &HUGGINGFACE,
}
}