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:
fawney19
2026-04-09 13:51:50 +08:00
parent 4fc95adfb9
commit b0b40c16ff
97 changed files with 5816 additions and 1881 deletions

View File

@@ -246,6 +246,12 @@ pub fn aggregate_models_for_cache(models: &[Value]) -> Vec<Value> {
.collect::<BTreeSet<_>>()
})
.unwrap_or_default();
let legacy_api_format = object
.get("api_format")
.and_then(Value::as_str)
.map(str::trim)
.filter(|value| !value.is_empty())
.map(ToOwned::to_owned);
let existing_formats = entry
.get("api_formats")
.and_then(Value::as_array)
@@ -259,9 +265,15 @@ pub fn aggregate_models_for_cache(models: &[Value]) -> Vec<Value> {
.collect::<BTreeSet<_>>()
})
.unwrap_or_default();
let merged_formats = existing_formats
let mut merged_formats = existing_formats
.union(&api_formats)
.cloned()
.collect::<BTreeSet<_>>();
if let Some(api_format) = legacy_api_format {
merged_formats.insert(api_format);
}
let merged_formats = merged_formats
.into_iter()
.map(Value::String)
.collect::<Vec<_>>();
entry.insert("api_formats".to_string(), Value::Array(merged_formats));
@@ -453,6 +465,17 @@ mod tests {
);
}
#[test]
fn aggregate_models_for_cache_preserves_legacy_api_format_field() {
let aggregated = aggregate_models_for_cache(&[json!({
"id":"gpt-5",
"api_format":"openai:chat"
})]);
assert_eq!(aggregated.len(), 1);
assert_eq!(aggregated[0]["api_formats"], json!(["openai:chat"]));
assert!(aggregated[0].get("api_format").is_none());
}
#[test]
fn build_gemini_models_url_preserves_base_query() {
let url =