重构: agentic 架构(run_agentic_loop 抽 finish_round_exit + router 调用点 + provider_pool 亲和 enabled)
- run_agentic_loop: 抽 finish_round_exit + emit_ai_completed_once(6 退出点收敛) - compress/title/knowledge_inject/project: router estimated_context+tier 调用点对齐 - provider_pool: 亲和加 model.enabled 过滤
This commit is contained in:
@@ -70,10 +70,12 @@ impl ProviderPool {
|
||||
// 反转比较结果:大者排前(亲和 true > false;weight 大 > 小;is_default true > false)。
|
||||
candidates.sort_by(|a, b| {
|
||||
// 主键:模型亲和。model_id None → 视两方都亲和(退化为全过此键)。
|
||||
// 必须过滤 m.enabled:用户禁用所有匹配实例时,该 provider 不应被标为亲和,
|
||||
// 否则会选不含可用目标模型的 provider 做主,污染 fallback 链顺序。
|
||||
let a_affinity = model_id
|
||||
.map_or(true, |mid| a.model_configs.iter().any(|m| m.model_id == mid));
|
||||
.map_or(true, |mid| a.model_configs.iter().any(|m| m.model_id == mid && m.enabled));
|
||||
let b_affinity = model_id
|
||||
.map_or(true, |mid| b.model_configs.iter().any(|m| m.model_id == mid));
|
||||
.map_or(true, |mid| b.model_configs.iter().any(|m| m.model_id == mid && m.enabled));
|
||||
let by_affinity = b_affinity.cmp(&a_affinity); // true 排前
|
||||
if by_affinity != std::cmp::Ordering::Equal {
|
||||
return by_affinity;
|
||||
@@ -267,4 +269,37 @@ mod tests {
|
||||
"应按 亲和 > weight > is_default 排序,排除 enabled=false/weight=0"
|
||||
);
|
||||
}
|
||||
|
||||
/// ── 模型亲和:enabled 过滤 ──
|
||||
|
||||
#[test]
|
||||
fn model_affinity_excludes_disabled_model() {
|
||||
// 回归点:匹配 model 全 disabled 时,provider 不应被标为亲和。
|
||||
// 设计:p1 含目标模型但 enabled=false 且 weight=90(高 weight 诱惑),
|
||||
// p2 含目标模型且 enabled=true 但 weight=30(低 weight)。
|
||||
// 修复后(过滤 m.enabled):p1 非亲和 / p2 亲和 → p2 因亲和主键排前(即使 weight 低)。
|
||||
// bug 复现(不过滤 enabled):p1 p2 同亲和 → 按 weight → p1(90)排前。
|
||||
// 位置差异精确捕获回归:p2 排前=修复正确,p1 排前=bug 复现。
|
||||
let pool = vec![
|
||||
AiProviderRecord {
|
||||
weight: 90,
|
||||
model_configs: vec![ModelConfig {
|
||||
enabled: false,
|
||||
..ModelConfig::with_defaults("glm-4-flash")
|
||||
}],
|
||||
..provider("p1_disabled_model")
|
||||
},
|
||||
AiProviderRecord {
|
||||
weight: 30,
|
||||
model_configs: vec![ModelConfig::with_defaults("glm-4-flash")],
|
||||
..provider("p2_enabled_model")
|
||||
},
|
||||
];
|
||||
let selected = ProviderPool::select(&pool, Some("glm-4-flash"));
|
||||
assert_eq!(
|
||||
selected.iter().map(|p| p.id.as_str()).collect::<Vec<_>>(),
|
||||
vec!["p2_enabled_model", "p1_disabled_model"],
|
||||
"匹配 model 全 disabled 的 p1 非亲和,含 enabled model 的 p2 因亲和排前(即使 weight 低)"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user