use serde::{Deserialize, Serialize};
use crate::provider;
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
#[serde(rename_all = "kebab-case")]
pub enum ProviderKind {
#[default]
#[serde(
alias = "deepseek-cn",
alias = "deepseek_china",
alias = "deepseekcn",
alias = "deepseek-china"
)]
Deepseek,
#[serde(
alias = "deepseek-anthropic",
alias = "deepseek_anthropic",
alias = "deepseek-claude",
alias = "deepseek_claude"
)]
DeepseekAnthropic,
NvidiaNim,
#[serde(alias = "open-ai")]
Openai,
Atlascloud,
#[serde(
alias = "wanjie",
alias = "wanjie_ark",
alias = "ark-wanjie",
alias = "ark_wanjie",
alias = "wanjie-maas",
alias = "wanjie_maas"
)]
WanjieArk,
#[serde(alias = "volcengine-ark", alias = "volcengine_ark", alias = "ark")]
Volcengine,
Openrouter,
#[serde(alias = "mimo", alias = "xiaomi", alias = "xiaomi_mimo")]
XiaomiMimo,
Novita,
Fireworks,
#[serde(alias = "silicon-flow", alias = "silicon_flow")]
Siliconflow,
#[serde(alias = "arcee-ai", alias = "arcee_ai")]
Arcee,
#[serde(alias = "siliconflow-cn", alias = "siliconflow-CN")]
SiliconflowCN,
Moonshot,
Sglang,
Vllm,
Ollama,
#[serde(alias = "hugging-face", alias = "hugging_face", alias = "hf")]
Huggingface,
#[serde(alias = "together-ai", alias = "together_ai")]
Together,
#[serde(alias = "baidu-qianfan", alias = "baidu_qianfan", alias = "baidu")]
Qianfan,
#[serde(
alias = "openai-codex",
alias = "openai_codex",
alias = "codex",
alias = "chatgpt",
alias = "chatgpt-codex",
alias = "chatgpt_codex"
)]
OpenaiCodex,
#[serde(alias = "claude")]
Anthropic,
#[serde(
alias = "z-ai",
alias = "z_ai",
alias = "z.ai",
alias = "zhipu",
alias = "zhipuai",
alias = "bigmodel",
alias = "big-model"
)]
Zai,
#[serde(
alias = "step-fun",
alias = "step_fun",
alias = "stepfun",
alias = "stepflash",
alias = "step-flash",
alias = "step_flash"
)]
Stepfun,
#[serde(alias = "mini-max", alias = "mini_max", alias = "minimax")]
Minimax,
#[serde(alias = "deep-infra", alias = "deep_infra")]
Deepinfra,
Custom,
}
impl ProviderKind {
pub const ALL: [Self; 28] = [
Self::Deepseek,
Self::DeepseekAnthropic,
Self::NvidiaNim,
Self::Openai,
Self::Atlascloud,
Self::WanjieArk,
Self::Volcengine,
Self::Openrouter,
Self::XiaomiMimo,
Self::Novita,
Self::Fireworks,
Self::Siliconflow,
Self::Arcee,
Self::SiliconflowCN,
Self::Moonshot,
Self::Sglang,
Self::Vllm,
Self::Ollama,
Self::Huggingface,
Self::Together,
Self::Qianfan,
Self::OpenaiCodex,
Self::Anthropic,
Self::Zai,
Self::Stepfun,
Self::Minimax,
Self::Deepinfra,
Self::Custom,
];
#[must_use]
pub fn all() -> &'static [Self] {
&Self::ALL
}
#[must_use]
pub fn names_hint() -> String {
Self::all()
.iter()
.map(|provider| provider.as_str())
.collect::<Vec<_>>()
.join(", ")
}
#[must_use]
pub fn as_str(self) -> &'static str {
self.provider().id()
}
#[must_use]
pub fn parse(value: &str) -> Option<Self> {
let trimmed = value.trim();
provider::all_providers()
.iter()
.find(|p| {
trimmed.eq_ignore_ascii_case(p.id())
|| p.aliases().iter().any(|a| trimmed.eq_ignore_ascii_case(a))
})
.map(|p| p.kind())
}
#[must_use]
pub fn is_siliconflow(self) -> bool {
matches!(self, Self::Siliconflow | Self::SiliconflowCN)
}
#[must_use]
pub fn provider(self) -> &'static dyn provider::Provider {
provider::provider_for_kind(self)
}
}