"""模型服务商预设目录。 预设只保存公开的协议与端点,不保存用户凭据。需要云 IAM、部署名称或 业务空间域名的服务商仍展示在目录中,但不会误导用户只靠 API Key 即可连接。 """ from dataclasses import dataclass @dataclass(frozen=True) class ModelProvider: """描述一个可展示、可验证的模型服务商预设。""" code: str name: str vendor: str category: str protocol: str base_url: str = "" models_path: str = "models" default_model: str = "" key_only: bool = True note: str = "" mark: str = "AI" @property def protocol_label(self) -> str: labels = { "openai_responses": "Responses API", "openai_compatible": "OpenAI 兼容", "anthropic_messages": "Messages API", "gemini": "Gemini API", "cloud": "云平台接口", } return labels.get(self.protocol, self.protocol) PROVIDERS = ( ModelProvider( "openai", "OpenAI", "OpenAI", "official", "openai_responses", "https://api.openai.com/v1", default_model="gpt-5.6-terra", mark="OA", ), ModelProvider( "anthropic", "Anthropic Claude", "Anthropic", "official", "anthropic_messages", "https://api.anthropic.com/v1", default_model="claude-sonnet-4-6", mark="CL", ), ModelProvider( "deepseek", "DeepSeek", "深度求索", "domestic", "openai_compatible", "https://api.deepseek.com", default_model="deepseek-chat", mark="DS", ), ModelProvider( "gemini", "Google Gemini", "Google", "official", "gemini", "https://generativelanguage.googleapis.com/v1beta", models_path="models", default_model="gemini-2.5-flash", mark="GE", ), ModelProvider( "aliyun", "阿里云百炼 / Qwen", "阿里云", "domestic", "openai_compatible", "https://dashscope.aliyuncs.com/compatible-mode/v1", default_model="qwen-plus", mark="QW", ), ModelProvider( "zhipu", "智谱 AI / Z.AI", "智谱", "domestic", "openai_compatible", "https://open.bigmodel.cn/api/paas/v4", default_model="glm-4.5", mark="GL", ), ModelProvider( "xiaomi_mimo", "小米 MiMo", "小米", "domestic", "openai_compatible", key_only=False, note="官方端点及账户区域确认后开放", mark="MI", ), ModelProvider( "siliconflow", "硅基流动", "SiliconFlow", "domestic", "openai_compatible", "https://api.siliconflow.cn/v1", default_model="deepseek-ai/DeepSeek-V3", mark="SF", ), ModelProvider( "moonshot", "月之暗面 Kimi", "Moonshot AI", "domestic", "openai_compatible", "https://api.moonshot.cn/v1", default_model="moonshot-v1-8k", mark="KM", ), ModelProvider( "minimax", "MiniMax", "MiniMax", "domestic", "openai_compatible", key_only=False, note="部分账户还需要 Group ID", mark="MM", ), ModelProvider( "volcengine", "火山引擎方舟 / 豆包", "火山引擎", "domestic", "cloud", key_only=False, note="需要接入点或推理端点配置", mark="DB", ), ModelProvider( "baidu", "百度智能云千帆 / 文心", "百度智能云", "domestic", "cloud", key_only=False, note="需要应用或云鉴权配置", mark="BD", ), ModelProvider( "tencent", "腾讯混元", "腾讯云", "domestic", "cloud", key_only=False, note="需要腾讯云鉴权配置", mark="HY", ), ModelProvider( "huawei", "华为云 ModelArts / 盘古", "华为云", "domestic", "cloud", key_only=False, note="需要项目、区域及云鉴权配置", mark="HW", ), ModelProvider( "openrouter", "OpenRouter", "OpenRouter", "gateway", "openai_compatible", "https://openrouter.ai/api/v1", default_model="openai/gpt-4o-mini", mark="OR", ), ModelProvider( "groq", "Groq", "Groq", "gateway", "openai_compatible", "https://api.groq.com/openai/v1", default_model="llama-3.3-70b-versatile", mark="GQ", ), ModelProvider( "together", "Together AI", "Together AI", "gateway", "openai_compatible", "https://api.together.xyz/v1", mark="TO", ), ModelProvider( "mistral", "Mistral AI", "Mistral", "official", "openai_compatible", "https://api.mistral.ai/v1", default_model="mistral-large-latest", mark="MS", ), ModelProvider( "cohere", "Cohere", "Cohere", "official", "openai_compatible", key_only=False, note="原生协议适配待接入", mark="CO", ), ModelProvider( "xai", "xAI Grok", "xAI", "official", "openai_compatible", "https://api.x.ai/v1", default_model="grok-4", mark="XA", ), ModelProvider( "azure_openai", "Azure OpenAI", "Microsoft Azure", "cloud", "cloud", key_only=False, note="需要资源端点和部署名称", mark="AZ", ), ModelProvider( "aws_bedrock", "AWS Bedrock", "Amazon Web Services", "cloud", "cloud", key_only=False, note="需要区域和 AWS IAM 凭据", mark="AW", ), ModelProvider( "custom", "自定义 OpenAI 兼容服务", "自定义", "gateway", "openai_compatible", key_only=False, note="需要 Base URL 和模型 ID", mark="+", ), ) PROVIDER_BY_CODE = {provider.code: provider for provider in PROVIDERS} CATEGORY_LABELS = { "all": "全部", "official": "官方直连", "domestic": "国内平台", "gateway": "云与聚合", "cloud": "云平台", "connected": "已连接", } def get_provider(code: str) -> ModelProvider | None: """按稳定编码读取预设,未知编码返回空值。""" return PROVIDER_BY_CODE.get(code)