refactor(gateway): 重构格式转换候选资格检查并优化测试基础设施

- 将 format_conversion_disabled 的过滤提前到候选遴选阶段,替代原来的 skip_reason 标记机制
- 为测试添加 execution_runtime_sync_override 直接注入支持,避免启动额外 HTTP 服务器
- 将 submit_terminal_event 改为 async record_terminal_event 确保失败用量事件可靠入库
- 新增 test_support 模块封装可重试的 loopback 端口绑定逻辑
- 前端:poolTrace 将 skipped 从隐藏状态移除,新增 buildPoolParticipatedCandidates 统一新旧链路逻辑,并将 skipped 状态色改为 foreground
This commit is contained in:
fawney19
2026-04-20 16:59:18 +08:00
parent 87afe4898e
commit 226a6e58d5
21 changed files with 380 additions and 247 deletions
@@ -1194,9 +1194,7 @@ mod tests {
assert_eq!(ranked.len(), 1);
assert_eq!(ranked[0].candidate.endpoint_id, "endpoint-same");
assert_eq!(skipped.len(), 1);
assert_eq!(skipped[0].candidate.endpoint_id, "endpoint-cross");
assert_eq!(skipped[0].skip_reason, "format_conversion_disabled");
assert!(skipped.is_empty());
}
#[tokio::test]
@@ -1,7 +1,6 @@
use tracing::warn;
use aether_scheduler_core::SchedulerMinimalCandidateSelectionCandidate;
use std::collections::BTreeSet;
use crate::ai_pipeline::{GatewayProviderTransportSnapshot, PlannerAppState};
use crate::orchestration::LocalExecutionCandidateMetadata;
@@ -101,7 +100,6 @@ where
{
let mut selectable = Vec::with_capacity(candidates.len());
let mut skipped = Vec::new();
let normalized_client_api_format = client_api_format.trim().to_ascii_lowercase();
for candidate in candidates {
let Some(transport) = read_candidate_transport_snapshot(state, &candidate).await else {
@@ -113,6 +111,10 @@ where
});
continue;
};
if candidate_is_ineligible_due_to_disabled_format_conversion(&transport, client_api_format)
{
continue;
}
match runtime_skip_reason(&candidate, &transport) {
Some(skip_reason) => skipped.push(SkippedLocalExecutionCandidate {
candidate,
@@ -129,28 +131,6 @@ where
}
}
let exact_selectable_keys = selectable
.iter()
.filter(|candidate| {
candidate
.provider_api_format
.eq_ignore_ascii_case(normalized_client_api_format.as_str())
})
.map(|candidate| {
(
candidate.candidate.provider_id.clone(),
candidate.candidate.key_id.clone(),
)
})
.collect::<BTreeSet<_>>();
skipped.retain(|candidate| {
candidate.skip_reason != "format_conversion_disabled"
|| !exact_selectable_keys.contains(&(
candidate.candidate.provider_id.clone(),
candidate.candidate.key_id.clone(),
))
});
let ranked = rank_eligible_local_execution_candidates(
state,
selectable,
@@ -234,6 +214,32 @@ fn current_local_execution_candidate_common_skip_reason_with_transport(
None
}
fn candidate_is_ineligible_due_to_disabled_format_conversion(
transport: &GatewayProviderTransportSnapshot,
client_api_format: &str,
) -> bool {
let endpoint_api_format = transport.endpoint.api_format.trim().to_ascii_lowercase();
let client_api_format = client_api_format.trim().to_ascii_lowercase();
if client_api_format == endpoint_api_format {
return false;
}
crate::ai_pipeline::conversion::request_conversion_kind(
client_api_format.as_str(),
endpoint_api_format.as_str(),
)
.is_some()
&& crate::ai_pipeline::conversion::request_conversion_requires_enable_flag(
client_api_format.as_str(),
endpoint_api_format.as_str(),
)
&& !crate::ai_pipeline::conversion::request_conversion_enabled_for_transport(
transport,
client_api_format.as_str(),
endpoint_api_format.as_str(),
)
}
fn current_local_execution_candidate_skip_reason_with_transport(
candidate: &SchedulerMinimalCandidateSelectionCandidate,
transport: &GatewayProviderTransportSnapshot,
@@ -259,25 +265,7 @@ fn current_local_execution_candidate_skip_reason_with_transport(
client_api_format.as_str(),
endpoint_api_format.as_str(),
) {
let skip_reason = if crate::ai_pipeline::conversion::request_conversion_kind(
client_api_format.as_str(),
endpoint_api_format.as_str(),
)
.is_some()
&& crate::ai_pipeline::conversion::request_conversion_requires_enable_flag(
client_api_format.as_str(),
endpoint_api_format.as_str(),
)
&& !crate::ai_pipeline::conversion::request_conversion_enabled_for_transport(
transport,
client_api_format.as_str(),
endpoint_api_format.as_str(),
) {
"format_conversion_disabled"
} else {
"transport_unsupported"
};
return Some(skip_reason);
return Some("transport_unsupported");
}
None