feat: 增加 MiniMax Anthropic 兼容预设#153
Conversation
改动说明: - 在 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 相关占位示例,不包含任何真实密钥。
📝 WalkthroughWalkthroughAdds MiniMax as an Anthropic-compatible provider: new ChangesMiniMax Anthropic integration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
interfaces/api/v1/workbench/llm_control.py (1)
108-133:⚠️ Potential issue | 🟠 MajorSeed the active profile's protocol and base URL when falling back.
Right now the fallback only copies
api_key, so requests that rely on the stored MiniMax profile still default toprotocol='openai'and an empty base URL. That skips_is_minimax_anthropic_base()and sends the wrong auth header unless the caller redundantly supplies the endpoint fields.🔧 Proposed fix
if not candidate.get('api_key'): # 尝试从当前激活配置中获取 key 作为 fallback active = _service.get_active_profile() if active: - candidate['api_key'] = active.api_key + candidate.update({ + 'api_key': active.api_key, + 'protocol': active.protocol, + 'base_url': active.base_url, + })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@interfaces/api/v1/workbench/llm_control.py` around lines 108 - 133, When falling back to the active profile in the candidate block (use _service.get_active_profile() and the candidate dict), also copy the active profile's protocol and base_url into candidate (not just api_key) so api_format = (candidate.get('protocol')...) and base_url = (candidate.get('base_url')...) reflect the stored profile; this ensures _is_minimax_anthropic_base(base_url) sees the MiniMax endpoint and the correct auth header is selected instead of defaulting to openai/empty base URL.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@interfaces/api/v1/workbench/llm_control.py`:
- Around line 108-133: When falling back to the active profile in the candidate
block (use _service.get_active_profile() and the candidate dict), also copy the
active profile's protocol and base_url into candidate (not just api_key) so
api_format = (candidate.get('protocol')...) and base_url =
(candidate.get('base_url')...) reflect the stored profile; this ensures
_is_minimax_anthropic_base(base_url) sees the MiniMax endpoint and the correct
auth header is selected instead of defaulting to openai/empty base URL.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 587b1cf2-40d7-4a51-be80-ba95f44f14c0
📒 Files selected for processing (3)
.env.exampleapplication/ai/llm_control_service.pyinterfaces/api/v1/workbench/llm_control.py
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with 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.
Inline comments:
In `@application/ai/llm_control_service.py`:
- 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.
- Around line 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.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 4850b83a-e4be-4f9e-b280-79dce328584a
📒 Files selected for processing (2)
application/ai/llm_control_service.pyinterfaces/api/v1/workbench/llm_control.py
🚧 Files skipped from review as they are similar to previous changes (1)
- interfaces/api/v1/workbench/llm_control.py
| 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。', |
There was a problem hiding this comment.
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.
| 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.
| 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 |
There was a problem hiding this comment.
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.
改动说明:
变更类型
feat新功能fixBug 修复refactor重构(不影响功能)perf性能优化docs文档chore构建/工具链变更说明
架构影响
domain/application/infrastructure/interfaces/frontend/scripts(删除不适用项)测试
python -m uvicorn ...)npm run dev)风险说明
Summary by CodeRabbit