4f3f0f24ff
新增后台 AGC 模型目录、别名、启停和默认项管理 客户端设置页恢复原状,对话框右下角按别名选择模型 服务端按稳定模型标识映射并校验实际模型白名单 修复 AGC 配套后端端口漂移、启动等待和 SpacetimeDB 版本检查 补充迁移、文档、启动与模型选择测试
98 lines
3.5 KiB
Rust
98 lines
3.5 KiB
Rust
use crate::{
|
|
admin::AuthenticatedAdmin, api_response::json_success_body, http_error::AppError,
|
|
request_context::RequestContext, state::AppState,
|
|
};
|
|
use axum::{
|
|
Json,
|
|
extract::{Extension, State},
|
|
http::StatusCode,
|
|
};
|
|
use module_runtime::AgcModelCatalog;
|
|
use shared_contracts::admin::{AdminAgcModel, AdminAgcModelCatalog};
|
|
|
|
pub(crate) async fn load_catalog(state: &AppState) -> Result<AgcModelCatalog, AppError> {
|
|
let json = state
|
|
.spacetime_client()
|
|
.read_agc_model_catalog()
|
|
.await
|
|
.map_err(|_| {
|
|
AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_message("模型目录暂不可用")
|
|
})?;
|
|
let catalog: AgcModelCatalog = serde_json::from_str(&json).map_err(|_| {
|
|
AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_message("模型目录格式无效")
|
|
})?;
|
|
catalog.validate().map_err(|message| {
|
|
AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_message(message)
|
|
})?;
|
|
Ok(catalog)
|
|
}
|
|
|
|
pub async fn admin_get_agc_models(
|
|
State(state): State<AppState>,
|
|
Extension(context): Extension<RequestContext>,
|
|
Extension(_admin): Extension<AuthenticatedAdmin>,
|
|
) -> Result<Json<serde_json::Value>, AppError> {
|
|
Ok(json_success_body(
|
|
Some(&context),
|
|
catalog_dto(load_catalog(&state).await?),
|
|
))
|
|
}
|
|
|
|
pub async fn admin_save_agc_models(
|
|
State(state): State<AppState>,
|
|
Extension(context): Extension<RequestContext>,
|
|
Extension(_admin): Extension<AuthenticatedAdmin>,
|
|
Json(payload): Json<AdminAgcModelCatalog>,
|
|
) -> Result<Json<serde_json::Value>, AppError> {
|
|
let catalog = AgcModelCatalog {
|
|
revision: payload.revision,
|
|
default_model_id: payload.default_model_id,
|
|
models: payload
|
|
.models
|
|
.into_iter()
|
|
.map(|m| module_runtime::AgcModel {
|
|
id: m.id,
|
|
alias: m.alias,
|
|
model_id: m.model_id,
|
|
enabled: m.enabled,
|
|
})
|
|
.collect(),
|
|
};
|
|
catalog
|
|
.validate()
|
|
.map_err(|message| AppError::from_status(StatusCode::BAD_REQUEST).with_message(message))?;
|
|
let payload = serde_json::to_string(&catalog)
|
|
.map_err(|_| AppError::from_status(StatusCode::INTERNAL_SERVER_ERROR))?;
|
|
let saved = state
|
|
.spacetime_client()
|
|
.save_agc_model_catalog(payload)
|
|
.await
|
|
.map_err(|error| {
|
|
if matches!(error, spacetime_client::SpacetimeClientError::Procedure(ref message) if message == module_runtime::AGC_MODEL_CATALOG_CONFLICT) {
|
|
AppError::from_status(StatusCode::CONFLICT).with_message("模型目录已被更新,请重新读取")
|
|
} else {
|
|
AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_message("保存模型目录失败,请稍后重试")
|
|
}
|
|
})?;
|
|
let catalog: AgcModelCatalog = serde_json::from_str(&saved)
|
|
.map_err(|_| AppError::from_status(StatusCode::INTERNAL_SERVER_ERROR))?;
|
|
Ok(json_success_body(Some(&context), catalog_dto(catalog)))
|
|
}
|
|
|
|
fn catalog_dto(catalog: AgcModelCatalog) -> AdminAgcModelCatalog {
|
|
AdminAgcModelCatalog {
|
|
revision: catalog.revision,
|
|
default_model_id: catalog.default_model_id,
|
|
models: catalog
|
|
.models
|
|
.into_iter()
|
|
.map(|m| AdminAgcModel {
|
|
id: m.id,
|
|
alias: m.alias,
|
|
model_id: m.model_id,
|
|
enabled: m.enabled,
|
|
})
|
|
.collect(),
|
|
}
|
|
}
|