Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions application/ai/llm_control_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -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。',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Resolve Ruff RUF001 on ambiguous punctuation in preset description.

Line 262 uses fullwidth and , which Ruff flags as ambiguous unicode punctuation.

Suggested fix
-                description='MiniMax Anthropic-compatible 接口;默认使用 MiniMax-M2.7,也可改为 MiniMax-M2.7-highspeed 等官方模型 ID。',
+                description='MiniMax Anthropic-compatible 接口; 默认使用 MiniMax-M2.7, 也可改为 MiniMax-M2.7-highspeed 等官方模型 ID。',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
description='MiniMax Anthropic-compatible 接口默认使用 MiniMax-M2.7也可改为 MiniMax-M2.7-highspeed 等官方模型 ID。',
description='MiniMax Anthropic-compatible 接口; 默认使用 MiniMax-M2.7, 也可改为 MiniMax-M2.7-highspeed 等官方模型 ID。',
🧰 Tools
🪛 Ruff (0.15.13)

[warning] 262-262: String contains ambiguous (FULLWIDTH SEMICOLON). Did you mean ; (SEMICOLON)?

(RUF001)


[warning] 262-262: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@application/ai/llm_control_service.py` at line 262, The description string
passed as the description parameter in ai/llm_control_service.py uses fullwidth
punctuation (fullwidth `;` and `,`) which triggers Ruff RUF001; replace those
characters with standard ASCII punctuation (use `;` and `,`) in the description
literal (the line containing description='MiniMax Anthropic-compatible 接口;默认使用
MiniMax-M2.7,也可改为 MiniMax-M2.7-highspeed 等官方模型 ID。') so the text becomes
ASCII-punctuated while preserving the rest of the content.

tags=['domestic', 'preset'],
),
LLMPreset(
key='doubao-ark',
label='豆包 / 火山方舟 Ark',
Expand Down Expand Up @@ -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):
Expand All @@ -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
Comment on lines +602 to +611

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Honor explicit LLM_PROVIDER when selecting MiniMax defaults.

The MiniMax branch currently ignores LLM_PROVIDER. If users explicitly set another provider, this can still switch active profile to MiniMax unexpectedly.

Suggested fix
-        elif minimax_key:
+        elif minimax_key and (llm_provider in ('anthropic', 'minimax') or not llm_provider):
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@application/ai/llm_control_service.py` around lines 602 - 611, The MiniMax
branch should respect an explicit LLM_PROVIDER env var; modify the conditional
around the minimax_key branch so it only applies the MiniMax defaults when
LLM_PROVIDER is not set/empty or explicitly set to a MiniMax value (e.g.,
'minimax'), rather than unconditionally when minimax_key exists. Concretely,
update the check that guards the profiles[1].model_copy(...) and
active_profile_id assignment to include a test like os.getenv('LLM_PROVIDER',
'').strip().lower() in ('', 'minimax') (or equivalent) so that if a user sets
LLM_PROVIDER to another provider the branch is skipped and the active profile is
not switched to MiniMax. Ensure you reference the minimax_key variable, the
profiles[1].model_copy(...) call, and the active_profile_id assignment when
making the change.

elif ark_key:
profiles[0] = profiles[0].model_copy(update={
'name': '豆包 / Ark',
Expand Down
26 changes: 22 additions & 4 deletions interfaces/api/v1/workbench/llm_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -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] = []
Expand Down Expand Up @@ -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'
Expand Down