mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-13 04:29:50 +08:00
refactor: 大规模模块拆分与重组,新增 aether-admin crate
- 新建独立 aether-admin crate 承载 admin 相关共享契约与纯辅助函数 - 拆分 ai_pipeline 下 kiro/private_envelope/conversion/planner 等大文件为子模块目录 - 重组 admin handlers 各业务域(billing/oauth/provider/system/users 等)为目录结构,移除 shared.rs/builders.rs 等反模式 - 移除 ai_pipeline runtime adapters 旧实现(claude/openai/gemini/kiro/vertex/antigravity 等),改由 provider transport 统一承载 - 移除 control_facade/execution_facade/auth_snapshot_facade 等冗余 facade 层 - 拆分 query/billing 与 query/monitoring 模块、state/runtime/payments 与 security 模块 - 扩展架构测试覆盖 admin_billing/admin_model/admin_users 等新模块 - 删除 docs/architecture/refactor-execution-plan.md 已完成的执行计划文档
This commit is contained in:
@@ -4,86 +4,25 @@ use super::shared::{
|
||||
quota_refresh_success_invalid_state, ProviderQuotaExecutionOutcome,
|
||||
};
|
||||
use crate::handlers::admin::provider::shared::payloads::ANTIGRAVITY_FETCH_AVAILABLE_MODELS_PATH;
|
||||
use crate::{AppState, GatewayError};
|
||||
use crate::handlers::admin::request::{AdminAppState, AdminGatewayProviderTransportSnapshot};
|
||||
use crate::GatewayError;
|
||||
use aether_admin::provider::quota::parse_antigravity_usage_response;
|
||||
use aether_contracts::{ExecutionPlan, ExecutionTimeouts, RequestBody};
|
||||
use aether_data_contracts::repository::provider_catalog::{
|
||||
StoredProviderCatalogEndpoint, StoredProviderCatalogKey, StoredProviderCatalogProvider,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::collections::BTreeMap;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
fn parse_antigravity_usage_response(
|
||||
value: &serde_json::Value,
|
||||
updated_at_unix_secs: u64,
|
||||
) -> Option<serde_json::Value> {
|
||||
let models = value.get("models")?.as_object()?;
|
||||
let mut quota_by_model = serde_json::Map::new();
|
||||
|
||||
for (model_id, model_value) in models {
|
||||
let mut payload = serde_json::Map::new();
|
||||
if let Some(display_name) = coerce_json_string(
|
||||
model_value
|
||||
.get("displayName")
|
||||
.or_else(|| model_value.get("display_name")),
|
||||
) {
|
||||
payload.insert("display_name".to_string(), json!(display_name));
|
||||
}
|
||||
|
||||
let quota_info = model_value
|
||||
.get("quotaInfo")
|
||||
.and_then(serde_json::Value::as_object);
|
||||
let remaining_fraction = quota_info
|
||||
.and_then(|object| object.get("remainingFraction"))
|
||||
.and_then(coerce_json_f64);
|
||||
let used_percent = remaining_fraction
|
||||
.map(|value| ((1.0 - value).max(0.0) * 100.0).min(100.0))
|
||||
.unwrap_or(100.0);
|
||||
payload.insert(
|
||||
"remaining_fraction".to_string(),
|
||||
json!(remaining_fraction.unwrap_or(0.0)),
|
||||
);
|
||||
payload.insert("used_percent".to_string(), json!(used_percent));
|
||||
if let Some(reset_time) = quota_info
|
||||
.and_then(|object| object.get("resetTime"))
|
||||
.cloned()
|
||||
.filter(|value| !value.is_null())
|
||||
{
|
||||
payload.insert("reset_time".to_string(), reset_time);
|
||||
}
|
||||
quota_by_model.insert(model_id.clone(), serde_json::Value::Object(payload));
|
||||
}
|
||||
|
||||
Some(json!({
|
||||
"updated_at": updated_at_unix_secs,
|
||||
"is_forbidden": false,
|
||||
"forbidden_reason": serde_json::Value::Null,
|
||||
"forbidden_at": serde_json::Value::Null,
|
||||
"models": quota_by_model,
|
||||
}))
|
||||
}
|
||||
|
||||
async fn execute_antigravity_quota_plan(
|
||||
state: &AppState,
|
||||
transport: &crate::provider_transport::GatewayProviderTransportSnapshot,
|
||||
state: &AdminAppState<'_>,
|
||||
transport: &AdminGatewayProviderTransportSnapshot,
|
||||
authorization: (String, String),
|
||||
project_id: &str,
|
||||
auth: &crate::provider_transport::antigravity::AntigravityRequestAuthSupport,
|
||||
mut identity_headers: BTreeMap<String, String>,
|
||||
) -> Result<ProviderQuotaExecutionOutcome, GatewayError> {
|
||||
let supported_auth = match auth {
|
||||
crate::provider_transport::antigravity::AntigravityRequestAuthSupport::Supported(auth) => {
|
||||
auth
|
||||
}
|
||||
crate::provider_transport::antigravity::AntigravityRequestAuthSupport::Unsupported(_) => {
|
||||
return Ok(ProviderQuotaExecutionOutcome::Failure(
|
||||
"缺少 OAuth 认证信息,请先授权/刷新 Token".to_string(),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let mut headers =
|
||||
crate::provider_transport::antigravity::build_antigravity_static_identity_headers(
|
||||
supported_auth,
|
||||
);
|
||||
let mut headers = std::mem::take(&mut identity_headers);
|
||||
headers.insert("authorization".to_string(), authorization.1);
|
||||
headers.insert("content-type".to_string(), "application/json".to_string());
|
||||
headers.insert("accept".to_string(), "application/json".to_string());
|
||||
@@ -117,28 +56,27 @@ async fn execute_antigravity_quota_plan(
|
||||
client_api_format: "gemini:chat".to_string(),
|
||||
provider_api_format: "antigravity:fetch_available_models".to_string(),
|
||||
model_name: Some("fetchAvailableModels".to_string()),
|
||||
proxy: crate::provider_transport::resolve_transport_proxy_snapshot_with_tunnel_affinity(
|
||||
state, transport,
|
||||
)
|
||||
.await,
|
||||
tls_profile: crate::provider_transport::resolve_transport_tls_profile(transport),
|
||||
timeouts: crate::provider_transport::resolve_transport_execution_timeouts(transport).or(
|
||||
Some(ExecutionTimeouts {
|
||||
proxy: state
|
||||
.resolve_transport_proxy_snapshot_with_tunnel_affinity(transport)
|
||||
.await,
|
||||
tls_profile: state.resolve_transport_tls_profile(transport),
|
||||
timeouts: state
|
||||
.resolve_transport_execution_timeouts(transport)
|
||||
.or(Some(ExecutionTimeouts {
|
||||
connect_ms: Some(30_000),
|
||||
read_ms: Some(30_000),
|
||||
write_ms: Some(30_000),
|
||||
pool_ms: Some(30_000),
|
||||
total_ms: Some(30_000),
|
||||
..ExecutionTimeouts::default()
|
||||
}),
|
||||
),
|
||||
})),
|
||||
};
|
||||
|
||||
execute_provider_quota_plan(state, transport, plan, "antigravity").await
|
||||
}
|
||||
|
||||
pub(crate) async fn refresh_antigravity_provider_quota_locally(
|
||||
state: &AppState,
|
||||
state: &AdminAppState<'_>,
|
||||
provider: &StoredProviderCatalogProvider,
|
||||
endpoint: &StoredProviderCatalogEndpoint,
|
||||
keys: Vec<StoredProviderCatalogKey>,
|
||||
@@ -165,11 +103,8 @@ pub(crate) async fn refresh_antigravity_provider_quota_locally(
|
||||
}
|
||||
};
|
||||
|
||||
let authorization = match state.resolve_local_oauth_request_auth(&transport).await? {
|
||||
Some(crate::provider_transport::LocalResolvedOAuthRequestAuth::Header {
|
||||
name,
|
||||
value,
|
||||
}) => (name, value),
|
||||
let authorization = match state.resolve_local_oauth_header_auth(&transport).await? {
|
||||
Some(auth) => auth,
|
||||
_ => {
|
||||
failed_count += 1;
|
||||
results.push(json!({
|
||||
@@ -182,26 +117,17 @@ pub(crate) async fn refresh_antigravity_provider_quota_locally(
|
||||
}
|
||||
};
|
||||
|
||||
let antigravity_auth =
|
||||
crate::provider_transport::antigravity::resolve_local_antigravity_request_auth(
|
||||
&transport,
|
||||
);
|
||||
let project_id = match &antigravity_auth {
|
||||
crate::provider_transport::antigravity::AntigravityRequestAuthSupport::Supported(
|
||||
auth,
|
||||
) => auth.project_id.clone(),
|
||||
crate::provider_transport::antigravity::AntigravityRequestAuthSupport::Unsupported(
|
||||
_,
|
||||
) => {
|
||||
failed_count += 1;
|
||||
results.push(json!({
|
||||
"key_id": key.id,
|
||||
"key_name": key.name,
|
||||
"status": "error",
|
||||
"message": "缺少 OAuth 认证信息,请先授权/刷新 Token",
|
||||
}));
|
||||
continue;
|
||||
}
|
||||
let Some((project_id, identity_headers)) =
|
||||
state.resolve_local_antigravity_identity_headers(&transport)
|
||||
else {
|
||||
failed_count += 1;
|
||||
results.push(json!({
|
||||
"key_id": key.id,
|
||||
"key_name": key.name,
|
||||
"status": "error",
|
||||
"message": "缺少 OAuth 认证信息,请先授权/刷新 Token",
|
||||
}));
|
||||
continue;
|
||||
};
|
||||
|
||||
let result = match execute_antigravity_quota_plan(
|
||||
@@ -209,7 +135,7 @@ pub(crate) async fn refresh_antigravity_provider_quota_locally(
|
||||
&transport,
|
||||
authorization,
|
||||
&project_id,
|
||||
&antigravity_auth,
|
||||
identity_headers,
|
||||
)
|
||||
.await?
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user