新增: F-01阶段5模型路由调用点接入

This commit is contained in:
2026-06-17 00:33:44 +08:00
parent 5b7f342e14
commit 2ddfea67c7
10 changed files with 220 additions and 24 deletions

View File

@@ -10,7 +10,11 @@ use std::collections::HashMap;
use std::sync::Arc;
use async_trait::async_trait;
use df_ai::df_ai_core::model::{IntelligenceTier, Modality, ModelConfig};
use df_ai::provider::{ChatMessage, CompletionRequest, LlmProvider};
// F-01 阶段5: AiNode 路由 — 节点 config.model_id 优先;否则按 TaskRequirements 路由
// (默认 Standard + needs_tool_use=true)。池空/无匹配兜底 record.default_model。
use df_ai::router::{select_model_id, TaskRequirements};
use df_storage::crud::{AiProviderRepo, TaskRepo};
use df_storage::db::Database;
use df_storage::models::AiProviderRecord;
@@ -45,6 +49,9 @@ struct ResolvedProvider {
api_key: String,
/// model 为空时的占位record.default_model 或 "gpt-4o-mini"),避免 provider 构造 panic
default_model: String,
/// F-01 阶段5: 候选模型池(来自 record.model_configs)。parse_params 路由用:
/// config.model 留空时经 select_model_id 选最优;池空兜底 default_model。
model_pool: Vec<ModelConfig>,
}
/// 经 ai_providers 表 + df_storage::secret 解析 provider 构造要素FR-S1 注入链核心)。
@@ -117,6 +124,8 @@ async fn resolve_provider(
base_url,
api_key,
default_model,
// 老明文路径无 record,候选池空(无路由能力,兜底 default_model)。
model_pool: Vec::new(),
});
}
@@ -154,6 +163,7 @@ fn resolve_from_record(
base_url: record.base_url.clone(),
api_key,
default_model,
model_pool: record.model_configs.clone(),
})
}
@@ -179,11 +189,30 @@ fn parse_params(
.ok_or_else(|| anyhow::anyhow!("AiNode 缺少必填参数: promptconfig 或上游输入均无)"))?;
// ── 可选参数 ──
let model = config
// model 解析优先级(F-01 阶段5):config.model 显式指定 > 路由选优(provider.model_pool 非空时)
// > 空(CompletionRequest.model 留空由 provider impl 回填 default_model,行为不变)。
// 注:provider.model_pool 在 provider move 进 AiNodeParams 前先借引用路由,选中的 model_id
// 填入 CompletionRequest.model;provider.default_model 仍是 build_provider 兜底用。
let config_model = config
.get("model")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
let model = if !config_model.is_empty() {
config_model
} else {
// F-01 阶段5: AiNode 默认路由 — Standard + needs_tool_use=true(工作流无人值守 AI 步骤
// 常含工具调用,如检索/生成;无需工具的节点应在 config 显式指定 model)。
// select_model_id None(池空/无匹配)→ 空串(由 provider impl 回填 default_model)。
let node_req = TaskRequirements {
modalities: vec![Modality::Text],
needs_tool_use: true,
min_intelligence: IntelligenceTier::Standard,
max_cost: None,
estimated_context: 0,
};
select_model_id(&node_req, &provider.model_pool).unwrap_or_default()
};
let temperature = config
.get("temperature")
.and_then(|v| v.as_f64())
@@ -600,6 +629,7 @@ mod tests {
base_url: "https://api.example.com".to_string(),
api_key: "sk-test".to_string(),
default_model: "gpt-4o-mini".to_string(),
model_pool: Vec::new(),
}
}