mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 09:20:22 +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:
@@ -8,5 +8,5 @@ pub use gemini_chat::convert_openai_chat_response_to_gemini_chat;
|
||||
pub use openai_cli::convert_openai_chat_response_to_openai_cli;
|
||||
pub use shared::{
|
||||
build_openai_cli_response, build_openai_cli_response_with_content,
|
||||
build_openai_cli_response_with_reasoning,
|
||||
build_openai_cli_response_with_reasoning, OpenAiCliResponseUsage,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use serde_json::{json, Value};
|
||||
|
||||
use super::shared::{build_openai_cli_response_with_content, canonicalize_tool_arguments};
|
||||
use super::shared::{
|
||||
build_openai_cli_response_with_content, canonicalize_tool_arguments, OpenAiCliResponseUsage,
|
||||
};
|
||||
|
||||
pub fn convert_openai_chat_response_to_openai_cli(
|
||||
body_json: &Value,
|
||||
@@ -143,8 +145,10 @@ pub fn convert_openai_chat_response_to_openai_cli(
|
||||
message_content,
|
||||
reasoning_summaries,
|
||||
function_calls,
|
||||
prompt_tokens,
|
||||
output_tokens,
|
||||
total_tokens,
|
||||
OpenAiCliResponseUsage {
|
||||
prompt_tokens,
|
||||
output_tokens,
|
||||
total_tokens,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
use serde_json::{json, Map, Value};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct OpenAiCliResponseUsage {
|
||||
pub prompt_tokens: u64,
|
||||
pub output_tokens: u64,
|
||||
pub total_tokens: u64,
|
||||
}
|
||||
|
||||
pub fn build_openai_cli_response(
|
||||
response_id: &str,
|
||||
model: &str,
|
||||
@@ -24,9 +31,11 @@ pub fn build_openai_cli_response(
|
||||
content,
|
||||
Vec::new(),
|
||||
function_calls,
|
||||
prompt_tokens,
|
||||
output_tokens,
|
||||
total_tokens,
|
||||
OpenAiCliResponseUsage {
|
||||
prompt_tokens,
|
||||
output_tokens,
|
||||
total_tokens,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -36,9 +45,7 @@ pub fn build_openai_cli_response_with_reasoning(
|
||||
text: &str,
|
||||
reasoning_summaries: Vec<String>,
|
||||
function_calls: Vec<Value>,
|
||||
prompt_tokens: u64,
|
||||
output_tokens: u64,
|
||||
total_tokens: u64,
|
||||
usage: OpenAiCliResponseUsage,
|
||||
) -> Value {
|
||||
let content = if text.is_empty() {
|
||||
Vec::new()
|
||||
@@ -55,9 +62,7 @@ pub fn build_openai_cli_response_with_reasoning(
|
||||
content,
|
||||
reasoning_summaries,
|
||||
function_calls,
|
||||
prompt_tokens,
|
||||
output_tokens,
|
||||
total_tokens,
|
||||
usage,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -67,9 +72,7 @@ pub fn build_openai_cli_response_with_content(
|
||||
content: Vec<Value>,
|
||||
reasoning_summaries: Vec<String>,
|
||||
function_calls: Vec<Value>,
|
||||
prompt_tokens: u64,
|
||||
output_tokens: u64,
|
||||
total_tokens: u64,
|
||||
usage: OpenAiCliResponseUsage,
|
||||
) -> Value {
|
||||
let mut output = Vec::new();
|
||||
for (index, summary) in reasoning_summaries.into_iter().enumerate() {
|
||||
@@ -104,9 +107,9 @@ pub fn build_openai_cli_response_with_content(
|
||||
"model": model,
|
||||
"output": output,
|
||||
"usage": {
|
||||
"input_tokens": prompt_tokens,
|
||||
"output_tokens": output_tokens,
|
||||
"total_tokens": total_tokens,
|
||||
"input_tokens": usage.prompt_tokens,
|
||||
"output_tokens": usage.output_tokens,
|
||||
"total_tokens": usage.total_tokens,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use serde_json::{json, Value};
|
||||
|
||||
use super::super::from_openai_chat::build_openai_cli_response_with_reasoning;
|
||||
use super::super::from_openai_chat::{
|
||||
build_openai_cli_response_with_reasoning, OpenAiCliResponseUsage,
|
||||
};
|
||||
use super::shared::{build_generated_tool_call_id, canonicalize_tool_arguments};
|
||||
|
||||
pub fn convert_claude_cli_response_to_openai_cli(
|
||||
@@ -76,8 +78,10 @@ pub fn convert_claude_cli_response_to_openai_cli(
|
||||
&text,
|
||||
reasoning_summaries,
|
||||
function_calls,
|
||||
prompt_tokens,
|
||||
output_tokens,
|
||||
total_tokens,
|
||||
OpenAiCliResponseUsage {
|
||||
prompt_tokens,
|
||||
output_tokens,
|
||||
total_tokens,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use serde_json::{json, Value};
|
||||
|
||||
use super::super::from_openai_chat::build_openai_cli_response_with_content;
|
||||
use super::super::from_openai_chat::{
|
||||
build_openai_cli_response_with_content, OpenAiCliResponseUsage,
|
||||
};
|
||||
use super::shared::{
|
||||
build_generated_tool_call_id, canonicalize_tool_arguments, extract_gemini_image_url,
|
||||
};
|
||||
@@ -99,8 +101,10 @@ pub fn convert_gemini_cli_response_to_openai_cli(
|
||||
message_content,
|
||||
reasoning_summaries,
|
||||
function_calls,
|
||||
prompt_tokens,
|
||||
output_tokens,
|
||||
total_tokens,
|
||||
OpenAiCliResponseUsage {
|
||||
prompt_tokens,
|
||||
output_tokens,
|
||||
total_tokens,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user