feat(grok): add admin oauth and quota support

This commit is contained in:
mayrain
2026-05-16 21:15:38 +08:00
parent cbfe1d378f
commit 936e1ae37b
61 changed files with 4748 additions and 287 deletions
@@ -32,7 +32,7 @@ pub(super) async fn maybe_handle(
.into_response(),
));
};
let Some(_provider) = state
let Some(provider) = state
.read_provider_catalog_providers_by_ids(std::slice::from_ref(&provider_id))
.await?
.into_iter()
@@ -129,7 +129,9 @@ pub(super) async fn maybe_handle(
Json(serde_json::Value::Array(
created
.iter()
.map(|model| build_admin_provider_model_response(model, now_unix_secs))
.map(|model| {
build_admin_provider_model_response(&provider, model, now_unix_secs)
})
.collect(),
))
.into_response(),
@@ -31,7 +31,7 @@ pub(super) async fn maybe_handle(
.into_response(),
));
};
let Some(_provider) = state
let Some(provider) = state
.read_provider_catalog_providers_by_ids(std::slice::from_ref(&provider_id))
.await?
.into_iter()
@@ -90,8 +90,12 @@ pub(super) async fn maybe_handle(
.ok()
.map(|duration| duration.as_secs())
.unwrap_or(0);
Json(build_admin_provider_model_response(&created, now_unix_secs))
.into_response()
Json(build_admin_provider_model_response(
&provider,
&created,
now_unix_secs,
))
.into_response()
}
None => (
http::StatusCode::INTERNAL_SERVER_ERROR,
@@ -1,9 +1,13 @@
use crate::handlers::admin::provider::shared::model_test_capabilities::{
admin_provider_model_supports_image_generation, admin_provider_model_test_capabilities_payload,
};
use crate::handlers::admin::request::AdminAppState;
use crate::GatewayError;
use aether_admin::provider::models as admin_provider_models_pure;
use aether_data_contracts::repository::global_models::{
AdminProviderModelListQuery, StoredAdminProviderModel,
};
use aether_data_contracts::repository::provider_catalog::StoredProviderCatalogProvider;
use std::time::{SystemTime, UNIX_EPOCH};
pub(super) fn admin_provider_model_effective_input_price(
@@ -26,10 +30,32 @@ pub(super) fn admin_provider_model_effective_capability(
}
pub(super) fn build_admin_provider_model_response(
provider: &StoredProviderCatalogProvider,
model: &StoredAdminProviderModel,
now_unix_secs: u64,
) -> serde_json::Value {
admin_provider_models_pure::build_admin_provider_model_response(model, now_unix_secs)
let mut payload =
admin_provider_models_pure::build_admin_provider_model_response(model, now_unix_secs);
let fallback_supports_image_generation = payload
.get("effective_supports_image_generation")
.and_then(serde_json::Value::as_bool)
.unwrap_or(false);
let supports_image_generation = admin_provider_model_supports_image_generation(
&provider.provider_type,
&model.provider_model_name,
fallback_supports_image_generation,
);
if let Some(object) = payload.as_object_mut() {
object.insert(
"model_test_capabilities".to_string(),
admin_provider_model_test_capabilities_payload(
&provider.provider_type,
&model.provider_model_name,
supports_image_generation,
),
);
}
payload
}
pub(super) async fn build_admin_provider_models_payload(
@@ -48,9 +74,10 @@ pub(super) async fn build_admin_provider_models_payload(
.ok()?
.into_iter()
.next()?;
let provider_id = provider.id.clone();
let mut models = state
.list_admin_provider_models(&AdminProviderModelListQuery {
provider_id: provider.id,
provider_id,
is_active,
offset: skip,
limit,
@@ -70,7 +97,7 @@ pub(super) async fn build_admin_provider_models_payload(
Some(serde_json::Value::Array(
models
.iter()
.map(|model| build_admin_provider_model_response(model, now_unix_secs))
.map(|model| build_admin_provider_model_response(&provider, model, now_unix_secs))
.collect(),
))
}
@@ -80,9 +107,15 @@ pub(super) async fn build_admin_provider_model_payload(
provider_id: &str,
model_id: &str,
) -> Option<serde_json::Value> {
if !state.has_global_model_data_reader() {
if !state.has_provider_catalog_data_reader() || !state.has_global_model_data_reader() {
return None;
}
let provider = state
.read_provider_catalog_providers_by_ids(&[provider_id.to_string()])
.await
.ok()?
.into_iter()
.next()?;
let model = state
.get_admin_provider_model(provider_id, model_id)
.await
@@ -92,7 +125,11 @@ pub(super) async fn build_admin_provider_model_payload(
.ok()
.map(|duration| duration.as_secs())
.unwrap_or(0);
Some(build_admin_provider_model_response(&model, now_unix_secs))
Some(build_admin_provider_model_response(
&provider,
&model,
now_unix_secs,
))
}
pub(super) async fn admin_provider_model_name_exists(
@@ -33,6 +33,20 @@ pub(super) async fn maybe_handle(
.into_response(),
));
};
let Some(provider) = state
.read_provider_catalog_providers_by_ids(std::slice::from_ref(&provider_id))
.await?
.into_iter()
.next()
else {
return Ok(Some(
(
http::StatusCode::NOT_FOUND,
Json(json!({ "detail": format!("Provider {provider_id} 不存在") })),
)
.into_response(),
));
};
let Some(existing) = state
.get_admin_provider_model(&provider_id, &model_id)
.await?
@@ -110,8 +124,12 @@ pub(super) async fn maybe_handle(
.ok()
.map(|duration| duration.as_secs())
.unwrap_or(0);
Json(build_admin_provider_model_response(&updated, now_unix_secs))
.into_response()
Json(build_admin_provider_model_response(
&provider,
&updated,
now_unix_secs,
))
.into_response()
}
None => (
http::StatusCode::NOT_FOUND,