refactor: 统一测试请求构建逻辑,支持多格式测试

- 重构 adapter 基类的 build_request_body 方法,使用 converter_registry 自动处理格式转换
- 后端 test_model 接口增加 endpoint_id 和 api_format 参数支持
- 前端模型映射测试支持根据 Key 和端点配置动态显示可用格式下拉菜单
This commit is contained in:
fawney19
2026-01-22 23:25:51 +08:00
parent 6c7b40764f
commit 1da70d0518
12 changed files with 264 additions and 85 deletions

View File

@@ -107,10 +107,18 @@ class ChatAdapterBase(ApiAdapter):
return build_adapter_headers(cls._get_api_format(), api_key, extra_headers)
@classmethod
def build_request_body(cls, request_data: Dict[str, Any]) -> Dict[str, Any]:
"""构建请求体,子类可以覆盖以自定义请求格式转换"""
# 默认实现:直接使用请求数据
return request_data.copy()
def build_request_body(cls, request_data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""构建测试请求体,使用转换器注册表自动处理格式转换
Args:
request_data: 可选的请求数据,会与默认测试请求合并
Returns:
转换为目标 API 格式的请求体
"""
from src.api.handlers.base.request_builder import build_test_request_body
return build_test_request_body(cls.FORMAT_ID, request_data)
def extract_api_key(self, request: Request) -> Optional[str]:
"""从请求中提取 API 密钥,使用统一的 headers.py 实现"""

View File

@@ -684,17 +684,18 @@ class CliAdapterBase(ApiAdapter):
raise NotImplementedError(f"{cls.FORMAT_ID} adapter must implement build_endpoint_url")
@classmethod
def build_request_body(cls, request_data: Dict[str, Any]) -> Dict[str, Any]:
"""
构建CLI API请求体 - 子类应覆盖
def build_request_body(cls, request_data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""构建测试请求体,使用转换器注册表自动处理格式转换
Args:
request_data: 请求数据
request_data: 可选的请求数据,会与默认测试请求合并
Returns:
请求体字典
转换为目标 API 格式的请求体
"""
raise NotImplementedError(f"{cls.FORMAT_ID} adapter must implement build_request_body")
from src.api.handlers.base.request_builder import build_test_request_body
return build_test_request_body(cls.FORMAT_ID, request_data)
@classmethod
def get_cli_user_agent(cls) -> Optional[str]:

View File

@@ -27,6 +27,67 @@ from src.core.api_format import HeaderBuilder, UPSTREAM_DROP_HEADERS
SENSITIVE_HEADERS: FrozenSet[str] = UPSTREAM_DROP_HEADERS
# ==============================================================================
# 测试请求常量与辅助函数
# ==============================================================================
# 标准测试请求体OpenAI 格式)
# 用于 check_endpoint 等测试场景,使用简单安全的消息内容避免触发安全过滤
DEFAULT_TEST_REQUEST: Dict[str, Any] = {
"messages": [{"role": "user", "content": "Hi"}],
"max_tokens": 5,
"temperature": 0,
}
def get_test_request_data(request_data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""获取测试请求数据
如果传入 request_data则合并到默认测试请求中
否则使用默认测试请求。
Args:
request_data: 用户提供的请求数据(会覆盖默认值)
Returns:
合并后的测试请求数据OpenAI 格式)
"""
if request_data:
merged = DEFAULT_TEST_REQUEST.copy()
merged.update(request_data)
return merged
return DEFAULT_TEST_REQUEST.copy()
def build_test_request_body(
format_id: str,
request_data: Optional[Dict[str, Any]] = None,
) -> Dict[str, Any]:
"""构建测试请求体,自动处理格式转换
使用 converter_registry 将 OpenAI 格式的测试请求转换为目标格式。
Args:
format_id: 目标 API 格式 ID"CLAUDE", "GEMINI", "OPENAI_CLI"
request_data: 可选的请求数据,会与默认测试请求合并
Returns:
转换为目标 API 格式的请求体
"""
from src.core.api_format.conversion import converter_registry
from src.core.api_format.utils import get_base_format
# 获取测试请求数据OpenAI 格式)
source_data = get_test_request_data(request_data)
# CLI 格式使用基础格式进行转换CLAUDE_CLI -> CLAUDE
# 因为 converter_registry 只注册了基础格式之间的转换器
target_format = get_base_format(format_id) or format_id
# 使用注册表进行格式转换 (OPENAI -> 目标基础格式)
return converter_registry.convert_request(source_data, "OPENAI", target_format)
# ==============================================================================
# 请求构建器
# ==============================================================================