fix(mapping): 对齐全局模型映射的正则匹配行为与范围 (#296)

- scheduler_core: `matches_model_mapping` 改为大小写不敏感且整串匹配,并补充单测
- global model routing 预览:
  - Key 过滤增加 `allowed_models + model_mappings` 校验
  - `all_keys_whitelist` 改为收集全站活跃 Provider 的活跃 Key 白名单
- provider mapping-preview:
  - 优先使用 admin 全量 GlobalModel(含非激活)参与映射
  - admin 数据为空时回退 public 模型,保持兼容
- public models 匹配逻辑统一复用 scheduler_core 实现,避免行为分叉
- 更新网关测试,覆盖未关联 Provider 的 Key 也进入 whitelist 的场景
This commit is contained in:
AAEE86
2026-04-14 21:58:52 +08:00
committed by GitHub
parent 47bf1d04a1
commit fb31928e44
5 changed files with 210 additions and 36 deletions

View File

@@ -4,7 +4,7 @@ use aether_data_contracts::repository::candidate_selection::{
StoredMinimalCandidateSelectionRow, StoredProviderModelMapping,
};
use aether_data_contracts::DataLayerError;
use regex::Regex;
use regex::RegexBuilder;
pub fn resolve_requested_global_model_name(
rows: &[StoredMinimalCandidateSelectionRow],
@@ -201,7 +201,15 @@ fn capabilities_support_required_capability(
}
pub fn matches_model_mapping(pattern: &str, model_name: &str) -> bool {
let Ok(compiled) = Regex::new(&format!("^(?:{pattern})$")) else {
if pattern.eq_ignore_ascii_case(model_name) {
return true;
}
let regex_pattern = format!("^(?:{pattern})$");
let Ok(compiled) = RegexBuilder::new(&regex_pattern)
.case_insensitive(true)
.build()
else {
return false;
};
compiled.is_match(model_name)
@@ -253,3 +261,25 @@ pub fn extract_global_priority_for_format(
pub fn normalize_api_format(value: &str) -> String {
value.trim().to_ascii_lowercase()
}
#[cfg(test)]
mod tests {
use super::matches_model_mapping;
#[test]
fn model_mapping_match_is_case_insensitive() {
assert!(matches_model_mapping("gpt-4o", "GPT-4O"));
assert!(matches_model_mapping("gpt-5(?:\\.\\d+)?", "GPT-5.1"));
}
#[test]
fn model_mapping_match_is_anchored_to_full_text() {
assert!(matches_model_mapping("gpt-4o", "gpt-4o"));
assert!(!matches_model_mapping("gpt-4o", "gpt-4o-mini"));
}
#[test]
fn invalid_model_mapping_pattern_returns_false() {
assert!(!matches_model_mapping("([a-z", "gpt-4o"));
}
}