mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
Normalize canonical API formats
This commit is contained in:
@@ -19,44 +19,5 @@ pub(crate) fn read_cached_scheduler_affinity_target(
|
||||
api_format,
|
||||
global_model_name,
|
||||
)?;
|
||||
state
|
||||
.read_cached_scheduler_affinity_target(&cache_key, SCHEDULER_AFFINITY_TTL)
|
||||
.or_else(|| {
|
||||
openai_responses_affinity_alias(api_format)
|
||||
.and_then(|alias| {
|
||||
legacy_raw_scheduler_affinity_cache_key(api_key_id, alias, global_model_name)
|
||||
})
|
||||
.and_then(|alias_cache_key| {
|
||||
state.read_cached_scheduler_affinity_target(
|
||||
&alias_cache_key,
|
||||
SCHEDULER_AFFINITY_TTL,
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn openai_responses_affinity_alias(api_format: &str) -> Option<&'static str> {
|
||||
match api_format.trim().to_ascii_lowercase().as_str() {
|
||||
"openai:responses" => Some("openai:cli"),
|
||||
"openai:responses:compact" => Some("openai:compact"),
|
||||
"openai:cli" => Some("openai:responses"),
|
||||
"openai:compact" => Some("openai:responses:compact"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn legacy_raw_scheduler_affinity_cache_key(
|
||||
api_key_id: &str,
|
||||
api_format: &str,
|
||||
global_model_name: &str,
|
||||
) -> Option<String> {
|
||||
let api_key_id = api_key_id.trim();
|
||||
let api_format = api_format.trim().to_ascii_lowercase();
|
||||
let global_model_name = global_model_name.trim();
|
||||
if api_key_id.is_empty() || api_format.is_empty() || global_model_name.is_empty() {
|
||||
return None;
|
||||
}
|
||||
Some(format!(
|
||||
"scheduler_affinity:{api_key_id}:{api_format}:{global_model_name}"
|
||||
))
|
||||
state.read_cached_scheduler_affinity_target(&cache_key, SCHEDULER_AFFINITY_TTL)
|
||||
}
|
||||
|
||||
@@ -75,9 +75,9 @@ async fn exclusive_required_capability_keeps_hard_filtering_only_matching_keys()
|
||||
incompatible.provider_id = "provider-a".to_string();
|
||||
incompatible.provider_name = "provider-a".to_string();
|
||||
incompatible.endpoint_id = "endpoint-a".to_string();
|
||||
incompatible.endpoint_api_format = "gemini:chat".to_string();
|
||||
incompatible.endpoint_api_format = "gemini:generate_content".to_string();
|
||||
incompatible.endpoint_api_family = Some("gemini".to_string());
|
||||
incompatible.key_api_formats = Some(vec!["gemini:chat".to_string()]);
|
||||
incompatible.key_api_formats = Some(vec!["gemini:generate_content".to_string()]);
|
||||
incompatible.key_id = "key-a".to_string();
|
||||
incompatible.key_name = "alpha".to_string();
|
||||
incompatible.global_model_name = "gemini-2.5-pro".to_string();
|
||||
@@ -87,9 +87,9 @@ async fn exclusive_required_capability_keeps_hard_filtering_only_matching_keys()
|
||||
compatible.provider_id = "provider-b".to_string();
|
||||
compatible.provider_name = "provider-b".to_string();
|
||||
compatible.endpoint_id = "endpoint-b".to_string();
|
||||
compatible.endpoint_api_format = "gemini:chat".to_string();
|
||||
compatible.endpoint_api_format = "gemini:generate_content".to_string();
|
||||
compatible.endpoint_api_family = Some("gemini".to_string());
|
||||
compatible.key_api_formats = Some(vec!["gemini:chat".to_string()]);
|
||||
compatible.key_api_formats = Some(vec!["gemini:generate_content".to_string()]);
|
||||
compatible.key_id = "key-b".to_string();
|
||||
compatible.key_name = "beta".to_string();
|
||||
compatible.global_model_name = "gemini-2.5-pro".to_string();
|
||||
@@ -109,7 +109,7 @@ async fn exclusive_required_capability_keeps_hard_filtering_only_matching_keys()
|
||||
let selection = list_selectable_candidates_for_required_capability_without_requested_model(
|
||||
state.data.as_ref(),
|
||||
&state,
|
||||
"gemini:chat",
|
||||
"gemini:generate_content",
|
||||
"gemini_files",
|
||||
false,
|
||||
None,
|
||||
|
||||
@@ -1385,9 +1385,11 @@ async fn keeps_refreshable_kiro_candidate_selectable_with_runtime_oauth_invalid_
|
||||
row.provider_name = "kiro".to_string();
|
||||
row.provider_type = "kiro".to_string();
|
||||
row.endpoint_id = "endpoint-kiro".to_string();
|
||||
row.endpoint_api_format = "claude:messages".to_string();
|
||||
row.key_id = "key-kiro".to_string();
|
||||
row.key_name = "kiro-refreshable".to_string();
|
||||
row.key_auth_type = "oauth".to_string();
|
||||
row.key_api_formats = Some(vec!["claude:messages".to_string()]);
|
||||
|
||||
let candidates = Arc::new(InMemoryMinimalCandidateSelectionReadRepository::seed(vec![
|
||||
row,
|
||||
@@ -1422,7 +1424,7 @@ async fn keeps_refreshable_kiro_candidate_selectable_with_runtime_oauth_invalid_
|
||||
let (selected, skipped) = collect_selectable_candidates_with_skip_reasons(
|
||||
state.data.as_ref(),
|
||||
&state,
|
||||
"openai:chat",
|
||||
"claude:messages",
|
||||
"gpt-4.1",
|
||||
false,
|
||||
None,
|
||||
@@ -1443,9 +1445,11 @@ async fn keeps_refreshable_kiro_candidate_selectable_when_oauth_token_expired()
|
||||
row.provider_name = "kiro".to_string();
|
||||
row.provider_type = "kiro".to_string();
|
||||
row.endpoint_id = "endpoint-kiro".to_string();
|
||||
row.endpoint_api_format = "claude:messages".to_string();
|
||||
row.key_id = "key-kiro".to_string();
|
||||
row.key_name = "kiro-expired-refreshable".to_string();
|
||||
row.key_auth_type = "oauth".to_string();
|
||||
row.key_api_formats = Some(vec!["claude:messages".to_string()]);
|
||||
|
||||
let candidates = Arc::new(InMemoryMinimalCandidateSelectionReadRepository::seed(vec![
|
||||
row,
|
||||
@@ -1479,7 +1483,7 @@ async fn keeps_refreshable_kiro_candidate_selectable_when_oauth_token_expired()
|
||||
let (selected, skipped) = collect_selectable_candidates_with_skip_reasons(
|
||||
state.data.as_ref(),
|
||||
&state,
|
||||
"openai:chat",
|
||||
"claude:messages",
|
||||
"gpt-4.1",
|
||||
false,
|
||||
None,
|
||||
@@ -1500,9 +1504,11 @@ async fn skips_kiro_candidate_after_refresh_failure_requires_reauth() {
|
||||
row.provider_name = "kiro".to_string();
|
||||
row.provider_type = "kiro".to_string();
|
||||
row.endpoint_id = "endpoint-kiro".to_string();
|
||||
row.endpoint_api_format = "claude:messages".to_string();
|
||||
row.key_id = "key-kiro".to_string();
|
||||
row.key_name = "kiro-refresh-failed".to_string();
|
||||
row.key_auth_type = "oauth".to_string();
|
||||
row.key_api_formats = Some(vec!["claude:messages".to_string()]);
|
||||
|
||||
let candidates = Arc::new(InMemoryMinimalCandidateSelectionReadRepository::seed(vec![
|
||||
row,
|
||||
@@ -1540,7 +1546,7 @@ async fn skips_kiro_candidate_after_refresh_failure_requires_reauth() {
|
||||
let (selected, skipped) = collect_selectable_candidates_with_skip_reasons(
|
||||
state.data.as_ref(),
|
||||
&state,
|
||||
"openai:chat",
|
||||
"claude:messages",
|
||||
"gpt-4.1",
|
||||
false,
|
||||
None,
|
||||
@@ -1562,9 +1568,11 @@ async fn skips_refreshable_kiro_candidate_when_oauth_marker_is_account_block() {
|
||||
row.provider_name = "kiro".to_string();
|
||||
row.provider_type = "kiro".to_string();
|
||||
row.endpoint_id = "endpoint-kiro".to_string();
|
||||
row.endpoint_api_format = "claude:messages".to_string();
|
||||
row.key_id = "key-kiro".to_string();
|
||||
row.key_name = "kiro-account-blocked".to_string();
|
||||
row.key_auth_type = "oauth".to_string();
|
||||
row.key_api_formats = Some(vec!["claude:messages".to_string()]);
|
||||
|
||||
let candidates = Arc::new(InMemoryMinimalCandidateSelectionReadRepository::seed(vec![
|
||||
row,
|
||||
@@ -1599,7 +1607,7 @@ async fn skips_refreshable_kiro_candidate_when_oauth_marker_is_account_block() {
|
||||
let (selected, skipped) = collect_selectable_candidates_with_skip_reasons(
|
||||
state.data.as_ref(),
|
||||
&state,
|
||||
"openai:chat",
|
||||
"claude:messages",
|
||||
"gpt-4.1",
|
||||
false,
|
||||
None,
|
||||
@@ -1702,22 +1710,22 @@ async fn skips_kiro_candidate_when_account_quota_is_exhausted_and_pool_flag_enab
|
||||
first.provider_name = "kiro".to_string();
|
||||
first.provider_type = "kiro".to_string();
|
||||
first.endpoint_id = "endpoint-kiro".to_string();
|
||||
first.endpoint_api_format = "claude:cli".to_string();
|
||||
first.endpoint_api_format = "claude:messages".to_string();
|
||||
first.key_id = "key-kiro".to_string();
|
||||
first.key_name = "kiro-exhausted".to_string();
|
||||
first.key_auth_type = "oauth".to_string();
|
||||
first.key_api_formats = Some(vec!["claude:cli".to_string()]);
|
||||
first.key_global_priority_by_format = Some(serde_json::json!({"claude:cli": 1}));
|
||||
first.key_api_formats = Some(vec!["claude:messages".to_string()]);
|
||||
first.key_global_priority_by_format = Some(serde_json::json!({"claude:messages": 1}));
|
||||
|
||||
let mut second = sample_row();
|
||||
second.provider_id = "provider-openai".to_string();
|
||||
second.provider_name = "openai".to_string();
|
||||
second.endpoint_id = "endpoint-openai".to_string();
|
||||
second.endpoint_api_format = "claude:cli".to_string();
|
||||
second.endpoint_api_format = "claude:messages".to_string();
|
||||
second.key_id = "key-openai".to_string();
|
||||
second.key_name = "fallback".to_string();
|
||||
second.key_api_formats = Some(vec!["claude:cli".to_string()]);
|
||||
second.key_global_priority_by_format = Some(serde_json::json!({"claude:cli": 2}));
|
||||
second.key_api_formats = Some(vec!["claude:messages".to_string()]);
|
||||
second.key_global_priority_by_format = Some(serde_json::json!({"claude:messages": 2}));
|
||||
|
||||
let candidates = Arc::new(InMemoryMinimalCandidateSelectionReadRepository::seed(vec![
|
||||
first, second,
|
||||
@@ -1762,7 +1770,7 @@ async fn skips_kiro_candidate_when_account_quota_is_exhausted_and_pool_flag_enab
|
||||
let (selected, skipped) = collect_selectable_candidates_with_skip_reasons(
|
||||
state.data.as_ref(),
|
||||
&state,
|
||||
"claude:cli",
|
||||
"claude:messages",
|
||||
"gpt-4.1",
|
||||
false,
|
||||
None,
|
||||
@@ -1878,14 +1886,14 @@ async fn same_priority_candidates_use_aggregate_health_score_when_api_format_spe
|
||||
sample_key("key-a", "provider-a", Some(10)).with_health_fields(
|
||||
Some(serde_json::json!({
|
||||
"openai:responses": {"health_score": 0.40},
|
||||
"claude:chat": {"health_score": 0.55}
|
||||
"claude:messages": {"health_score": 0.55}
|
||||
})),
|
||||
None,
|
||||
),
|
||||
sample_key("key-b", "provider-b", Some(10)).with_health_fields(
|
||||
Some(serde_json::json!({
|
||||
"openai:responses": {"health_score": 0.90},
|
||||
"claude:chat": {"health_score": 0.92}
|
||||
"claude:messages": {"health_score": 0.92}
|
||||
})),
|
||||
None,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user