Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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 @@ -253,6 +253,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 @@ -564,6 +573,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 @@ -589,6 +599,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