fix(reliability): validate fallback API key mapping
This commit is contained in:
parent
44ef09da9b
commit
39f2d9dd44
@ -5952,6 +5952,29 @@ impl Config {
|
||||
anyhow::bail!("gateway.host must not be empty");
|
||||
}
|
||||
|
||||
// Reliability
|
||||
let configured_fallbacks = self
|
||||
.reliability
|
||||
.fallback_providers
|
||||
.iter()
|
||||
.map(|provider| provider.trim())
|
||||
.filter(|provider| !provider.is_empty())
|
||||
.collect::<std::collections::HashSet<_>>();
|
||||
for (entry, api_key) in &self.reliability.fallback_api_keys {
|
||||
let normalized_entry = entry.trim();
|
||||
if normalized_entry.is_empty() {
|
||||
anyhow::bail!("reliability.fallback_api_keys contains an empty key");
|
||||
}
|
||||
if api_key.trim().is_empty() {
|
||||
anyhow::bail!("reliability.fallback_api_keys.{normalized_entry} must not be empty");
|
||||
}
|
||||
if !configured_fallbacks.contains(normalized_entry) {
|
||||
anyhow::bail!(
|
||||
"reliability.fallback_api_keys.{normalized_entry} has no matching entry in reliability.fallback_providers"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Autonomy
|
||||
if self.autonomy.max_actions_per_hour == 0 {
|
||||
anyhow::bail!("autonomy.max_actions_per_hour must be greater than 0");
|
||||
@ -10412,6 +10435,40 @@ baseline_syscalls = ["read", "write", "openat", "close"]
|
||||
assert!(err.to_string().contains("gated_domains"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn reliability_validation_rejects_empty_fallback_api_key_value() {
|
||||
let mut config = Config::default();
|
||||
config.reliability.fallback_providers = vec!["openrouter".to_string()];
|
||||
config
|
||||
.reliability
|
||||
.fallback_api_keys
|
||||
.insert("openrouter".to_string(), " ".to_string());
|
||||
|
||||
let err = config
|
||||
.validate()
|
||||
.expect_err("expected fallback_api_keys empty value validation failure");
|
||||
assert!(err
|
||||
.to_string()
|
||||
.contains("reliability.fallback_api_keys.openrouter must not be empty"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn reliability_validation_rejects_unmapped_fallback_api_key_entry() {
|
||||
let mut config = Config::default();
|
||||
config.reliability.fallback_providers = vec!["openrouter".to_string()];
|
||||
config
|
||||
.reliability
|
||||
.fallback_api_keys
|
||||
.insert("anthropic".to_string(), "sk-ant-test".to_string());
|
||||
|
||||
let err = config
|
||||
.validate()
|
||||
.expect_err("expected fallback_api_keys mapping validation failure");
|
||||
assert!(err
|
||||
.to_string()
|
||||
.contains("reliability.fallback_api_keys.anthropic has no matching entry"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn security_validation_rejects_unknown_domain_category() {
|
||||
let mut config = Config::default();
|
||||
|
||||
@ -1442,7 +1442,7 @@ pub fn create_resilient_provider_with_options(
|
||||
Ok(provider) => providers.push((fallback.clone(), provider)),
|
||||
Err(_error) => {
|
||||
tracing::warn!(
|
||||
fallback_provider = fallback,
|
||||
fallback_provider = provider_name,
|
||||
"Ignoring invalid fallback provider during initialization"
|
||||
);
|
||||
}
|
||||
|
||||
@ -90,6 +90,7 @@ async fn fallback_api_keys_support_multiple_custom_endpoints() {
|
||||
|
||||
assert_eq!(reply, "response-from-fallback-two");
|
||||
|
||||
primary_server.verify().await;
|
||||
fallback_server_one.verify().await;
|
||||
fallback_server_two.verify().await;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user