mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
feat: 全栈功能增强 - 扩展 provider/pool 管理、完善调度与数据层、重构前端 Pool 页面
后端: - 扩展 pool_admin payloads 和 provider query models,增强 endpoint key 管理 - 完善 scheduler-core 候选排序与请求候选逻辑 - 增强 usage-runtime 写入、provider-transport 网络层与 OAuth 刷新 - 改进 AI pipeline 响应转换与流式处理 - 扩展 global_models/provider_catalog 数据层查询能力 - 增强 video-tasks-core 多 provider 支持 - 新增大量集成测试覆盖 pool/keys/provider_query/frontdoor 前端: - 重构 PoolManagement 页面,拆分状态管理/对话框逻辑到独立模块 - 新增 poolAdvancedDialog/poolSchedulingDialog/poolManagementState/poolMobilePresentation 工具函数及测试 - 改进 Dialog 组件与 provider tabs 显示 部署: - 更新 Rust CI workflow 和 Dockerfile 构建配置 Closes #275 Co-authored-by: AAEE86 <ppk0227@hotmail.com>
This commit is contained in:
@@ -231,9 +231,98 @@ pub(crate) fn provider_key_health_summary(
|
||||
)
|
||||
}
|
||||
|
||||
fn normalize_catalog_oauth_plan_type(value: &str, provider_type: &str) -> Option<String> {
|
||||
let mut normalized = value.trim().to_string();
|
||||
if normalized.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let provider_type = provider_type.trim().to_ascii_lowercase();
|
||||
if !provider_type.is_empty() && normalized.to_ascii_lowercase().starts_with(&provider_type) {
|
||||
normalized = normalized[provider_type.len()..]
|
||||
.trim_matches(|ch: char| [' ', ':', '-', '_'].contains(&ch))
|
||||
.to_string();
|
||||
}
|
||||
|
||||
let normalized = normalized.trim().to_ascii_lowercase();
|
||||
if normalized.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(normalized)
|
||||
}
|
||||
}
|
||||
|
||||
fn catalog_oauth_plan_type_from_source(
|
||||
source: &serde_json::Map<String, serde_json::Value>,
|
||||
provider_type: &str,
|
||||
fields: &[&str],
|
||||
) -> Option<String> {
|
||||
for field in fields {
|
||||
let Some(value) = source.get(*field).and_then(serde_json::Value::as_str) else {
|
||||
continue;
|
||||
};
|
||||
if let Some(normalized) = normalize_catalog_oauth_plan_type(value, provider_type) {
|
||||
return Some(normalized);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn derive_catalog_oauth_plan_type(
|
||||
key: &StoredProviderCatalogKey,
|
||||
provider_type: &str,
|
||||
auth_config: Option<&serde_json::Map<String, serde_json::Value>>,
|
||||
) -> Option<String> {
|
||||
if !key.auth_type.trim().eq_ignore_ascii_case("oauth") {
|
||||
return None;
|
||||
}
|
||||
|
||||
let provider_type_key = provider_type.trim().to_ascii_lowercase();
|
||||
if let Some(upstream_metadata) = key
|
||||
.upstream_metadata
|
||||
.as_ref()
|
||||
.and_then(serde_json::Value::as_object)
|
||||
{
|
||||
let provider_bucket = if provider_type_key.is_empty() {
|
||||
None
|
||||
} else {
|
||||
upstream_metadata
|
||||
.get(&provider_type_key)
|
||||
.and_then(serde_json::Value::as_object)
|
||||
};
|
||||
for source in provider_bucket
|
||||
.into_iter()
|
||||
.chain(std::iter::once(upstream_metadata))
|
||||
{
|
||||
if let Some(plan_type) = catalog_oauth_plan_type_from_source(
|
||||
source,
|
||||
provider_type,
|
||||
&[
|
||||
"plan_type",
|
||||
"tier",
|
||||
"subscription_title",
|
||||
"subscription_plan",
|
||||
"plan",
|
||||
],
|
||||
) {
|
||||
return Some(plan_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auth_config.and_then(|source| {
|
||||
catalog_oauth_plan_type_from_source(
|
||||
source,
|
||||
provider_type,
|
||||
&["plan_type", "tier", "plan", "subscription_plan"],
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn build_admin_provider_key_response(
|
||||
state: &AppState,
|
||||
key: &StoredProviderCatalogKey,
|
||||
provider_type: &str,
|
||||
now_unix_secs: u64,
|
||||
) -> serde_json::Value {
|
||||
let request_count = u64::from(key.request_count.unwrap_or(0));
|
||||
@@ -257,16 +346,7 @@ pub(crate) fn build_admin_provider_key_response(
|
||||
.and_then(serde_json::Value::as_array)
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
let oauth_plan_type = auth_config
|
||||
.as_ref()
|
||||
.and_then(|config| config.get("plan_type").and_then(serde_json::Value::as_str))
|
||||
.map(ToOwned::to_owned)
|
||||
.or_else(|| {
|
||||
auth_config
|
||||
.as_ref()
|
||||
.and_then(|config| config.get("tier").and_then(serde_json::Value::as_str))
|
||||
.map(|value| value.to_ascii_lowercase())
|
||||
});
|
||||
let oauth_plan_type = derive_catalog_oauth_plan_type(key, provider_type, auth_config.as_ref());
|
||||
let (
|
||||
health_score,
|
||||
consecutive_failures,
|
||||
|
||||
Reference in New Issue
Block a user