feat: custom global api_url
This commit is contained in:
parent
c4c1272580
commit
808450c48e
7 changed files with 43 additions and 10 deletions
|
|
@ -182,9 +182,18 @@ fn parse_custom_provider_url(
|
|||
}
|
||||
}
|
||||
|
||||
/// Factory: create the right provider from config
|
||||
#[allow(clippy::too_many_lines)]
|
||||
/// Factory: create the right provider from config (without custom URL)
|
||||
pub fn create_provider(name: &str, api_key: Option<&str>) -> anyhow::Result<Box<dyn Provider>> {
|
||||
create_provider_with_url(name, api_key, None)
|
||||
}
|
||||
|
||||
/// Factory: create the right provider from config with optional custom base URL
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn create_provider_with_url(
|
||||
name: &str,
|
||||
api_key: Option<&str>,
|
||||
api_url: Option<&str>,
|
||||
) -> anyhow::Result<Box<dyn Provider>> {
|
||||
let resolved_key = resolve_api_key(name, api_key);
|
||||
let key = resolved_key.as_deref();
|
||||
match name {
|
||||
|
|
@ -192,9 +201,8 @@ pub fn create_provider(name: &str, api_key: Option<&str>) -> anyhow::Result<Box<
|
|||
"openrouter" => Ok(Box::new(openrouter::OpenRouterProvider::new(key))),
|
||||
"anthropic" => Ok(Box::new(anthropic::AnthropicProvider::new(key))),
|
||||
"openai" => Ok(Box::new(openai::OpenAiProvider::new(key))),
|
||||
// Ollama is a local service that doesn't use API keys.
|
||||
// The api_key parameter is ignored to avoid it being misinterpreted as a base_url.
|
||||
"ollama" => Ok(Box::new(ollama::OllamaProvider::new(None))),
|
||||
// Ollama uses api_url for custom base URL (e.g. remote Ollama instance)
|
||||
"ollama" => Ok(Box::new(ollama::OllamaProvider::new(api_url))),
|
||||
"gemini" | "google" | "google-gemini" => {
|
||||
Ok(Box::new(gemini::GeminiProvider::new(key)))
|
||||
}
|
||||
|
|
@ -326,13 +334,14 @@ pub fn create_provider(name: &str, api_key: Option<&str>) -> anyhow::Result<Box<
|
|||
pub fn create_resilient_provider(
|
||||
primary_name: &str,
|
||||
api_key: Option<&str>,
|
||||
api_url: Option<&str>,
|
||||
reliability: &crate::config::ReliabilityConfig,
|
||||
) -> anyhow::Result<Box<dyn Provider>> {
|
||||
let mut providers: Vec<(String, Box<dyn Provider>)> = Vec::new();
|
||||
|
||||
providers.push((
|
||||
primary_name.to_string(),
|
||||
create_provider(primary_name, api_key)?,
|
||||
create_provider_with_url(primary_name, api_key, api_url)?,
|
||||
));
|
||||
|
||||
for fallback in &reliability.fallback_providers {
|
||||
|
|
@ -349,6 +358,7 @@ pub fn create_resilient_provider(
|
|||
);
|
||||
}
|
||||
|
||||
// Fallback providers don't use the custom api_url (it's specific to primary)
|
||||
match create_provider(fallback, api_key) {
|
||||
Ok(provider) => providers.push((fallback.clone(), provider)),
|
||||
Err(e) => {
|
||||
|
|
@ -377,12 +387,13 @@ pub fn create_resilient_provider(
|
|||
pub fn create_routed_provider(
|
||||
primary_name: &str,
|
||||
api_key: Option<&str>,
|
||||
api_url: Option<&str>,
|
||||
reliability: &crate::config::ReliabilityConfig,
|
||||
model_routes: &[crate::config::ModelRouteConfig],
|
||||
default_model: &str,
|
||||
) -> anyhow::Result<Box<dyn Provider>> {
|
||||
if model_routes.is_empty() {
|
||||
return create_resilient_provider(primary_name, api_key, reliability);
|
||||
return create_resilient_provider(primary_name, api_key, api_url, reliability);
|
||||
}
|
||||
|
||||
// Collect unique provider names needed
|
||||
|
|
@ -401,7 +412,9 @@ pub fn create_routed_provider(
|
|||
.find(|r| &r.provider == name)
|
||||
.and_then(|r| r.api_key.as_deref())
|
||||
.or(api_key);
|
||||
match create_resilient_provider(name, key, reliability) {
|
||||
// Only use api_url for the primary provider
|
||||
let url = if name == primary_name { api_url } else { None };
|
||||
match create_resilient_provider(name, key, url, reliability) {
|
||||
Ok(provider) => providers.push((name.clone(), provider)),
|
||||
Err(e) => {
|
||||
if name == primary_name {
|
||||
|
|
@ -761,17 +774,25 @@ mod tests {
|
|||
scheduler_retries: 2,
|
||||
};
|
||||
|
||||
let provider = create_resilient_provider("openrouter", Some("sk-test"), &reliability);
|
||||
let provider = create_resilient_provider("openrouter", Some("sk-test"), None, &reliability);
|
||||
assert!(provider.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resilient_provider_errors_for_invalid_primary() {
|
||||
let reliability = crate::config::ReliabilityConfig::default();
|
||||
let provider = create_resilient_provider("totally-invalid", Some("sk-test"), &reliability);
|
||||
let provider =
|
||||
create_resilient_provider("totally-invalid", Some("sk-test"), None, &reliability);
|
||||
assert!(provider.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ollama_with_custom_url() {
|
||||
let provider =
|
||||
create_provider_with_url("ollama", None, Some("http://10.100.2.32:11434"));
|
||||
assert!(provider.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn factory_all_providers_create_successfully() {
|
||||
let providers = [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue