refactor: 移除 Python upstream 依赖,清理全部 legacy/Python 兼容层

- 移除 upstream_base_url 参数及 AETHER_GATEWAY_UPSTREAM 环境变量,gateway 不再需要指向 Python 宿主
- 删除所有 LEGACY_*/PYTHON_* 常量、路由组、header 定义及 sunset/phaseout 机制
- 将 legacy_gateway_bridge 重命名为 internal_gateway,executor 相关命名统一为 execution_runtime
- dev.sh 新增 Postgres/Redis 预检查,移除 upstream 相关启动参数和提示
- 新增 ai_public 路由处理器
- 全量适配 handler、test、state、control 等模块的命名和接口变更
This commit is contained in:
fawney19
2026-04-04 01:40:24 +08:00
parent 1d9c77522a
commit cbc811f6ce
484 changed files with 11046 additions and 3925 deletions

View File

@@ -1,4 +1,13 @@
use super::*;
use sha2::{Digest, Sha256};
use crate::gateway::gateway_cache::SchedulerAffinityTarget;
use crate::gateway::gateway_data::StoredGatewayAuthApiKeySnapshot;
use crate::gateway::AppState;
use super::{
normalize_api_format, GatewayMinimalCandidateSelectionCandidate,
SCHEDULER_AFFINITY_MAX_ENTRIES, SCHEDULER_AFFINITY_TTL,
};
pub(super) fn build_scheduler_affinity_cache_key(
auth_snapshot: Option<&StoredGatewayAuthApiKeySnapshot>,

View File

@@ -1,4 +1,14 @@
use super::*;
use std::collections::BTreeSet;
use aether_data::repository::candidate_selection::{
StoredMinimalCandidateSelectionRow, StoredProviderModelMapping,
};
use aether_data::DataLayerError;
use regex::Regex;
use crate::gateway::gateway_data::{GatewayDataState, StoredGatewayAuthApiKeySnapshot};
use super::GatewayMinimalCandidateSelectionCandidate;
pub(super) fn auth_snapshot_allows_provider(
auth_snapshot: Option<&StoredGatewayAuthApiKeySnapshot>,

View File

@@ -1,4 +1,26 @@
use super::*;
use std::collections::{BTreeMap, BTreeSet};
use aether_data::repository::candidates::StoredRequestCandidate;
use aether_data::repository::provider_catalog::{
StoredProviderCatalogKey, StoredProviderCatalogProvider,
};
use aether_data::repository::quota::StoredProviderQuotaSnapshot;
use aether_wallet::{ProviderBillingType, ProviderQuotaSnapshot};
use crate::gateway::gateway_cache::SchedulerAffinityTarget;
use crate::gateway::gateway_data::StoredGatewayAuthApiKeySnapshot;
use crate::gateway::{AppState, GatewayError};
use super::super::health::{
count_recent_active_requests_for_provider, effective_provider_key_health_score,
is_candidate_in_recent_failure_cooldown, is_provider_key_circuit_open,
provider_key_health_bucket, provider_key_health_score, provider_key_rpm_allows_request_since,
ProviderKeyHealthBucket,
};
use super::{
compare_affinity_order, matches_affinity_target, GatewayMinimalCandidateSelectionCandidate,
};
pub(super) fn reorder_candidates_by_scheduler_health(
candidates: &mut [GatewayMinimalCandidateSelectionCandidate],
@@ -45,7 +67,7 @@ fn compare_provider_key_health_order(
fn candidate_provider_key_health_bucket(
candidate: &GatewayMinimalCandidateSelectionCandidate,
provider_key_rpm_states: &BTreeMap<String, StoredProviderCatalogKey>,
) -> Option<super::super::health::ProviderKeyHealthBucket> {
) -> Option<ProviderKeyHealthBucket> {
provider_key_rpm_states
.get(&candidate.key_id)
.and_then(|key| provider_key_health_bucket(key, candidate.endpoint_api_format.as_str()))

View File

@@ -293,7 +293,7 @@ async fn selects_next_candidate_when_first_provider_quota_is_exhausted() {
)
.expect("quota should build"),
]));
let state = AppState::new("http://127.0.0.1:1")
let state = AppState::new()
.expect("state should build")
.with_data_state_for_tests(
GatewayDataState::with_candidate_selection_and_quota_for_tests(candidates, quotas),
@@ -398,7 +398,7 @@ async fn cooled_down_when_recent_failures_are_recorded_for_same_key() {
)
.expect("candidate should build"),
]));
let state = AppState::new("http://127.0.0.1:1")
let state = AppState::new()
.expect("state should build")
.with_data_state_for_tests(
GatewayDataState::with_candidate_selection_quota_and_request_candidates_for_tests(
@@ -608,7 +608,7 @@ async fn reuses_cached_scheduler_affinity_candidate_before_sorted_fallback() {
first, second,
]));
let quotas = Arc::new(InMemoryProviderQuotaRepository::seed(vec![]));
let state = AppState::new("http://127.0.0.1:1")
let state = AppState::new()
.expect("state should build")
.with_data_state_for_tests(
GatewayDataState::with_candidate_selection_and_quota_for_tests(candidates, quotas),
@@ -728,7 +728,7 @@ async fn selects_next_candidate_when_first_provider_concurrent_limit_is_reached(
)
.expect("candidate should build"),
]));
let state = AppState::new("http://127.0.0.1:1")
let state = AppState::new()
.expect("state should build")
.with_data_state_for_tests(
GatewayDataState::with_candidate_selection_provider_catalog_quota_and_request_candidates_for_tests(
@@ -788,7 +788,7 @@ async fn returns_none_when_auth_api_key_concurrent_limit_is_reached() {
)
.expect("candidate should build"),
]));
let state = AppState::new("http://127.0.0.1:1")
let state = AppState::new()
.expect("state should build")
.with_data_state_for_tests(
GatewayDataState::with_candidate_selection_provider_catalog_quota_and_request_candidates_for_tests(
@@ -901,7 +901,7 @@ async fn selects_next_candidate_when_first_provider_key_rpm_slots_are_reserved_f
)
.expect("candidate should build"),
]));
let state = AppState::new("http://127.0.0.1:1")
let state = AppState::new()
.expect("state should build")
.with_data_state_for_tests(
GatewayDataState::with_candidate_selection_provider_catalog_quota_and_request_candidates_for_tests(
@@ -1016,7 +1016,7 @@ async fn cached_affinity_candidate_can_use_reserved_provider_key_rpm_capacity()
)
.expect("candidate should build"),
]));
let state = AppState::new("http://127.0.0.1:1")
let state = AppState::new()
.expect("state should build")
.with_data_state_for_tests(
GatewayDataState::with_candidate_selection_provider_catalog_quota_and_request_candidates_for_tests(
@@ -1119,7 +1119,7 @@ async fn selects_next_candidate_when_first_provider_key_circuit_is_open() {
));
let quotas = Arc::new(InMemoryProviderQuotaRepository::seed(vec![]));
let request_candidates = Arc::new(InMemoryRequestCandidateRepository::seed(vec![]));
let state = AppState::new("http://127.0.0.1:1")
let state = AppState::new()
.expect("state should build")
.with_data_state_for_tests(
GatewayDataState::with_candidate_selection_provider_catalog_quota_and_request_candidates_for_tests(
@@ -1179,7 +1179,7 @@ async fn same_priority_candidates_prefer_healthier_provider_key_before_id_order(
));
let quotas = Arc::new(InMemoryProviderQuotaRepository::seed(vec![]));
let request_candidates = Arc::new(InMemoryRequestCandidateRepository::seed(vec![]));
let state = AppState::new("http://127.0.0.1:1")
let state = AppState::new()
.expect("state should build")
.with_data_state_for_tests(
GatewayDataState::with_candidate_selection_provider_catalog_quota_and_request_candidates_for_tests(
@@ -1246,7 +1246,7 @@ async fn same_priority_candidates_use_aggregate_health_score_when_api_format_spe
));
let quotas = Arc::new(InMemoryProviderQuotaRepository::seed(vec![]));
let request_candidates = Arc::new(InMemoryRequestCandidateRepository::seed(vec![]));
let state = AppState::new("http://127.0.0.1:1")
let state = AppState::new()
.expect("state should build")
.with_data_state_for_tests(
GatewayDataState::with_candidate_selection_provider_catalog_quota_and_request_candidates_for_tests(