优化: AI Chat全栈多批审查修复与架构清理(risk_level清理/路由解耦/工具渲染/测试补测/死代码)

This commit is contained in:
2026-06-18 22:57:19 +08:00
parent 0ca5d9805f
commit a2871a66e0
87 changed files with 5720 additions and 3012 deletions

View File

@@ -13,11 +13,12 @@ use df_ai::provider::{ChatMessage, CompletionRequest, LlmProvider};
// 实现流前失败重试退避对齐(决策 F-260616-07 a1),避免重写退避逻辑。
use df_ai::retry;
// F-01 阶段5: 智能路由 helper + TaskRequirements + 维度枚举。
// 调用点构造 TaskRequirements(主对话:needs_tool_use=true,min_intelligence=Standard,
// 调用点构造 TaskRequirements(主对话:needs_tool_use=true,
// 当前仅 Text 模态;后续多模态接入时检测消息内 Part/Image 追加 Vision),
// 经 select_model_id 在 provider.model_configs 池中选最优;池空/无匹配兜底 default_model。
// 注:路由已解耦(B-260618-03),cost_tier/intelligence 不再参与硬路由。
use df_ai::router::{
select_model_id, IntelligenceTier, Modality, TaskRequirements,
select_model_id, Modality, TaskRequirements,
};
use df_storage::db::Database;
@@ -344,10 +345,20 @@ pub(crate) async fn run_agentic_loop(
// AiProviderRepo::new 仅 clone Arc<Database>(廉价),不复用 AppState.ai_providers
// (run_agentic_loop 签名只传 Arc<Database>,改签名会牵动 3 调用点 + try_continue)。
let provider_repo = df_storage::crud::AiProviderRepo::new(&db);
let pool_providers: Vec<AiProviderRecord> = provider_repo.list_all().await.unwrap_or_default();
let pool_providers: Vec<AiProviderRecord> = match provider_repo.list_all().await {
Ok(v) => v,
Err(e) => {
tracing::warn!(error = %e, "[ai] list_all providers 失败,负载均衡池退化为入参默认 provider(空池兜底)");
Vec::new()
}
};
let ranked_candidates: Vec<AiProviderRecord> = super::provider_pool::ProviderPool::select(
&pool_providers,
None, // 模型亲和此时尚未确定(router 选模型需 provider_config,见下方)
// specify 模式(用户指定 model):传 override 作亲和键,ProviderPool 优先选
// 「池中含该 model 的 provider」作 primary,打破下方「router 选模型需 provider_config」
// 的鸡生蛋——override 此时已知(入参 ← session.model_override),无须等 router。
// auto 模式(override=None)→ 全亲和纯权重排序,行为不变(向后兼容)。
model_override.as_deref(),
);
let (primary_provider, candidates): (AiProviderRecord, Vec<AiProviderRecord>) =
match ranked_candidates.split_first() {
@@ -401,14 +412,12 @@ pub(crate) async fn run_agentic_loop(
"[ai] 发起 LLM 请求"
);
// F-01 阶段5: 主对话路由 — TaskRequirements(needs_tool_use=true,min_intelligence=Standard)。
// F-01 阶段5: 主对话路由 — TaskRequirements(needs_tool_use=true)。
// 模态当前仅 Text(图像消息类型未实现,后续多模态接入时检测 Part/Image 追加 Vision)。
// select_model_id None(池空/无匹配)→ 兜底 default_model,行为与接入前一致。
let agentic_req = TaskRequirements {
modalities: vec![Modality::Text],
needs_tool_use: true,
min_intelligence: IntelligenceTier::Standard,
max_cost: None,
estimated_context: 0,
};
let resolved_model = select_model_id(&agentic_req, &provider_config.model_configs)