"""厂商解析:按 provider id / modelPrefix / 默认厂商定位。""" from __future__ import annotations import logging from typing import Optional from ..models.config import AppConfig, Provider from ..errors import HttpError logger = logging.getLogger(__name__) def resolve_provider( config: AppConfig, *, provider_id: Optional[str] = None, model: Optional[str] = None, ) -> Provider: """按优先级解析厂商:显式 id > modelPrefix 匹配 > 默认厂商。""" # 1. 显式 provider_id if provider_id: p = config.find_provider(provider_id) if not p: logger.warning("[resolver] provider not found or disabled: %s", provider_id) raise HttpError( f"Provider not found or disabled: {provider_id}", status=404, code="not_found", ) return p # 2. modelPrefix 匹配 if model: for p in config.providers: if not p.enabled or not p.model_prefix: continue if model.startswith(p.model_prefix): return p # 3. 默认厂商 default = config.find_default_provider() if not default: logger.warning("[resolver] no enabled provider configured") raise HttpError( "No enabled provider configured. Add one in /admin.", status=503, code="service_unavailable", ) return default def normalize_model(provider: Provider, model: Optional[str], *, fallback: Optional[str] = None) -> str: """剥离 provider 前缀,回退到默认模型。""" if model: if provider.model_prefix and model.startswith(provider.model_prefix): return model[len(provider.model_prefix):] return model if fallback: return fallback if provider.type == "gemini": from ..config import GEMINI_DEFAULT_MODEL return GEMINI_DEFAULT_MODEL return "gpt-4o-mini"