From 65cd882776dd7f4851c983beadbb315b5c534778 Mon Sep 17 00:00:00 2001 From: Ekko0303 <1048894033@qq.com> Date: Wed, 29 Apr 2026 19:45:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20MiniMax=20Anthropi?= =?UTF-8?q?c=20=E5=85=BC=E5=AE=B9=E9=A2=84=E8=AE=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 改动说明: - 在 AI 控制台厂商预设中新增 MiniMax / Anthropic 兼容配置,默认 Base URL 为 https://api.minimaxi.com/anthropic,默认模型为 MiniMax-M2.7。 - 支持通过 MINIMAX_API_KEY、MINIMAX_BASE_URL、MINIMAX_MODEL 初始化 MiniMax 配置。 - 模型列表接口识别 MiniMax Anthropic 端点,并按 MiniMax 文档使用 Bearer Token 认证拉取模型列表。 - 更新 .env.example,仅增加 MiniMax 相关占位示例,不包含任何真实密钥。 --- .env.example | 5 +++++ application/ai/llm_control_service.py | 20 +++++++++++++++++ interfaces/api/v1/workbench/llm_control.py | 26 ++++++++++++++++++---- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index 0068b2e4a..54c1d9415 100644 --- a/.env.example +++ b/.env.example @@ -4,6 +4,11 @@ # ANTHROPIC_AUTH_TOKEN= # ANTHROPIC_BASE_URL= +# MiniMax Anthropic-compatible preset +# MINIMAX_API_KEY= +# MINIMAX_BASE_URL=https://api.minimaxi.com/anthropic +# MINIMAX_MODEL=MiniMax-M2.7 + # 与 aivideo 共用方舟凭证 ARK_API_KEY= ARK_BASE_URL=https://ark.cn-beijing.volces.com/api/v3/chat/completions diff --git a/application/ai/llm_control_service.py b/application/ai/llm_control_service.py index dee87f7e0..bc6371eb8 100644 --- a/application/ai/llm_control_service.py +++ b/application/ai/llm_control_service.py @@ -248,6 +248,15 @@ def get_presets(self) -> List[LLMPreset]: description='智谱 Anthropic-compatible 接口。模型名以智谱文档为准。', tags=['domestic', 'preset'], ), + LLMPreset( + key='minimax-anthropic', + label='MiniMax / Anthropic 兼容', + protocol='anthropic', + default_base_url='https://api.minimaxi.com/anthropic', + default_model='MiniMax-M2.7', + description='MiniMax Anthropic-compatible 接口;默认使用 MiniMax-M2.7,也可改为 MiniMax-M2.7-highspeed 等官方模型 ID。', + tags=['domestic', 'preset'], + ), LLMPreset( key='doubao-ark', label='豆包 / 火山方舟 Ark', @@ -532,6 +541,7 @@ def _build_initial_config(self) -> LLMControlConfig: anthropic_key = (os.getenv('ANTHROPIC_API_KEY') or os.getenv('ANTHROPIC_AUTH_TOKEN') or '').strip() openai_key = (os.getenv('OPENAI_API_KEY') or '').strip() gemini_key = (os.getenv('GEMINI_API_KEY') or '').strip() + minimax_key = (os.getenv('MINIMAX_API_KEY') or '').strip() ark_key = (os.getenv('ARK_API_KEY') or '').strip() if anthropic_key and (llm_provider == 'anthropic' or not llm_provider): @@ -557,6 +567,16 @@ def _build_initial_config(self) -> LLMControlConfig: 'model': (os.getenv('GEMINI_MODEL') or '').strip() or profiles[2].model, }) active_profile_id = profiles[2].id + elif minimax_key: + profiles[1] = profiles[1].model_copy(update={ + 'name': 'MiniMax / Anthropic', + 'preset_key': 'minimax-anthropic', + 'api_key': minimax_key, + 'base_url': (os.getenv('MINIMAX_BASE_URL') or '').strip() or 'https://api.minimaxi.com/anthropic', + 'model': (os.getenv('MINIMAX_MODEL') or '').strip() or 'MiniMax-M2.7', + 'temperature': 1.0, + }) + active_profile_id = profiles[1].id elif ark_key: profiles[0] = profiles[0].model_copy(update={ 'name': '豆包 / Ark', diff --git a/interfaces/api/v1/workbench/llm_control.py b/interfaces/api/v1/workbench/llm_control.py index c21dfeb5d..49ab41cfa 100644 --- a/interfaces/api/v1/workbench/llm_control.py +++ b/interfaces/api/v1/workbench/llm_control.py @@ -72,6 +72,18 @@ def _openai_compatible_models_base(base_url: str) -> str: ).rstrip('/') +def _is_minimax_anthropic_base(base_url: str) -> bool: + raw = (base_url or '').strip() + if not raw: + return False + if '://' not in raw: + raw = f'https://{raw}' + parsed = urlparse(raw) + host = (parsed.netloc or '').lower() + path = (parsed.path or '').lower() + return host.endswith('minimaxi.com') and '/anthropic' in path + + def _normalize_model_items(data: Dict[str, Any]) -> List[ModelItem]: """将不同网关的 /models 响应统一为 ModelItem 列表。""" items: List[ModelItem] = [] @@ -109,10 +121,16 @@ async def list_models(payload: ModelListRequest) -> ModelListResponse: if api_format == 'anthropic': url = f"{(base_url or 'https://api.anthropic.com').rstrip('/')}/v1/models" - headers = { - 'x-api-key': api_key, - 'anthropic-version': '2023-06-01', - } + if _is_minimax_anthropic_base(base_url): + headers = { + 'Authorization': f'Bearer {api_key}', + 'anthropic-version': '2023-06-01', + } + else: + headers = { + 'x-api-key': api_key, + 'anthropic-version': '2023-06-01', + } else: openai_base = _openai_compatible_models_base(base_url) url = f'{openai_base}/models'