mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-12 23:01:41 +00:00
feat: generate rust providers from registry
This commit is contained in:
parent
5d5dd89829
commit
9ba5a1522b
6 changed files with 1240 additions and 659 deletions
|
|
@ -1,6 +1,7 @@
|
|||
# Adding a provider / route to litellm-rust
|
||||
|
||||
- Keep the route contract pure in `crates/core/src/<route>/`: define the typed request/response structs and a provider config trait with no network, env, auth, or logging.
|
||||
- Add provider identity to `providers/providers.json`: `routing_name` must match Python `LlmProviders.value`; `display_name` is human-facing; `default_api_base` and `api_key_env_var` are optional provider defaults.
|
||||
- Put provider-specific transforms in `crates/providers/src/<provider>/<route>/transformation.rs`, mirroring the Python provider tree and exposing a `const <PROVIDER>_<ROUTE>_CONFIG`.
|
||||
- The provider config owns three pure steps: map LiteLLM params, transform the LiteLLM request into the provider request, and transform the provider response back into the LiteLLM response.
|
||||
- If the provider has a reverse or normalization step, keep it pure and explicit next to the transforms; do not hide reverse mapping inside the HTTP transport.
|
||||
|
|
|
|||
|
|
@ -9,3 +9,7 @@ repository.workspace = true
|
|||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
thiserror.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
|
|
|||
335
litellm-rust/crates/core/build.rs
Normal file
335
litellm-rust/crates/core/build.rs
Normal file
|
|
@ -0,0 +1,335 @@
|
|||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ProviderMetadataInput {
|
||||
routing_name: String,
|
||||
display_name: String,
|
||||
default_api_base: Option<String>,
|
||||
api_key_env_var: Option<String>,
|
||||
}
|
||||
|
||||
fn rust_string(value: &str) -> String {
|
||||
format!("{value:?}")
|
||||
}
|
||||
|
||||
fn rust_option(value: Option<&str>) -> String {
|
||||
value
|
||||
.map(|value| format!("Some({})", rust_string(value)))
|
||||
.unwrap_or_else(|| "None".to_string())
|
||||
}
|
||||
|
||||
fn variant_name(routing_name: &str) -> String {
|
||||
routing_name
|
||||
.split(['_', '-', '.'])
|
||||
.filter(|part| !part.is_empty())
|
||||
.map(|part| {
|
||||
let mut chars = part.chars();
|
||||
match chars.next() {
|
||||
Some(first) => {
|
||||
let mut out = String::new();
|
||||
out.extend(first.to_uppercase());
|
||||
out.push_str(chars.as_str());
|
||||
out
|
||||
}
|
||||
None => String::new(),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn validate_providers(providers: &[ProviderMetadataInput]) {
|
||||
let mut routing_names = HashSet::new();
|
||||
let mut variants = HashSet::new();
|
||||
|
||||
for provider in providers {
|
||||
if provider.routing_name.trim().is_empty() {
|
||||
panic!("provider routing_name cannot be empty");
|
||||
}
|
||||
if provider.display_name.trim().is_empty() {
|
||||
panic!(
|
||||
"provider {} has an empty display_name",
|
||||
provider.routing_name
|
||||
);
|
||||
}
|
||||
if !routing_names.insert(provider.routing_name.as_str()) {
|
||||
panic!("duplicate provider routing_name: {}", provider.routing_name);
|
||||
}
|
||||
|
||||
let variant = variant_name(&provider.routing_name);
|
||||
if variant.is_empty() {
|
||||
panic!(
|
||||
"provider {} generated an empty Rust variant",
|
||||
provider.routing_name
|
||||
);
|
||||
}
|
||||
if !variants.insert(variant.clone()) {
|
||||
panic!(
|
||||
"provider {} generated duplicate Rust variant {variant}",
|
||||
provider.routing_name
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_provider_code(providers: &[ProviderMetadataInput]) -> String {
|
||||
let variants: Vec<String> = providers
|
||||
.iter()
|
||||
.map(|provider| variant_name(&provider.routing_name))
|
||||
.collect();
|
||||
|
||||
let enum_variants = variants
|
||||
.iter()
|
||||
.map(|variant| format!(" {variant},"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
let all_values = variants
|
||||
.iter()
|
||||
.map(|variant| format!(" LlmProvider::{variant},"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
let metadata_values = providers
|
||||
.iter()
|
||||
.zip(variants.iter())
|
||||
.map(|(provider, variant)| {
|
||||
format!(
|
||||
" ProviderMetadata {{ provider: LlmProvider::{variant}, routing_name: {}, display_name: {}, default_api_base: {}, api_key_env_var: {} }},",
|
||||
rust_string(&provider.routing_name),
|
||||
rust_string(&provider.display_name),
|
||||
rust_option(provider.default_api_base.as_deref()),
|
||||
rust_option(provider.api_key_env_var.as_deref()),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
let metadata_match_arms = variants
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, variant)| {
|
||||
format!(" LlmProvider::{variant} => &Self::METADATA[{index}],")
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
format!(
|
||||
r#"// @generated by crates/core/build.rs from litellm-rust/providers/providers.json.
|
||||
// Do not edit this file by hand.
|
||||
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::error::CoreError;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct ProviderMetadata {{
|
||||
pub provider: LlmProvider,
|
||||
pub routing_name: &'static str,
|
||||
pub display_name: &'static str,
|
||||
pub default_api_base: Option<&'static str>,
|
||||
pub api_key_env_var: Option<&'static str>,
|
||||
}}
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum LlmProvider {{
|
||||
{enum_variants}
|
||||
}}
|
||||
|
||||
impl LlmProvider {{
|
||||
pub const ALL: [LlmProvider; {provider_count}] = [
|
||||
{all_values}
|
||||
];
|
||||
|
||||
pub const METADATA: [ProviderMetadata; {provider_count}] = [
|
||||
{metadata_values}
|
||||
];
|
||||
|
||||
pub fn metadata(self) -> &'static ProviderMetadata {{
|
||||
match self {{
|
||||
{metadata_match_arms}
|
||||
}}
|
||||
}}
|
||||
|
||||
pub fn as_str(self) -> &'static str {{
|
||||
self.metadata().routing_name
|
||||
}}
|
||||
|
||||
pub fn display_name(self) -> &'static str {{
|
||||
self.metadata().display_name
|
||||
}}
|
||||
|
||||
pub fn default_api_base(self) -> Option<&'static str> {{
|
||||
self.metadata().default_api_base
|
||||
}}
|
||||
|
||||
pub fn api_key_env_var(self) -> Option<&'static str> {{
|
||||
self.metadata().api_key_env_var
|
||||
}}
|
||||
}}
|
||||
|
||||
impl fmt::Display for LlmProvider {{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {{
|
||||
f.write_str(self.as_str())
|
||||
}}
|
||||
}}
|
||||
|
||||
impl FromStr for LlmProvider {{
|
||||
type Err = CoreError;
|
||||
|
||||
fn from_str(value: &str) -> Result<Self, Self::Err> {{
|
||||
LlmProvider::ALL
|
||||
.iter()
|
||||
.copied()
|
||||
.find(|provider| provider.as_str() == value)
|
||||
.ok_or_else(|| CoreError::InvalidProvider(value.to_string()))
|
||||
}}
|
||||
}}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {{
|
||||
use super::*;
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct RegistryProvider {{
|
||||
routing_name: String,
|
||||
}}
|
||||
|
||||
fn registry_provider_values() -> Vec<String> {{
|
||||
let raw = include_str!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/../../providers/providers.json"
|
||||
));
|
||||
serde_json::from_str::<Vec<RegistryProvider>>(raw)
|
||||
.expect("providers.json parses")
|
||||
.into_iter()
|
||||
.map(|provider| provider.routing_name)
|
||||
.collect()
|
||||
}}
|
||||
|
||||
fn python_provider_values() -> Vec<String> {{
|
||||
let source = include_str!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/../../../litellm/types/utils.py"
|
||||
));
|
||||
let mut values = Vec::new();
|
||||
let mut in_llm_providers = false;
|
||||
|
||||
for line in source.lines() {{
|
||||
if line.starts_with("class LlmProviders(") {{
|
||||
in_llm_providers = true;
|
||||
continue;
|
||||
}}
|
||||
if in_llm_providers && line.starts_with("class ") {{
|
||||
break;
|
||||
}}
|
||||
if !in_llm_providers {{
|
||||
continue;
|
||||
}}
|
||||
|
||||
let trimmed = line.trim();
|
||||
let Some((name, value_expr)) = trimmed.split_once('=') else {{
|
||||
continue;
|
||||
}};
|
||||
if !name
|
||||
.trim()
|
||||
.chars()
|
||||
.all(|ch| ch.is_ascii_uppercase() || ch.is_ascii_digit() || ch == '_')
|
||||
{{
|
||||
continue;
|
||||
}}
|
||||
let Some(value) = value_expr.split('"').nth(1) else {{
|
||||
continue;
|
||||
}};
|
||||
values.push(value.to_string());
|
||||
}}
|
||||
|
||||
assert!(!values.is_empty(), "parsed Python LlmProviders values");
|
||||
values
|
||||
}}
|
||||
|
||||
#[test]
|
||||
fn provider_values_match_registry_order() {{
|
||||
let registry_values = registry_provider_values();
|
||||
assert_eq!(LlmProvider::ALL.len(), registry_values.len());
|
||||
assert_eq!(
|
||||
LlmProvider::ALL
|
||||
.iter()
|
||||
.map(|provider| provider.as_str().to_string())
|
||||
.collect::<Vec<_>>(),
|
||||
registry_values
|
||||
);
|
||||
}}
|
||||
|
||||
#[test]
|
||||
fn provider_registry_matches_python_llm_providers() {{
|
||||
assert_eq!(registry_provider_values(), python_provider_values());
|
||||
}}
|
||||
|
||||
#[test]
|
||||
fn from_str_round_trips_all_providers() {{
|
||||
for provider in LlmProvider::ALL {{
|
||||
assert_eq!(LlmProvider::from_str(provider.as_str()), Ok(provider));
|
||||
assert_eq!(provider.to_string(), provider.as_str());
|
||||
}}
|
||||
}}
|
||||
|
||||
#[test]
|
||||
fn from_str_rejects_unknown_provider() {{
|
||||
assert_eq!(
|
||||
LlmProvider::from_str("not-a-provider"),
|
||||
Err(CoreError::InvalidProvider("not-a-provider".to_string()))
|
||||
);
|
||||
}}
|
||||
|
||||
#[test]
|
||||
fn provider_metadata_exposes_optional_defaults() {{
|
||||
assert_eq!(LlmProvider::Mistral.display_name(), "Mistral");
|
||||
assert_eq!(
|
||||
LlmProvider::Mistral.default_api_base(),
|
||||
Some("https://api.mistral.ai/v1")
|
||||
);
|
||||
assert_eq!(LlmProvider::Mistral.api_key_env_var(), Some("MISTRAL_API_KEY"));
|
||||
}}
|
||||
}}
|
||||
"#,
|
||||
enum_variants = enum_variants,
|
||||
provider_count = providers.len(),
|
||||
all_values = all_values,
|
||||
metadata_values = metadata_values,
|
||||
metadata_match_arms = metadata_match_arms,
|
||||
)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
let providers_path = manifest_dir.join("../../providers/providers.json");
|
||||
println!("cargo:rerun-if-changed={}", providers_path.display());
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
manifest_dir.join("build.rs").display()
|
||||
);
|
||||
|
||||
let raw = fs::read_to_string(&providers_path).unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"failed to read provider registry {}: {err}",
|
||||
providers_path.display()
|
||||
)
|
||||
});
|
||||
let providers: Vec<ProviderMetadataInput> = serde_json::from_str(&raw)
|
||||
.unwrap_or_else(|err| panic!("failed to parse {}: {err}", providers_path.display()));
|
||||
validate_providers(&providers);
|
||||
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
fs::write(
|
||||
out_dir.join("provider_generated.rs"),
|
||||
generate_provider_code(&providers),
|
||||
)
|
||||
.expect("failed to write generated provider code");
|
||||
}
|
||||
|
|
@ -1,659 +1 @@
|
|||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::error::CoreError;
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum LlmProvider {
|
||||
Openai,
|
||||
Chatgpt,
|
||||
OpenaiLike,
|
||||
JinaAi,
|
||||
Xai,
|
||||
Zai,
|
||||
CustomOpenai,
|
||||
TextCompletionOpenai,
|
||||
Cohere,
|
||||
CohereChat,
|
||||
Clarifai,
|
||||
Anthropic,
|
||||
AnthropicText,
|
||||
Bytez,
|
||||
Replicate,
|
||||
Reducto,
|
||||
Runwayml,
|
||||
AwsPolly,
|
||||
Huggingface,
|
||||
TogetherAi,
|
||||
Openrouter,
|
||||
Datarobot,
|
||||
VertexAi,
|
||||
VertexAiBeta,
|
||||
Gemini,
|
||||
Ai21,
|
||||
Baseten,
|
||||
BlackForestLabs,
|
||||
Azure,
|
||||
AzureText,
|
||||
AzureAi,
|
||||
Sagemaker,
|
||||
SagemakerChat,
|
||||
SagemakerNova,
|
||||
Bedrock,
|
||||
Vllm,
|
||||
NlpCloud,
|
||||
Petals,
|
||||
Oobabooga,
|
||||
Ollama,
|
||||
OllamaChat,
|
||||
Deepinfra,
|
||||
Perplexity,
|
||||
Mistral,
|
||||
Milvus,
|
||||
Groq,
|
||||
A2a,
|
||||
Gigachat,
|
||||
NvidiaNim,
|
||||
NvidiaRiva,
|
||||
Soniox,
|
||||
Cerebras,
|
||||
Ai21Chat,
|
||||
Volcengine,
|
||||
Codestral,
|
||||
TextCompletionCodestral,
|
||||
Dashscope,
|
||||
Modelscope,
|
||||
Moonshot,
|
||||
Publicai,
|
||||
V0,
|
||||
Morph,
|
||||
LambdaAi,
|
||||
Inception,
|
||||
TextCompletionInception,
|
||||
Deepseek,
|
||||
Sambanova,
|
||||
Maritalk,
|
||||
Voyage,
|
||||
Cloudflare,
|
||||
Xinference,
|
||||
FireworksAi,
|
||||
Friendliai,
|
||||
FeatherlessAi,
|
||||
Watsonx,
|
||||
WatsonxText,
|
||||
Triton,
|
||||
Predibase,
|
||||
Databricks,
|
||||
Empower,
|
||||
Github,
|
||||
Ragflow,
|
||||
Compactifai,
|
||||
DockerModelRunner,
|
||||
Custom,
|
||||
LitellmProxy,
|
||||
HostedVllm,
|
||||
Llamafile,
|
||||
LmStudio,
|
||||
Galadriel,
|
||||
Nebius,
|
||||
Infinity,
|
||||
Deepgram,
|
||||
Elevenlabs,
|
||||
Novita,
|
||||
AiohttpOpenai,
|
||||
Langfuse,
|
||||
Humanloop,
|
||||
Topaz,
|
||||
Sap,
|
||||
Assemblyai,
|
||||
CharityEngine,
|
||||
GithubCopilot,
|
||||
Snowflake,
|
||||
GradientAi,
|
||||
MetaLlama,
|
||||
Nscale,
|
||||
PgVector,
|
||||
S3Vectors,
|
||||
Helicone,
|
||||
Hyperbolic,
|
||||
Recraft,
|
||||
FalAi,
|
||||
Stability,
|
||||
Heroku,
|
||||
Aiml,
|
||||
Cometapi,
|
||||
Oci,
|
||||
AutoRouter,
|
||||
VercelAiGateway,
|
||||
Dotprompt,
|
||||
Manus,
|
||||
Wandb,
|
||||
Ovhcloud,
|
||||
Scaleway,
|
||||
Lemonade,
|
||||
AmazonNova,
|
||||
A2aAgent,
|
||||
Langgraph,
|
||||
Langflow,
|
||||
Minimax,
|
||||
Synthetic,
|
||||
Apertis,
|
||||
NanoGpt,
|
||||
Poe,
|
||||
Chutes,
|
||||
Neosantara,
|
||||
Parasail,
|
||||
XiaomiMimo,
|
||||
Tensormesh,
|
||||
Libertai,
|
||||
Pinstripes,
|
||||
Darkbloom,
|
||||
LitellmAgent,
|
||||
Cursor,
|
||||
BedrockMantle,
|
||||
}
|
||||
|
||||
impl LlmProvider {
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
LlmProvider::Openai => "openai",
|
||||
LlmProvider::Chatgpt => "chatgpt",
|
||||
LlmProvider::OpenaiLike => "openai_like",
|
||||
LlmProvider::JinaAi => "jina_ai",
|
||||
LlmProvider::Xai => "xai",
|
||||
LlmProvider::Zai => "zai",
|
||||
LlmProvider::CustomOpenai => "custom_openai",
|
||||
LlmProvider::TextCompletionOpenai => "text-completion-openai",
|
||||
LlmProvider::Cohere => "cohere",
|
||||
LlmProvider::CohereChat => "cohere_chat",
|
||||
LlmProvider::Clarifai => "clarifai",
|
||||
LlmProvider::Anthropic => "anthropic",
|
||||
LlmProvider::AnthropicText => "anthropic_text",
|
||||
LlmProvider::Bytez => "bytez",
|
||||
LlmProvider::Replicate => "replicate",
|
||||
LlmProvider::Reducto => "reducto",
|
||||
LlmProvider::Runwayml => "runwayml",
|
||||
LlmProvider::AwsPolly => "aws_polly",
|
||||
LlmProvider::Huggingface => "huggingface",
|
||||
LlmProvider::TogetherAi => "together_ai",
|
||||
LlmProvider::Openrouter => "openrouter",
|
||||
LlmProvider::Datarobot => "datarobot",
|
||||
LlmProvider::VertexAi => "vertex_ai",
|
||||
LlmProvider::VertexAiBeta => "vertex_ai_beta",
|
||||
LlmProvider::Gemini => "gemini",
|
||||
LlmProvider::Ai21 => "ai21",
|
||||
LlmProvider::Baseten => "baseten",
|
||||
LlmProvider::BlackForestLabs => "black_forest_labs",
|
||||
LlmProvider::Azure => "azure",
|
||||
LlmProvider::AzureText => "azure_text",
|
||||
LlmProvider::AzureAi => "azure_ai",
|
||||
LlmProvider::Sagemaker => "sagemaker",
|
||||
LlmProvider::SagemakerChat => "sagemaker_chat",
|
||||
LlmProvider::SagemakerNova => "sagemaker_nova",
|
||||
LlmProvider::Bedrock => "bedrock",
|
||||
LlmProvider::Vllm => "vllm",
|
||||
LlmProvider::NlpCloud => "nlp_cloud",
|
||||
LlmProvider::Petals => "petals",
|
||||
LlmProvider::Oobabooga => "oobabooga",
|
||||
LlmProvider::Ollama => "ollama",
|
||||
LlmProvider::OllamaChat => "ollama_chat",
|
||||
LlmProvider::Deepinfra => "deepinfra",
|
||||
LlmProvider::Perplexity => "perplexity",
|
||||
LlmProvider::Mistral => "mistral",
|
||||
LlmProvider::Milvus => "milvus",
|
||||
LlmProvider::Groq => "groq",
|
||||
LlmProvider::A2a => "a2a",
|
||||
LlmProvider::Gigachat => "gigachat",
|
||||
LlmProvider::NvidiaNim => "nvidia_nim",
|
||||
LlmProvider::NvidiaRiva => "nvidia_riva",
|
||||
LlmProvider::Soniox => "soniox",
|
||||
LlmProvider::Cerebras => "cerebras",
|
||||
LlmProvider::Ai21Chat => "ai21_chat",
|
||||
LlmProvider::Volcengine => "volcengine",
|
||||
LlmProvider::Codestral => "codestral",
|
||||
LlmProvider::TextCompletionCodestral => "text-completion-codestral",
|
||||
LlmProvider::Dashscope => "dashscope",
|
||||
LlmProvider::Modelscope => "modelscope",
|
||||
LlmProvider::Moonshot => "moonshot",
|
||||
LlmProvider::Publicai => "publicai",
|
||||
LlmProvider::V0 => "v0",
|
||||
LlmProvider::Morph => "morph",
|
||||
LlmProvider::LambdaAi => "lambda_ai",
|
||||
LlmProvider::Inception => "inception",
|
||||
LlmProvider::TextCompletionInception => "text-completion-inception",
|
||||
LlmProvider::Deepseek => "deepseek",
|
||||
LlmProvider::Sambanova => "sambanova",
|
||||
LlmProvider::Maritalk => "maritalk",
|
||||
LlmProvider::Voyage => "voyage",
|
||||
LlmProvider::Cloudflare => "cloudflare",
|
||||
LlmProvider::Xinference => "xinference",
|
||||
LlmProvider::FireworksAi => "fireworks_ai",
|
||||
LlmProvider::Friendliai => "friendliai",
|
||||
LlmProvider::FeatherlessAi => "featherless_ai",
|
||||
LlmProvider::Watsonx => "watsonx",
|
||||
LlmProvider::WatsonxText => "watsonx_text",
|
||||
LlmProvider::Triton => "triton",
|
||||
LlmProvider::Predibase => "predibase",
|
||||
LlmProvider::Databricks => "databricks",
|
||||
LlmProvider::Empower => "empower",
|
||||
LlmProvider::Github => "github",
|
||||
LlmProvider::Ragflow => "ragflow",
|
||||
LlmProvider::Compactifai => "compactifai",
|
||||
LlmProvider::DockerModelRunner => "docker_model_runner",
|
||||
LlmProvider::Custom => "custom",
|
||||
LlmProvider::LitellmProxy => "litellm_proxy",
|
||||
LlmProvider::HostedVllm => "hosted_vllm",
|
||||
LlmProvider::Llamafile => "llamafile",
|
||||
LlmProvider::LmStudio => "lm_studio",
|
||||
LlmProvider::Galadriel => "galadriel",
|
||||
LlmProvider::Nebius => "nebius",
|
||||
LlmProvider::Infinity => "infinity",
|
||||
LlmProvider::Deepgram => "deepgram",
|
||||
LlmProvider::Elevenlabs => "elevenlabs",
|
||||
LlmProvider::Novita => "novita",
|
||||
LlmProvider::AiohttpOpenai => "aiohttp_openai",
|
||||
LlmProvider::Langfuse => "langfuse",
|
||||
LlmProvider::Humanloop => "humanloop",
|
||||
LlmProvider::Topaz => "topaz",
|
||||
LlmProvider::Sap => "sap",
|
||||
LlmProvider::Assemblyai => "assemblyai",
|
||||
LlmProvider::CharityEngine => "charity_engine",
|
||||
LlmProvider::GithubCopilot => "github_copilot",
|
||||
LlmProvider::Snowflake => "snowflake",
|
||||
LlmProvider::GradientAi => "gradient_ai",
|
||||
LlmProvider::MetaLlama => "meta_llama",
|
||||
LlmProvider::Nscale => "nscale",
|
||||
LlmProvider::PgVector => "pg_vector",
|
||||
LlmProvider::S3Vectors => "s3_vectors",
|
||||
LlmProvider::Helicone => "helicone",
|
||||
LlmProvider::Hyperbolic => "hyperbolic",
|
||||
LlmProvider::Recraft => "recraft",
|
||||
LlmProvider::FalAi => "fal_ai",
|
||||
LlmProvider::Stability => "stability",
|
||||
LlmProvider::Heroku => "heroku",
|
||||
LlmProvider::Aiml => "aiml",
|
||||
LlmProvider::Cometapi => "cometapi",
|
||||
LlmProvider::Oci => "oci",
|
||||
LlmProvider::AutoRouter => "auto_router",
|
||||
LlmProvider::VercelAiGateway => "vercel_ai_gateway",
|
||||
LlmProvider::Dotprompt => "dotprompt",
|
||||
LlmProvider::Manus => "manus",
|
||||
LlmProvider::Wandb => "wandb",
|
||||
LlmProvider::Ovhcloud => "ovhcloud",
|
||||
LlmProvider::Scaleway => "scaleway",
|
||||
LlmProvider::Lemonade => "lemonade",
|
||||
LlmProvider::AmazonNova => "amazon_nova",
|
||||
LlmProvider::A2aAgent => "a2a_agent",
|
||||
LlmProvider::Langgraph => "langgraph",
|
||||
LlmProvider::Langflow => "langflow",
|
||||
LlmProvider::Minimax => "minimax",
|
||||
LlmProvider::Synthetic => "synthetic",
|
||||
LlmProvider::Apertis => "apertis",
|
||||
LlmProvider::NanoGpt => "nano-gpt",
|
||||
LlmProvider::Poe => "poe",
|
||||
LlmProvider::Chutes => "chutes",
|
||||
LlmProvider::Neosantara => "neosantara",
|
||||
LlmProvider::Parasail => "parasail",
|
||||
LlmProvider::XiaomiMimo => "xiaomi_mimo",
|
||||
LlmProvider::Tensormesh => "tensormesh",
|
||||
LlmProvider::Libertai => "libertai",
|
||||
LlmProvider::Pinstripes => "pinstripes",
|
||||
LlmProvider::Darkbloom => "darkbloom",
|
||||
LlmProvider::LitellmAgent => "litellm_agent",
|
||||
LlmProvider::Cursor => "cursor",
|
||||
LlmProvider::BedrockMantle => "bedrock_mantle",
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub const ALL: [LlmProvider; 146] = [
|
||||
LlmProvider::Openai,
|
||||
LlmProvider::Chatgpt,
|
||||
LlmProvider::OpenaiLike,
|
||||
LlmProvider::JinaAi,
|
||||
LlmProvider::Xai,
|
||||
LlmProvider::Zai,
|
||||
LlmProvider::CustomOpenai,
|
||||
LlmProvider::TextCompletionOpenai,
|
||||
LlmProvider::Cohere,
|
||||
LlmProvider::CohereChat,
|
||||
LlmProvider::Clarifai,
|
||||
LlmProvider::Anthropic,
|
||||
LlmProvider::AnthropicText,
|
||||
LlmProvider::Bytez,
|
||||
LlmProvider::Replicate,
|
||||
LlmProvider::Reducto,
|
||||
LlmProvider::Runwayml,
|
||||
LlmProvider::AwsPolly,
|
||||
LlmProvider::Huggingface,
|
||||
LlmProvider::TogetherAi,
|
||||
LlmProvider::Openrouter,
|
||||
LlmProvider::Datarobot,
|
||||
LlmProvider::VertexAi,
|
||||
LlmProvider::VertexAiBeta,
|
||||
LlmProvider::Gemini,
|
||||
LlmProvider::Ai21,
|
||||
LlmProvider::Baseten,
|
||||
LlmProvider::BlackForestLabs,
|
||||
LlmProvider::Azure,
|
||||
LlmProvider::AzureText,
|
||||
LlmProvider::AzureAi,
|
||||
LlmProvider::Sagemaker,
|
||||
LlmProvider::SagemakerChat,
|
||||
LlmProvider::SagemakerNova,
|
||||
LlmProvider::Bedrock,
|
||||
LlmProvider::Vllm,
|
||||
LlmProvider::NlpCloud,
|
||||
LlmProvider::Petals,
|
||||
LlmProvider::Oobabooga,
|
||||
LlmProvider::Ollama,
|
||||
LlmProvider::OllamaChat,
|
||||
LlmProvider::Deepinfra,
|
||||
LlmProvider::Perplexity,
|
||||
LlmProvider::Mistral,
|
||||
LlmProvider::Milvus,
|
||||
LlmProvider::Groq,
|
||||
LlmProvider::A2a,
|
||||
LlmProvider::Gigachat,
|
||||
LlmProvider::NvidiaNim,
|
||||
LlmProvider::NvidiaRiva,
|
||||
LlmProvider::Soniox,
|
||||
LlmProvider::Cerebras,
|
||||
LlmProvider::Ai21Chat,
|
||||
LlmProvider::Volcengine,
|
||||
LlmProvider::Codestral,
|
||||
LlmProvider::TextCompletionCodestral,
|
||||
LlmProvider::Dashscope,
|
||||
LlmProvider::Modelscope,
|
||||
LlmProvider::Moonshot,
|
||||
LlmProvider::Publicai,
|
||||
LlmProvider::V0,
|
||||
LlmProvider::Morph,
|
||||
LlmProvider::LambdaAi,
|
||||
LlmProvider::Inception,
|
||||
LlmProvider::TextCompletionInception,
|
||||
LlmProvider::Deepseek,
|
||||
LlmProvider::Sambanova,
|
||||
LlmProvider::Maritalk,
|
||||
LlmProvider::Voyage,
|
||||
LlmProvider::Cloudflare,
|
||||
LlmProvider::Xinference,
|
||||
LlmProvider::FireworksAi,
|
||||
LlmProvider::Friendliai,
|
||||
LlmProvider::FeatherlessAi,
|
||||
LlmProvider::Watsonx,
|
||||
LlmProvider::WatsonxText,
|
||||
LlmProvider::Triton,
|
||||
LlmProvider::Predibase,
|
||||
LlmProvider::Databricks,
|
||||
LlmProvider::Empower,
|
||||
LlmProvider::Github,
|
||||
LlmProvider::Ragflow,
|
||||
LlmProvider::Compactifai,
|
||||
LlmProvider::DockerModelRunner,
|
||||
LlmProvider::Custom,
|
||||
LlmProvider::LitellmProxy,
|
||||
LlmProvider::HostedVllm,
|
||||
LlmProvider::Llamafile,
|
||||
LlmProvider::LmStudio,
|
||||
LlmProvider::Galadriel,
|
||||
LlmProvider::Nebius,
|
||||
LlmProvider::Infinity,
|
||||
LlmProvider::Deepgram,
|
||||
LlmProvider::Elevenlabs,
|
||||
LlmProvider::Novita,
|
||||
LlmProvider::AiohttpOpenai,
|
||||
LlmProvider::Langfuse,
|
||||
LlmProvider::Humanloop,
|
||||
LlmProvider::Topaz,
|
||||
LlmProvider::Sap,
|
||||
LlmProvider::Assemblyai,
|
||||
LlmProvider::CharityEngine,
|
||||
LlmProvider::GithubCopilot,
|
||||
LlmProvider::Snowflake,
|
||||
LlmProvider::GradientAi,
|
||||
LlmProvider::MetaLlama,
|
||||
LlmProvider::Nscale,
|
||||
LlmProvider::PgVector,
|
||||
LlmProvider::S3Vectors,
|
||||
LlmProvider::Helicone,
|
||||
LlmProvider::Hyperbolic,
|
||||
LlmProvider::Recraft,
|
||||
LlmProvider::FalAi,
|
||||
LlmProvider::Stability,
|
||||
LlmProvider::Heroku,
|
||||
LlmProvider::Aiml,
|
||||
LlmProvider::Cometapi,
|
||||
LlmProvider::Oci,
|
||||
LlmProvider::AutoRouter,
|
||||
LlmProvider::VercelAiGateway,
|
||||
LlmProvider::Dotprompt,
|
||||
LlmProvider::Manus,
|
||||
LlmProvider::Wandb,
|
||||
LlmProvider::Ovhcloud,
|
||||
LlmProvider::Scaleway,
|
||||
LlmProvider::Lemonade,
|
||||
LlmProvider::AmazonNova,
|
||||
LlmProvider::A2aAgent,
|
||||
LlmProvider::Langgraph,
|
||||
LlmProvider::Langflow,
|
||||
LlmProvider::Minimax,
|
||||
LlmProvider::Synthetic,
|
||||
LlmProvider::Apertis,
|
||||
LlmProvider::NanoGpt,
|
||||
LlmProvider::Poe,
|
||||
LlmProvider::Chutes,
|
||||
LlmProvider::Neosantara,
|
||||
LlmProvider::Parasail,
|
||||
LlmProvider::XiaomiMimo,
|
||||
LlmProvider::Tensormesh,
|
||||
LlmProvider::Libertai,
|
||||
LlmProvider::Pinstripes,
|
||||
LlmProvider::Darkbloom,
|
||||
LlmProvider::LitellmAgent,
|
||||
LlmProvider::Cursor,
|
||||
LlmProvider::BedrockMantle,
|
||||
];
|
||||
}
|
||||
|
||||
impl fmt::Display for LlmProvider {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for LlmProvider {
|
||||
type Err = CoreError;
|
||||
|
||||
fn from_str(value: &str) -> Result<Self, Self::Err> {
|
||||
LlmProvider::ALL
|
||||
.iter()
|
||||
.copied()
|
||||
.find(|provider| provider.as_str() == value)
|
||||
.ok_or_else(|| CoreError::InvalidProvider(value.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const PYTHON_LLM_PROVIDER_VALUES: &[&str] = &[
|
||||
"openai",
|
||||
"chatgpt",
|
||||
"openai_like",
|
||||
"jina_ai",
|
||||
"xai",
|
||||
"zai",
|
||||
"custom_openai",
|
||||
"text-completion-openai",
|
||||
"cohere",
|
||||
"cohere_chat",
|
||||
"clarifai",
|
||||
"anthropic",
|
||||
"anthropic_text",
|
||||
"bytez",
|
||||
"replicate",
|
||||
"reducto",
|
||||
"runwayml",
|
||||
"aws_polly",
|
||||
"huggingface",
|
||||
"together_ai",
|
||||
"openrouter",
|
||||
"datarobot",
|
||||
"vertex_ai",
|
||||
"vertex_ai_beta",
|
||||
"gemini",
|
||||
"ai21",
|
||||
"baseten",
|
||||
"black_forest_labs",
|
||||
"azure",
|
||||
"azure_text",
|
||||
"azure_ai",
|
||||
"sagemaker",
|
||||
"sagemaker_chat",
|
||||
"sagemaker_nova",
|
||||
"bedrock",
|
||||
"vllm",
|
||||
"nlp_cloud",
|
||||
"petals",
|
||||
"oobabooga",
|
||||
"ollama",
|
||||
"ollama_chat",
|
||||
"deepinfra",
|
||||
"perplexity",
|
||||
"mistral",
|
||||
"milvus",
|
||||
"groq",
|
||||
"a2a",
|
||||
"gigachat",
|
||||
"nvidia_nim",
|
||||
"nvidia_riva",
|
||||
"soniox",
|
||||
"cerebras",
|
||||
"ai21_chat",
|
||||
"volcengine",
|
||||
"codestral",
|
||||
"text-completion-codestral",
|
||||
"dashscope",
|
||||
"modelscope",
|
||||
"moonshot",
|
||||
"publicai",
|
||||
"v0",
|
||||
"morph",
|
||||
"lambda_ai",
|
||||
"inception",
|
||||
"text-completion-inception",
|
||||
"deepseek",
|
||||
"sambanova",
|
||||
"maritalk",
|
||||
"voyage",
|
||||
"cloudflare",
|
||||
"xinference",
|
||||
"fireworks_ai",
|
||||
"friendliai",
|
||||
"featherless_ai",
|
||||
"watsonx",
|
||||
"watsonx_text",
|
||||
"triton",
|
||||
"predibase",
|
||||
"databricks",
|
||||
"empower",
|
||||
"github",
|
||||
"ragflow",
|
||||
"compactifai",
|
||||
"docker_model_runner",
|
||||
"custom",
|
||||
"litellm_proxy",
|
||||
"hosted_vllm",
|
||||
"llamafile",
|
||||
"lm_studio",
|
||||
"galadriel",
|
||||
"nebius",
|
||||
"infinity",
|
||||
"deepgram",
|
||||
"elevenlabs",
|
||||
"novita",
|
||||
"aiohttp_openai",
|
||||
"langfuse",
|
||||
"humanloop",
|
||||
"topaz",
|
||||
"sap",
|
||||
"assemblyai",
|
||||
"charity_engine",
|
||||
"github_copilot",
|
||||
"snowflake",
|
||||
"gradient_ai",
|
||||
"meta_llama",
|
||||
"nscale",
|
||||
"pg_vector",
|
||||
"s3_vectors",
|
||||
"helicone",
|
||||
"hyperbolic",
|
||||
"recraft",
|
||||
"fal_ai",
|
||||
"stability",
|
||||
"heroku",
|
||||
"aiml",
|
||||
"cometapi",
|
||||
"oci",
|
||||
"auto_router",
|
||||
"vercel_ai_gateway",
|
||||
"dotprompt",
|
||||
"manus",
|
||||
"wandb",
|
||||
"ovhcloud",
|
||||
"scaleway",
|
||||
"lemonade",
|
||||
"amazon_nova",
|
||||
"a2a_agent",
|
||||
"langgraph",
|
||||
"langflow",
|
||||
"minimax",
|
||||
"synthetic",
|
||||
"apertis",
|
||||
"nano-gpt",
|
||||
"poe",
|
||||
"chutes",
|
||||
"neosantara",
|
||||
"parasail",
|
||||
"xiaomi_mimo",
|
||||
"tensormesh",
|
||||
"libertai",
|
||||
"pinstripes",
|
||||
"darkbloom",
|
||||
"litellm_agent",
|
||||
"cursor",
|
||||
"bedrock_mantle",
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn provider_values_match_python_enum_order() {
|
||||
assert_eq!(LlmProvider::ALL.len(), 146);
|
||||
assert_eq!(
|
||||
LlmProvider::ALL
|
||||
.iter()
|
||||
.map(|provider| provider.as_str())
|
||||
.collect::<Vec<_>>(),
|
||||
PYTHON_LLM_PROVIDER_VALUES
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str_round_trips_all_providers() {
|
||||
for provider in LlmProvider::ALL {
|
||||
assert_eq!(LlmProvider::from_str(provider.as_str()), Ok(provider));
|
||||
assert_eq!(provider.to_string(), provider.as_str());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str_rejects_unknown_provider() {
|
||||
assert_eq!(
|
||||
LlmProvider::from_str("not-a-provider"),
|
||||
Err(CoreError::InvalidProvider("not-a-provider".to_string()))
|
||||
);
|
||||
}
|
||||
}
|
||||
include!(concat!(env!("OUT_DIR"), "/provider_generated.rs"));
|
||||
|
|
|
|||
21
litellm-rust/providers/README.md
Normal file
21
litellm-rust/providers/README.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# Rust Provider Registry
|
||||
|
||||
`providers.json` is the source of truth for provider identity in `litellm-rust`.
|
||||
`crates/core/build.rs` reads it at compile time and generates the typed
|
||||
`LlmProvider` enum plus static provider metadata. Runtime code does not parse
|
||||
this JSON.
|
||||
|
||||
To add a provider:
|
||||
|
||||
- Add a `providers.json` entry with `routing_name` matching Python
|
||||
`LlmProviders.value` in `litellm/types/utils.py`.
|
||||
- Set `display_name` to the human-readable provider name for docs/errors.
|
||||
- Set `default_api_base` to a stable provider-level default base URL, or `null`
|
||||
when it is unknown, dynamic, or route-specific.
|
||||
- Set `api_key_env_var` to the canonical LiteLLM env var, or `null` when there
|
||||
is no single provider-level key.
|
||||
- Put request/response logic under
|
||||
`crates/providers/src/<provider>/<route>/transformation.rs`; do not put
|
||||
transforms, signing logic, or secrets in this registry.
|
||||
- Run `cargo test -p litellm-core --locked`; it verifies the Rust registry stays
|
||||
in parity with Python `LlmProviders`.
|
||||
878
litellm-rust/providers/providers.json
Normal file
878
litellm-rust/providers/providers.json
Normal file
|
|
@ -0,0 +1,878 @@
|
|||
[
|
||||
{
|
||||
"routing_name": "openai",
|
||||
"display_name": "OpenAI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "chatgpt",
|
||||
"display_name": "ChatGPT",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "openai_like",
|
||||
"display_name": "OpenAI Like",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "jina_ai",
|
||||
"display_name": "Jina AI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "xai",
|
||||
"display_name": "xAI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "zai",
|
||||
"display_name": "Z.ai",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "custom_openai",
|
||||
"display_name": "Custom OpenAI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "text-completion-openai",
|
||||
"display_name": "Text Completion OpenAI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "cohere",
|
||||
"display_name": "Cohere",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "cohere_chat",
|
||||
"display_name": "Cohere Chat",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "clarifai",
|
||||
"display_name": "Clarifai",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "anthropic",
|
||||
"display_name": "Anthropic",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "anthropic_text",
|
||||
"display_name": "Anthropic Text",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "bytez",
|
||||
"display_name": "Bytez",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "replicate",
|
||||
"display_name": "Replicate",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "reducto",
|
||||
"display_name": "Reducto",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "runwayml",
|
||||
"display_name": "Runwayml",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "aws_polly",
|
||||
"display_name": "AWS Polly",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "huggingface",
|
||||
"display_name": "Hugging Face",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "together_ai",
|
||||
"display_name": "Together AI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "openrouter",
|
||||
"display_name": "Openrouter",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "datarobot",
|
||||
"display_name": "Datarobot",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "vertex_ai",
|
||||
"display_name": "Vertex AI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "vertex_ai_beta",
|
||||
"display_name": "Vertex AI Beta",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "gemini",
|
||||
"display_name": "Gemini",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "ai21",
|
||||
"display_name": "AI21",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "baseten",
|
||||
"display_name": "Baseten",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "black_forest_labs",
|
||||
"display_name": "Black Forest Labs",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "azure",
|
||||
"display_name": "Azure",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "azure_text",
|
||||
"display_name": "Azure Text",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "azure_ai",
|
||||
"display_name": "Azure AI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "sagemaker",
|
||||
"display_name": "Sagemaker",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "sagemaker_chat",
|
||||
"display_name": "Sagemaker Chat",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "sagemaker_nova",
|
||||
"display_name": "Sagemaker Nova",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "bedrock",
|
||||
"display_name": "Bedrock",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "vllm",
|
||||
"display_name": "vLLM",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "nlp_cloud",
|
||||
"display_name": "NLP Cloud",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "petals",
|
||||
"display_name": "Petals",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "oobabooga",
|
||||
"display_name": "Oobabooga",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "ollama",
|
||||
"display_name": "Ollama",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "ollama_chat",
|
||||
"display_name": "Ollama Chat",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "deepinfra",
|
||||
"display_name": "Deepinfra",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "perplexity",
|
||||
"display_name": "Perplexity",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "mistral",
|
||||
"display_name": "Mistral",
|
||||
"default_api_base": "https://api.mistral.ai/v1",
|
||||
"api_key_env_var": "MISTRAL_API_KEY"
|
||||
},
|
||||
{
|
||||
"routing_name": "milvus",
|
||||
"display_name": "Milvus",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "groq",
|
||||
"display_name": "Groq",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "a2a",
|
||||
"display_name": "A2A",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "gigachat",
|
||||
"display_name": "Gigachat",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "nvidia_nim",
|
||||
"display_name": "NVIDIA NIM",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "nvidia_riva",
|
||||
"display_name": "NVIDIA Riva",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "soniox",
|
||||
"display_name": "Soniox",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "cerebras",
|
||||
"display_name": "Cerebras",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "ai21_chat",
|
||||
"display_name": "AI21 Chat",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "volcengine",
|
||||
"display_name": "Volcengine",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "codestral",
|
||||
"display_name": "Codestral",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "text-completion-codestral",
|
||||
"display_name": "Text Completion Codestral",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "dashscope",
|
||||
"display_name": "Dashscope",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "modelscope",
|
||||
"display_name": "Modelscope",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "moonshot",
|
||||
"display_name": "Moonshot",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "publicai",
|
||||
"display_name": "Publicai",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "v0",
|
||||
"display_name": "v0",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "morph",
|
||||
"display_name": "Morph",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "lambda_ai",
|
||||
"display_name": "Lambda AI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "inception",
|
||||
"display_name": "Inception",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "text-completion-inception",
|
||||
"display_name": "Text Completion Inception",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "deepseek",
|
||||
"display_name": "Deepseek",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "sambanova",
|
||||
"display_name": "Sambanova",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "maritalk",
|
||||
"display_name": "Maritalk",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "voyage",
|
||||
"display_name": "Voyage",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "cloudflare",
|
||||
"display_name": "Cloudflare",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "xinference",
|
||||
"display_name": "Xinference",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "fireworks_ai",
|
||||
"display_name": "Fireworks AI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "friendliai",
|
||||
"display_name": "Friendliai",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "featherless_ai",
|
||||
"display_name": "Featherless AI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "watsonx",
|
||||
"display_name": "Watsonx",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "watsonx_text",
|
||||
"display_name": "Watsonx Text",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "triton",
|
||||
"display_name": "Triton",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "predibase",
|
||||
"display_name": "Predibase",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "databricks",
|
||||
"display_name": "Databricks",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "empower",
|
||||
"display_name": "Empower",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "github",
|
||||
"display_name": "GitHub",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "ragflow",
|
||||
"display_name": "Ragflow",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "compactifai",
|
||||
"display_name": "Compactifai",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "docker_model_runner",
|
||||
"display_name": "Docker Model Runner",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "custom",
|
||||
"display_name": "Custom",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "litellm_proxy",
|
||||
"display_name": "LiteLLM Proxy",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "hosted_vllm",
|
||||
"display_name": "Hosted vLLM",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "llamafile",
|
||||
"display_name": "Llamafile",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "lm_studio",
|
||||
"display_name": "LM Studio",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "galadriel",
|
||||
"display_name": "Galadriel",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "nebius",
|
||||
"display_name": "Nebius",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "infinity",
|
||||
"display_name": "Infinity",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "deepgram",
|
||||
"display_name": "Deepgram",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "elevenlabs",
|
||||
"display_name": "Elevenlabs",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "novita",
|
||||
"display_name": "Novita",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "aiohttp_openai",
|
||||
"display_name": "AIOHTTP OpenAI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "langfuse",
|
||||
"display_name": "Langfuse",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "humanloop",
|
||||
"display_name": "Humanloop",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "topaz",
|
||||
"display_name": "Topaz",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "sap",
|
||||
"display_name": "Sap Generative AI Hub",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "assemblyai",
|
||||
"display_name": "Assemblyai",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "charity_engine",
|
||||
"display_name": "Charity Engine",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "github_copilot",
|
||||
"display_name": "GitHub Copilot",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "snowflake",
|
||||
"display_name": "Snowflake",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "gradient_ai",
|
||||
"display_name": "Gradient AI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "meta_llama",
|
||||
"display_name": "Llama",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "nscale",
|
||||
"display_name": "Nscale",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "pg_vector",
|
||||
"display_name": "Pg Vector",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "s3_vectors",
|
||||
"display_name": "S3 Vectors",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "helicone",
|
||||
"display_name": "Helicone",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "hyperbolic",
|
||||
"display_name": "Hyperbolic",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "recraft",
|
||||
"display_name": "Recraft",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "fal_ai",
|
||||
"display_name": "Fal AI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "stability",
|
||||
"display_name": "Stability",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "heroku",
|
||||
"display_name": "Heroku",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "aiml",
|
||||
"display_name": "Aiml",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "cometapi",
|
||||
"display_name": "Cometapi",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "oci",
|
||||
"display_name": "OCI",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "auto_router",
|
||||
"display_name": "Auto Router",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "vercel_ai_gateway",
|
||||
"display_name": "Vercel AI Gateway",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "dotprompt",
|
||||
"display_name": "Dotprompt",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "manus",
|
||||
"display_name": "Manus",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "wandb",
|
||||
"display_name": "Wandb",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "ovhcloud",
|
||||
"display_name": "OVHcloud",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "scaleway",
|
||||
"display_name": "Scaleway",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "lemonade",
|
||||
"display_name": "Lemonade",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "amazon_nova",
|
||||
"display_name": "Amazon Nova",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "a2a_agent",
|
||||
"display_name": "A2A Agent",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "langgraph",
|
||||
"display_name": "Langgraph",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "langflow",
|
||||
"display_name": "Langflow",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "minimax",
|
||||
"display_name": "Minimax",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "synthetic",
|
||||
"display_name": "Synthetic",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "apertis",
|
||||
"display_name": "Apertis",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "nano-gpt",
|
||||
"display_name": "NanoGPT",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "poe",
|
||||
"display_name": "Poe",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "chutes",
|
||||
"display_name": "Chutes",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "neosantara",
|
||||
"display_name": "Neosantara",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "parasail",
|
||||
"display_name": "Parasail",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "xiaomi_mimo",
|
||||
"display_name": "Xiaomi MiMo",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "tensormesh",
|
||||
"display_name": "Tensormesh",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "libertai",
|
||||
"display_name": "Libertai",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "pinstripes",
|
||||
"display_name": "Pinstripes",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "darkbloom",
|
||||
"display_name": "Darkbloom",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "litellm_agent",
|
||||
"display_name": "LiteLLM Agent",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "cursor",
|
||||
"display_name": "Cursor",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
},
|
||||
{
|
||||
"routing_name": "bedrock_mantle",
|
||||
"display_name": "Bedrock Mantle",
|
||||
"default_api_base": null,
|
||||
"api_key_env_var": null
|
||||
}
|
||||
]
|
||||
Loading…
Add table
Reference in a new issue