mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
refactor: 增强跨格式转换系统,支持 thinking/文件/音频/响应格式等完整转换
- 新增 ThinkingConfig/ResponseFormatConfig/FileBlock/AudioBlock 内部表示 - 实现 OpenAI reasoning_effort <-> Claude thinking <-> Gemini thinkingConfig 互转 - 支持 OpenAI web_search_options -> Claude web_search tool 转换 - 新增异步 convert_request_async,在转换阶段解析图片 URL 为 base64 - 将 GlobalModel.output_limit 传播至跨格式转换用于 max_tokens 默认值 - 前端模型表单增加最大输出 Token 和上下文窗口配置 - Claude normalizer 保留 cache_control 透传(system 数组和 content block) - Gemini normalizer 支持内置工具(googleSearch/codeExecution/urlContext) - OpenAI normalizer 补全采样参数、response_format、usage details 转换 - 各 normalizer 工具方法提取至基类消除重复代码 - 简化 Kiro model mapping 为直接透传 - 预置模型列表添加 claude-sonnet-4.6
This commit is contained in:
@@ -20,41 +20,9 @@ from src.services.provider.adapters.kiro.constants import (
|
||||
|
||||
|
||||
def map_model(model: str) -> str | None:
|
||||
"""Map an Anthropic model name to a Kiro-compatible model ID.
|
||||
|
||||
Kiro upstream expects specific model IDs (e.g. ``claude-sonnet-4.5``).
|
||||
If *model* already matches a Kiro ID it is returned as-is; otherwise we
|
||||
attempt a best-effort fuzzy mapping. Returns ``None`` when the model is
|
||||
unrecognised.
|
||||
"""
|
||||
"""Pass through the model name as-is to Kiro upstream."""
|
||||
raw = str(model or "").strip()
|
||||
if not raw:
|
||||
return None
|
||||
|
||||
model_lower = raw.lower()
|
||||
|
||||
# Already a Kiro-native ID?
|
||||
_KIRO_NATIVE_IDS = {
|
||||
"claude-sonnet-4.5",
|
||||
"claude-opus-4.5",
|
||||
"claude-opus-4.6",
|
||||
"claude-haiku-4.5",
|
||||
}
|
||||
if model_lower in _KIRO_NATIVE_IDS:
|
||||
return model_lower
|
||||
|
||||
# Fuzzy mapping from Anthropic-style model names
|
||||
if "sonnet" in model_lower:
|
||||
return "claude-sonnet-4.5"
|
||||
if "opus" in model_lower:
|
||||
if "4-5" in model_lower or "4.5" in model_lower:
|
||||
return "claude-opus-4.5"
|
||||
return "claude-opus-4.6"
|
||||
if "haiku" in model_lower:
|
||||
return "claude-haiku-4.5"
|
||||
|
||||
# Unrecognised — pass through as-is (let the upstream decide)
|
||||
return raw
|
||||
return raw or None
|
||||
|
||||
|
||||
def _extract_session_id(user_id: str) -> str | None:
|
||||
|
||||
@@ -35,6 +35,12 @@ PRESET_MODELS: dict[str, list[dict[str, Any]]] = {
|
||||
"owned_by": "anthropic",
|
||||
"display_name": "Claude Sonnet 4.5",
|
||||
},
|
||||
{
|
||||
"id": "claude-sonnet-4.6",
|
||||
"object": "model",
|
||||
"owned_by": "anthropic",
|
||||
"display_name": "Claude Sonnet 4.6",
|
||||
},
|
||||
{
|
||||
"id": "claude-opus-4.5",
|
||||
"object": "model",
|
||||
|
||||
@@ -386,6 +386,17 @@ class CandidateBuilder:
|
||||
client_format_str = normalize_endpoint_signature(client_format)
|
||||
client_sig = parse_signature_key(client_format_str)
|
||||
client_family, client_kind = client_sig.api_family, client_sig.endpoint_kind
|
||||
|
||||
# 提取 GlobalModel 配置的 output_limit(用于跨格式转换时的 max_tokens 默认值)
|
||||
output_limit: int | None = None
|
||||
normalized_name = model_name.strip() if isinstance(model_name, str) else ""
|
||||
if normalized_name:
|
||||
gm = await ModelCacheService.get_global_model_by_name(db, normalized_name)
|
||||
if gm and isinstance(gm.config, dict):
|
||||
raw = gm.config.get("output_limit")
|
||||
if isinstance(raw, int) and raw > 0:
|
||||
output_limit = raw
|
||||
|
||||
# chat/cli 互相可回退(用于同协议族下的端点变体),video/image 等不跨类回退
|
||||
if client_kind in {EndpointKind.CHAT, EndpointKind.CLI}:
|
||||
allowed_kinds = {EndpointKind.CHAT, EndpointKind.CLI}
|
||||
@@ -581,6 +592,7 @@ class CandidateBuilder:
|
||||
mapping_matched_model=mapping_matched_model,
|
||||
needs_conversion=needs_conversion,
|
||||
provider_api_format=str(endpoint_format_str or ""),
|
||||
output_limit=output_limit,
|
||||
)
|
||||
|
||||
if needs_conversion:
|
||||
|
||||
@@ -28,6 +28,7 @@ class ProviderCandidate:
|
||||
mapping_matched_model: str | None = None # 通过映射匹配到的模型名(用于实际请求)
|
||||
needs_conversion: bool = False # 是否需要格式转换
|
||||
provider_api_format: str = "" # Provider 端点实际格式(用于健康度/熔断 bucket)
|
||||
output_limit: int | None = None # GlobalModel 配置的模型输出上限
|
||||
|
||||
def _stable_order_key(self) -> tuple[int, int, str, str, str]:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user