mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-04 08:27:46 +08:00
Merge branch 'fawney19:main' into main
This commit is contained in:
+12
-1
@@ -53,6 +53,15 @@ fn admin_usage_aggregation_by_provider_json(
|
||||
json!(rows
|
||||
.iter()
|
||||
.map(|row| {
|
||||
let identity_source = match row.secondary_name.as_deref() {
|
||||
Some("legacy_name") => "legacy_name",
|
||||
_ => "provider_id",
|
||||
};
|
||||
let provider_id = if identity_source == "provider_id" {
|
||||
json!(row.group_key)
|
||||
} else {
|
||||
serde_json::Value::Null
|
||||
};
|
||||
let success_count = row.success_count.unwrap_or_default();
|
||||
let error_count = row.request_count.saturating_sub(success_count);
|
||||
let success_rate = if row.request_count == 0 {
|
||||
@@ -67,7 +76,9 @@ fn admin_usage_aggregation_by_provider_json(
|
||||
.filter(|value| !value.is_empty())
|
||||
.unwrap_or(row.group_key.as_str());
|
||||
json!({
|
||||
"provider_id": row.group_key,
|
||||
"provider_id": provider_id,
|
||||
"provider_key": row.group_key,
|
||||
"provider_identity_source": identity_source,
|
||||
"provider": provider_name,
|
||||
"request_count": row.request_count,
|
||||
"total_tokens": row.total_tokens,
|
||||
|
||||
@@ -2,7 +2,9 @@ use super::state::{
|
||||
decode_jwt_claims, enrich_admin_provider_oauth_auth_config, json_non_empty_string,
|
||||
json_u64_value,
|
||||
};
|
||||
use crate::handlers::admin::admin_provider_pool_config;
|
||||
use crate::handlers::admin::request::AdminAppState;
|
||||
use crate::maintenance::ensure_provider_key_pool_scores_for_keys;
|
||||
use crate::provider_key_auth::provider_active_api_formats;
|
||||
use crate::GatewayError;
|
||||
use aether_data_contracts::repository::provider_catalog::{
|
||||
@@ -168,6 +170,7 @@ pub(crate) async fn create_provider_oauth_catalog_key(
|
||||
.app()
|
||||
.invalidate_local_oauth_refresh_entry(&key.id)
|
||||
.await;
|
||||
seed_provider_oauth_pool_score(state, provider_id, key, now_unix_secs).await;
|
||||
}
|
||||
Ok(created)
|
||||
}
|
||||
@@ -221,10 +224,75 @@ pub(crate) async fn update_existing_provider_oauth_catalog_key(
|
||||
.app()
|
||||
.invalidate_local_oauth_refresh_entry(&key.id)
|
||||
.await;
|
||||
seed_provider_oauth_pool_score(state, &existing_key.provider_id, key, now_unix_secs).await;
|
||||
}
|
||||
Ok(persisted)
|
||||
}
|
||||
|
||||
async fn seed_provider_oauth_pool_score(
|
||||
state: &AdminAppState<'_>,
|
||||
provider_id: &str,
|
||||
key: &StoredProviderCatalogKey,
|
||||
now_unix_secs: u64,
|
||||
) {
|
||||
let provider_id = provider_id.to_string();
|
||||
let provider = match state
|
||||
.read_provider_catalog_providers_by_ids(std::slice::from_ref(&provider_id))
|
||||
.await
|
||||
{
|
||||
Ok(mut providers) => providers.pop(),
|
||||
Err(err) => {
|
||||
tracing::debug!(
|
||||
provider_id = %provider_id,
|
||||
key_id = %key.id,
|
||||
error = ?err,
|
||||
"gateway provider oauth provisioning: failed to read provider for pool score seed"
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let Some(provider) = provider else {
|
||||
return;
|
||||
};
|
||||
let Some(pool_config) = admin_provider_pool_config(&provider) else {
|
||||
return;
|
||||
};
|
||||
let endpoints = match state
|
||||
.list_provider_catalog_endpoints_by_provider_ids(std::slice::from_ref(&provider_id))
|
||||
.await
|
||||
{
|
||||
Ok(endpoints) => endpoints,
|
||||
Err(err) => {
|
||||
tracing::debug!(
|
||||
provider_id = %provider_id,
|
||||
key_id = %key.id,
|
||||
error = ?err,
|
||||
"gateway provider oauth provisioning: failed to read endpoints for pool score seed"
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let score_ensure_budget = (pool_config.score_fallback_scan_limit as usize).clamp(1, 50_000);
|
||||
if let Err(err) = ensure_provider_key_pool_scores_for_keys(
|
||||
state.as_ref(),
|
||||
&provider,
|
||||
&pool_config,
|
||||
&endpoints,
|
||||
std::slice::from_ref(key),
|
||||
now_unix_secs,
|
||||
score_ensure_budget,
|
||||
)
|
||||
.await
|
||||
{
|
||||
tracing::debug!(
|
||||
provider_id = %provider_id,
|
||||
key_id = %key.id,
|
||||
error = ?err,
|
||||
"gateway provider oauth provisioning: failed to seed pool score row"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn provider_oauth_catalog_key_api_formats(
|
||||
provider_type: &str,
|
||||
api_formats: &[String],
|
||||
|
||||
@@ -115,6 +115,30 @@ pub(crate) const ADMIN_MODULE_DEFINITIONS: &[AdminModuleDefinition] = &[
|
||||
admin_menu_group: Some("system"),
|
||||
admin_menu_order: 60,
|
||||
},
|
||||
AdminModuleDefinition {
|
||||
name: "payment_gateways",
|
||||
display_name: "支付配置",
|
||||
description: "配置易支付、支付宝官方、微信支付官方和 Stripe 等支付网关",
|
||||
category: "integration",
|
||||
env_key: "PAYMENT_GATEWAYS_AVAILABLE",
|
||||
default_available: true,
|
||||
admin_route: Some("/admin/payment-gateways"),
|
||||
admin_menu_icon: Some("CreditCard"),
|
||||
admin_menu_group: None,
|
||||
admin_menu_order: 70,
|
||||
},
|
||||
AdminModuleDefinition {
|
||||
name: "referral",
|
||||
display_name: "邀请返利",
|
||||
description: "管理用户邀请关系与返利记录,支持比例返利和人头返利",
|
||||
category: "integration",
|
||||
env_key: "REFERRAL_AVAILABLE",
|
||||
default_available: true,
|
||||
admin_route: Some("/admin/referrals"),
|
||||
admin_menu_icon: Some("Gift"),
|
||||
admin_menu_group: Some("management"),
|
||||
admin_menu_order: 75,
|
||||
},
|
||||
];
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize)]
|
||||
|
||||
@@ -46,7 +46,7 @@ pub(crate) async fn build_admin_keys_grouped_by_format_payload(
|
||||
|
||||
let (endpoints_result, keys_result) = tokio::join!(
|
||||
state.list_provider_catalog_endpoints_by_provider_ids(&provider_ids),
|
||||
state.list_provider_catalog_key_summaries_by_provider_ids(&provider_ids),
|
||||
state.list_provider_catalog_keys_by_provider_ids(&provider_ids),
|
||||
);
|
||||
|
||||
let active_endpoints = endpoints_result
|
||||
|
||||
Reference in New Issue
Block a user