mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-08 18:37:46 +08:00
Merge remote-tracking branch 'zhefox/main' into zhefox-main
# Conflicts: # crates/aether-admin/src/provider/quota.rs # crates/aether-ai/formats/src/formats/openai/chat/stream.rs # crates/aether-ai/formats/src/formats/openai/responses/mod.rs # crates/aether-provider/pool/src/provider.rs # crates/aether-provider/pool/src/quota.rs
This commit is contained in:
@@ -167,6 +167,14 @@ fn parse_pool_score_rules(pool_advanced: &Map<String, Value>) -> PoolMemberScore
|
||||
|
||||
fn normalize_pool_preset_mode(preset: &str, raw_mode: Option<&Value>) -> Option<String> {
|
||||
match preset {
|
||||
"cache_affinity" => Some(
|
||||
raw_mode
|
||||
.and_then(Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|value| matches!(*value, "single_account" | "lru"))
|
||||
.unwrap_or("single_account")
|
||||
.to_string(),
|
||||
),
|
||||
"free_team_first" | "free_first" | "team_first" | "plus_first" | "pro_first" => {
|
||||
let default_mode = match preset {
|
||||
"free_team_first" => "both",
|
||||
|
||||
@@ -1342,6 +1342,7 @@ pub(super) fn build_admin_pool_key_payload(
|
||||
json!(key.internal_priority),
|
||||
);
|
||||
payload.insert("rpm_limit".to_string(), json!(key.rpm_limit));
|
||||
payload.insert("concurrent_limit".to_string(), json!(key.concurrent_limit));
|
||||
payload.insert(
|
||||
"cache_ttl_minutes".to_string(),
|
||||
json!(key.cache_ttl_minutes),
|
||||
|
||||
@@ -3177,6 +3177,7 @@ async fn provider_query_execute_standard_test_candidate(
|
||||
crate::ai_serving::openai_responses_reasoning_replay_policy(
|
||||
transport.provider.provider_type.as_str(),
|
||||
transport.endpoint.base_url.as_str(),
|
||||
request_model,
|
||||
),
|
||||
)
|
||||
else {
|
||||
@@ -3238,6 +3239,7 @@ async fn provider_query_execute_standard_test_candidate(
|
||||
crate::ai_serving::openai_responses_reasoning_replay_policy(
|
||||
transport.provider.provider_type.as_str(),
|
||||
transport.endpoint.base_url.as_str(),
|
||||
request_model,
|
||||
),
|
||||
)
|
||||
.is_err()
|
||||
|
||||
@@ -34,6 +34,22 @@ fn admin_user_id_from_billing_path(request_path: &str, suffix: &str) -> Option<S
|
||||
}
|
||||
}
|
||||
|
||||
fn admin_user_entitlement_ids_from_path(request_path: &str) -> Option<(String, String)> {
|
||||
let rest = request_path
|
||||
.trim_end_matches('/')
|
||||
.strip_prefix("/api/admin/users/")?;
|
||||
let mut parts = rest.split('/');
|
||||
let user_id = parts.next()?.trim();
|
||||
if parts.next()? != "billing" || parts.next()? != "entitlements" {
|
||||
return None;
|
||||
}
|
||||
let entitlement_id = parts.next()?.trim();
|
||||
if user_id.is_empty() || entitlement_id.is_empty() || parts.next().is_some() {
|
||||
return None;
|
||||
}
|
||||
Some((user_id.to_string(), entitlement_id.to_string()))
|
||||
}
|
||||
|
||||
fn admin_user_billing_operator_id(request_context: &AdminRequestContext<'_>) -> Option<String> {
|
||||
request_context
|
||||
.decision()
|
||||
@@ -202,6 +218,60 @@ pub(in super::super) async fn build_admin_list_user_billing_entitlements_respons
|
||||
}
|
||||
}
|
||||
|
||||
pub(in super::super) async fn build_admin_revoke_user_billing_entitlement_response(
|
||||
state: &AdminAppState<'_>,
|
||||
request_context: &AdminRequestContext<'_>,
|
||||
) -> Result<Response<Body>, GatewayError> {
|
||||
let Some((user_id, entitlement_id)) =
|
||||
admin_user_entitlement_ids_from_path(request_context.path())
|
||||
else {
|
||||
return Ok(build_admin_users_bad_request_response("缺少套餐权益 ID"));
|
||||
};
|
||||
if state.find_user_auth_by_id(&user_id).await?.is_none() {
|
||||
return Ok((
|
||||
http::StatusCode::NOT_FOUND,
|
||||
Json(json!({ "detail": "用户不存在" })),
|
||||
)
|
||||
.into_response());
|
||||
}
|
||||
match state
|
||||
.app()
|
||||
.revoke_user_plan_entitlement(&user_id, &entitlement_id)
|
||||
.await?
|
||||
{
|
||||
crate::LocalMutationOutcome::Applied(()) => {}
|
||||
crate::LocalMutationOutcome::NotFound => {
|
||||
return Ok((
|
||||
http::StatusCode::NOT_FOUND,
|
||||
Json(json!({ "detail": "套餐权益不存在或已失效" })),
|
||||
)
|
||||
.into_response());
|
||||
}
|
||||
crate::LocalMutationOutcome::Invalid(detail) => {
|
||||
return Ok(build_admin_users_bad_request_response(detail));
|
||||
}
|
||||
crate::LocalMutationOutcome::Unavailable => {
|
||||
return Ok(build_admin_users_data_unavailable_response());
|
||||
}
|
||||
}
|
||||
let entitlements = match load_admin_user_entitlements_payload(state, &user_id).await? {
|
||||
Some(value) => value,
|
||||
None => return Ok(build_admin_users_data_unavailable_response()),
|
||||
};
|
||||
Ok(attach_admin_audit_response(
|
||||
Json(json!({
|
||||
"items": entitlements["items"].clone(),
|
||||
"entitlements": entitlements["items"].clone(),
|
||||
"total": entitlements["total"].clone(),
|
||||
}))
|
||||
.into_response(),
|
||||
"admin_user_plan_revoked",
|
||||
"revoke_user_billing_entitlement",
|
||||
"user_plan_entitlement",
|
||||
&entitlement_id,
|
||||
))
|
||||
}
|
||||
|
||||
pub(in super::super) async fn build_admin_grant_user_billing_plan_response(
|
||||
state: &AdminAppState<'_>,
|
||||
request_context: &AdminRequestContext<'_>,
|
||||
|
||||
@@ -28,6 +28,7 @@ use self::batch::{
|
||||
use self::billing::{
|
||||
build_admin_grant_user_billing_plan_response,
|
||||
build_admin_list_user_billing_entitlements_response,
|
||||
build_admin_revoke_user_billing_entitlement_response,
|
||||
};
|
||||
use self::groups::{
|
||||
build_admin_create_user_group_response, build_admin_delete_user_group_response,
|
||||
|
||||
@@ -8,10 +8,11 @@ use super::{
|
||||
build_admin_list_user_group_members_response, build_admin_list_user_groups_response,
|
||||
build_admin_list_user_sessions_response, build_admin_list_users_response,
|
||||
build_admin_replace_user_group_members_response, build_admin_resolve_user_selection_response,
|
||||
build_admin_reveal_user_api_key_response, build_admin_set_default_user_group_response,
|
||||
build_admin_toggle_user_api_key_lock_response, build_admin_update_user_api_key_response,
|
||||
build_admin_update_user_group_response, build_admin_update_user_response,
|
||||
build_admin_user_batch_action_response, build_admin_users_data_unavailable_response,
|
||||
build_admin_reveal_user_api_key_response, build_admin_revoke_user_billing_entitlement_response,
|
||||
build_admin_set_default_user_group_response, build_admin_toggle_user_api_key_lock_response,
|
||||
build_admin_update_user_api_key_response, build_admin_update_user_group_response,
|
||||
build_admin_update_user_response, build_admin_user_batch_action_response,
|
||||
build_admin_users_data_unavailable_response,
|
||||
};
|
||||
use crate::handlers::admin::request::{AdminAppState, AdminRequestContext};
|
||||
use crate::GatewayError;
|
||||
@@ -58,6 +59,10 @@ fn is_admin_users_route(request_context: &AdminRequestContext<'_>) -> bool {
|
||||
&& path.starts_with("/api/admin/users/")
|
||||
&& path.ends_with("/billing/grant-plan")
|
||||
&& path.matches('/').count() == 6)
|
||||
|| (request_context.method() == http::Method::DELETE
|
||||
&& path.starts_with("/api/admin/users/")
|
||||
&& path.contains("/billing/entitlements/")
|
||||
&& path.matches('/').count() == 7)
|
||||
|| ((request_context.method() == http::Method::GET
|
||||
|| request_context.method() == http::Method::PUT
|
||||
|| request_context.method() == http::Method::DELETE)
|
||||
@@ -155,6 +160,9 @@ pub(super) async fn maybe_build_local_admin_users_routes_response(
|
||||
build_admin_grant_user_billing_plan_response(state, request_context, request_body)
|
||||
.await?,
|
||||
)),
|
||||
Some("revoke_user_billing_entitlement") => Ok(Some(
|
||||
build_admin_revoke_user_billing_entitlement_response(state, request_context).await?,
|
||||
)),
|
||||
Some("get_user") => Ok(Some(
|
||||
build_admin_get_user_response(state, request_context).await?,
|
||||
)),
|
||||
|
||||
Reference in New Issue
Block a user