mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
feat(pool): 引入 pro_first 调度预设、Pool 候选持久化跳过与诊断信息优化
- 新增 pro_first 调度预设(Pro 优先),更新 plus_first 仅针对 Plus 计划,移除 free_team_first - Pool 内部候选(pool_key_index 不为空)跳过 DB 持久化(available/skipped/unused 均适用) - LRU 排序新增 catalog_lru_score 回退:runtime 无记录时使用 last_used_at_unix_secs - 执行路径 miss 诊断消息细化为中文,按 reason 分类输出可读说明 - build_local_request_candidate_status_record 补充 extra_data 和 created_at_unix_ms 字段 - OpenAI CLI 计划构建流程补充候选评估进度跟踪与 terminal reason 设置 - 前端 PoolSchedulingDialog 增加 pro_first 预设展示,修复 LRU 默认预设检测逻辑
This commit is contained in:
@@ -10,6 +10,23 @@ use super::{
|
||||
};
|
||||
use crate::DataLayerError;
|
||||
|
||||
fn merge_extra_data(
|
||||
existing: Option<serde_json::Value>,
|
||||
overlay: Option<serde_json::Value>,
|
||||
) -> Option<serde_json::Value> {
|
||||
match (existing, overlay) {
|
||||
(
|
||||
Some(serde_json::Value::Object(mut existing_object)),
|
||||
Some(serde_json::Value::Object(overlay_object)),
|
||||
) => {
|
||||
existing_object.extend(overlay_object);
|
||||
Some(serde_json::Value::Object(existing_object))
|
||||
}
|
||||
(_existing, Some(overlay)) => Some(overlay),
|
||||
(existing, None) => existing,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct InMemoryRequestCandidateRepository {
|
||||
by_id: RwLock<BTreeMap<String, StoredRequestCandidate>>,
|
||||
@@ -353,9 +370,10 @@ impl RequestCandidateWriteRepository for InMemoryRequestCandidateRepository {
|
||||
concurrent_requests: candidate
|
||||
.concurrent_requests
|
||||
.or_else(|| existing.as_ref().and_then(|row| row.concurrent_requests)),
|
||||
extra_data: candidate
|
||||
.extra_data
|
||||
.or_else(|| existing.as_ref().and_then(|row| row.extra_data.clone())),
|
||||
extra_data: merge_extra_data(
|
||||
existing.as_ref().and_then(|row| row.extra_data.clone()),
|
||||
candidate.extra_data,
|
||||
),
|
||||
required_capabilities: candidate.required_capabilities.or_else(|| {
|
||||
existing
|
||||
.as_ref()
|
||||
@@ -411,6 +429,7 @@ mod tests {
|
||||
RequestCandidateReadRepository, RequestCandidateStatus, RequestCandidateWriteRepository,
|
||||
StoredRequestCandidate, UpsertRequestCandidateRecord,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
fn sample_candidate(
|
||||
id: &str,
|
||||
@@ -540,7 +559,10 @@ mod tests {
|
||||
error_message: None,
|
||||
latency_ms: None,
|
||||
concurrent_requests: None,
|
||||
extra_data: None,
|
||||
extra_data: Some(json!({
|
||||
"execution_strategy": "local_cross_format",
|
||||
"provider_name": "primary",
|
||||
})),
|
||||
required_capabilities: None,
|
||||
created_at_unix_ms: Some(100),
|
||||
started_at_unix_ms: None,
|
||||
@@ -572,7 +594,10 @@ mod tests {
|
||||
error_message: None,
|
||||
latency_ms: Some(25),
|
||||
concurrent_requests: Some(2),
|
||||
extra_data: None,
|
||||
extra_data: Some(json!({
|
||||
"provider_api_format": "openai:cli",
|
||||
"provider_name": "updated",
|
||||
})),
|
||||
required_capabilities: None,
|
||||
created_at_unix_ms: None,
|
||||
started_at_unix_ms: Some(101),
|
||||
@@ -584,6 +609,27 @@ mod tests {
|
||||
assert_eq!(updated.status, RequestCandidateStatus::Success);
|
||||
assert_eq!(updated.status_code, Some(200));
|
||||
assert_eq!(updated.latency_ms, Some(25));
|
||||
assert_eq!(
|
||||
updated
|
||||
.extra_data
|
||||
.as_ref()
|
||||
.and_then(|value| value.get("execution_strategy")),
|
||||
Some(&json!("local_cross_format"))
|
||||
);
|
||||
assert_eq!(
|
||||
updated
|
||||
.extra_data
|
||||
.as_ref()
|
||||
.and_then(|value| value.get("provider_api_format")),
|
||||
Some(&json!("openai:cli"))
|
||||
);
|
||||
assert_eq!(
|
||||
updated
|
||||
.extra_data
|
||||
.as_ref()
|
||||
.and_then(|value| value.get("provider_name")),
|
||||
Some(&json!("updated"))
|
||||
);
|
||||
assert_eq!(updated.started_at_unix_ms, Some(101));
|
||||
}
|
||||
|
||||
|
||||
@@ -240,7 +240,14 @@ DO UPDATE SET
|
||||
error_message = COALESCE(EXCLUDED.error_message, request_candidates.error_message),
|
||||
latency_ms = COALESCE(EXCLUDED.latency_ms, request_candidates.latency_ms),
|
||||
concurrent_requests = COALESCE(EXCLUDED.concurrent_requests, request_candidates.concurrent_requests),
|
||||
extra_data = COALESCE(EXCLUDED.extra_data, request_candidates.extra_data),
|
||||
extra_data = CASE
|
||||
WHEN request_candidates.extra_data IS NULL THEN EXCLUDED.extra_data
|
||||
WHEN EXCLUDED.extra_data IS NULL THEN request_candidates.extra_data
|
||||
WHEN json_typeof(request_candidates.extra_data) = 'object'
|
||||
AND json_typeof(EXCLUDED.extra_data) = 'object'
|
||||
THEN (request_candidates.extra_data::jsonb || EXCLUDED.extra_data::jsonb)::json
|
||||
ELSE EXCLUDED.extra_data
|
||||
END,
|
||||
required_capabilities = COALESCE(EXCLUDED.required_capabilities, request_candidates.required_capabilities),
|
||||
started_at = COALESCE(EXCLUDED.started_at, request_candidates.started_at),
|
||||
finished_at = COALESCE(EXCLUDED.finished_at, request_candidates.finished_at)
|
||||
|
||||
Reference in New Issue
Block a user