refactor: 限制外部 API 仅接受 GlobalModel.name

移除调度器和模型映射器对映射名解析的支持,外部请求必须使用精确的
GlobalModel.name。同时新增 is_active 检查确保停用的模型被正确拒绝。

- 使用 get_global_model_by_name 替代 resolve_global_model_by_name_or_mapping
- 添加模型名称规范化(去除首尾空格)
- 统一检查 GlobalModel.is_active 状态
This commit is contained in:
fawney19
2026-02-04 11:49:47 +08:00
parent f6dac1c38a
commit 3ffc6f21c4
2 changed files with 31 additions and 28 deletions

View File

@@ -626,13 +626,15 @@ class CacheAwareScheduler:
target_format,
)
# 0. 解析 model_name 到 GlobalModel支持直接匹配和映射名匹配,使用 ModelCacheService
global_model = await ModelCacheService.resolve_global_model_by_name_or_mapping(
db, model_name
)
# 0. 解析 model_name 到 GlobalModel仅接受 GlobalModel.name
normalized_name = model_name.strip() if isinstance(model_name, str) else ""
if not normalized_name:
logger.warning("GlobalModel not found: <empty model name>")
raise ModelNotSupportedException(model=model_name)
if not global_model:
logger.warning(f"GlobalModel not found: {model_name}")
global_model = await ModelCacheService.get_global_model_by_name(db, normalized_name)
if not global_model or not global_model.is_active:
logger.warning(f"GlobalModel not found or inactive: {normalized_name}")
raise ModelNotSupportedException(model=model_name)
logger.debug(
@@ -828,14 +830,12 @@ class CacheAwareScheduler:
- 模型支持的能力是全局的,与具体的 Key 无关
- 如果模型不支持某能力,整个 Provider 的所有 Key 都应该被跳过
支持两种匹配方式:
1. 直接匹配 GlobalModel.name
2. 通过 ModelCacheService 匹配映射名(全局查找)
支持直接匹配 GlobalModel.name外部请求不接受映射名
Args:
db: 数据库会话
provider: Provider 对象
model_name: 模型名称(可以是 GlobalModel.name 或映射名
model_name: 模型名称(必须是 GlobalModel.name
is_stream: 是否是流式请求,如果为 True 则同时检查流式支持
capability_requirements: 能力需求(可选),用于检查模型是否支持所需能力
@@ -849,14 +849,14 @@ class CacheAwareScheduler:
# Avoid holding a DB connection while awaiting cache/Redis inside ModelCacheService.
self._release_db_connection_before_await(db)
# 使用 ModelCacheService 解析模型名称(支持映射名)
global_model = await ModelCacheService.resolve_global_model_by_name_or_mapping(
db, model_name
)
# 仅接受 GlobalModel.name不允许映射名)
normalized_name = model_name.strip() if isinstance(model_name, str) else ""
if not normalized_name:
return False, "模型不存在或名称无效", None, None
if not global_model:
# 完全未找到匹配
return False, "模型不存在或 Provider 未配置此模型", None, None
global_model = await ModelCacheService.get_global_model_by_name(db, normalized_name)
if not global_model or not global_model.is_active:
return False, "模型不存在或已停用", None, None
# 找到 GlobalModel 后,检查当前 Provider 是否支持
is_supported, skip_reason, caps, provider_model_names = (

View File

@@ -86,30 +86,33 @@ class ModelMapperMiddleware:
获取模型映射
简化后的逻辑:
1. 通过 GlobalModel.name 或映射名解析 GlobalModel
1. 通过 GlobalModel.name 解析 GlobalModel
2. 找到 GlobalModel 后,查找该 Provider 的 Model 实现
Args:
source_model: 用户请求的模型名(可以是 GlobalModel.name 或映射名
source_model: 用户请求的模型名(必须是 GlobalModel.name
provider_id: 提供商ID (UUID)
Returns:
模型映射对象(包含 model 字段如果没有找到返回None
"""
# 检查缓存
cache_key = f"{provider_id}:{source_model}"
# 步骤 1: 规范化模型名称
normalized_name = source_model.strip() if isinstance(source_model, str) else ""
if not normalized_name:
logger.debug("GlobalModel not found: <empty model name>")
return None
# 检查缓存(使用规范化后的名称)
cache_key = f"{provider_id}:{normalized_name}"
if cache_key in self._cache:
return self._cache[cache_key]
mapping = None
# 步骤 1: 解析 GlobalModel(支持映射名)
global_model = await ModelCacheService.resolve_global_model_by_name_or_mapping(
self.db, source_model
)
global_model = await ModelCacheService.get_global_model_by_name(self.db, normalized_name)
if not global_model:
logger.debug(f"GlobalModel not found: {source_model}")
if not global_model or not global_model.is_active:
logger.debug(f"GlobalModel not found or inactive: {normalized_name}")
self._cache[cache_key] = None
return None
@@ -132,7 +135,7 @@ class ModelMapperMiddleware:
)()
logger.debug(
f"Found model mapping: {source_model} -> {model.provider_model_name} "
f"Found model mapping: {normalized_name} -> {model.provider_model_name} "
f"(provider={provider_id[:8]}...)"
)