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

@@ -187,12 +187,12 @@ impl ClaudeProviderState {
tool_state.call_id = block
.get("id")
.and_then(Value::as_str)
.unwrap_or_else(|| tool_state.call_id.as_str())
.unwrap_or(tool_state.call_id.as_str())
.to_string();
tool_state.name = block
.get("name")
.and_then(Value::as_str)
.unwrap_or_else(|| tool_state.name.as_str())
.unwrap_or(tool_state.name.as_str())
.to_string();
if !tool_state.started_emitted {
out.push(CanonicalStreamFrame {

View File

@@ -125,12 +125,12 @@ impl GeminiProviderState {
tool_state.call_id = function_call
.get("id")
.and_then(Value::as_str)
.unwrap_or_else(|| tool_state.call_id.as_str())
.unwrap_or(tool_state.call_id.as_str())
.to_string();
tool_state.name = function_call
.get("name")
.and_then(Value::as_str)
.unwrap_or_else(|| tool_state.name.as_str())
.unwrap_or(tool_state.name.as_str())
.to_string();
if !tool_state.started_emitted {
out.push(CanonicalStreamFrame {

View File

@@ -367,12 +367,12 @@ impl OpenAICliProviderState {
.get("call_id")
.or_else(|| item.get("id"))
.and_then(Value::as_str)
.unwrap_or_else(|| state.call_id.as_str())
.unwrap_or(state.call_id.as_str())
.to_string();
state.name = item
.get("name")
.and_then(Value::as_str)
.unwrap_or_else(|| state.name.as_str())
.unwrap_or(state.name.as_str())
.to_string();
if !state.started_emitted {
out.push(CanonicalStreamFrame {
@@ -525,12 +525,12 @@ impl OpenAICliProviderState {
.get("call_id")
.or_else(|| item.get("id"))
.and_then(Value::as_str)
.unwrap_or_else(|| state.call_id.as_str())
.unwrap_or(state.call_id.as_str())
.to_string();
state.name = item
.get("name")
.and_then(Value::as_str)
.unwrap_or_else(|| state.name.as_str())
.unwrap_or(state.name.as_str())
.to_string();
if !state.started_emitted {
out.push(CanonicalStreamFrame {
@@ -662,7 +662,7 @@ impl OpenAIChatClientEmitter {
return Ok(Vec::new());
}
self.started = true;
Ok(encode_json_sse(
encode_json_sse(
None,
&build_openai_chat_role_chunk(
self.response_id
@@ -670,7 +670,7 @@ impl OpenAIChatClientEmitter {
.unwrap_or("chatcmpl-local-stream"),
self.model.as_deref().unwrap_or("unknown"),
),
)?)
)
}
pub fn emit(&mut self, frame: CanonicalStreamFrame) -> Result<Vec<u8>, PipelineFinalizeError> {