Skip to content

feat: 增加 MiniMax Anthropic 兼容预设#153

Open
Ekko0303 wants to merge 4 commits into
shenminglinyi:masterfrom
Ekko0303:master
Open

feat: 增加 MiniMax Anthropic 兼容预设#153
Ekko0303 wants to merge 4 commits into
shenminglinyi:masterfrom
Ekko0303:master

Conversation

@Ekko0303
Copy link
Copy Markdown

@Ekko0303 Ekko0303 commented Apr 29, 2026

改动说明:

  • 在 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 相关占位示例,不包含任何真实密钥。

变更类型

  • feat 新功能
  • fix Bug 修复
  • refactor 重构(不影响功能)
  • perf 性能优化
  • docs 文档
  • chore 构建/工具链

变更说明


架构影响

  • 涉及层级:domain / application / infrastructure / interfaces / frontend / scripts(删除不适用项)
  • 是否新增数据库表/字段:是 / 否(如是,请附 migration 说明)
  • 是否修改现有 API 契约(路径/字段/类型变更):是 / 否

测试

# 后端单测(必填,粘贴你实际跑的命令和结果摘要)
pytest tests/unit/... -q

# 前端构建(如改了前端必填)
cd frontend && npm run build
  • 新增/修改的逻辑有对应单测
  • 本地后端启动正常(python -m uvicorn ...
  • 本地前端启动正常(npm run dev

风险说明

  • 潜在风险:
  • 回滚方式:

Summary by CodeRabbit

  • New Features
    • Added MiniMax as an Anthropic-compatible LLM provider with a preset and default model/base URL.
    • Users can enable MiniMax by supplying optional environment credentials/placeholders.
    • Requests to MiniMax Anthropic endpoints now use Bearer token authentication for model listing and usage.

Review Change Stack

改动说明:

- 在 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 相关占位示例,不包含任何真实密钥。
@Ekko0303 Ekko0303 requested a review from shenminglinyi as a code owner April 29, 2026 12:25
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

📝 Walkthrough

Walkthrough

Adds MiniMax as an Anthropic-compatible provider: new .env.example placeholders, a minimax-anthropic preset and init-path handling, and a base-URL detector that changes Anthropic model-list requests to use Authorization: Bearer for MiniMax endpoints.

Changes

MiniMax Anthropic integration

Layer / File(s) Summary
Environment variables
.env.example
Adds MINIMAX_API_KEY, MINIMAX_BASE_URL (https://api.minimaxi.com/anthropic), and MINIMAX_MODEL (MiniMax-M2.7) placeholders.
Preset registration and init
application/ai/llm_control_service.py
Adds minimax-anthropic preset; reads MINIMAX_API_KEY and, when present, populates the Anthropic profile slot with MiniMax preset_key, base_url/model fallbacks and sets temperature=1.0, marking it active.
API auth header detection
interfaces/api/v1/workbench/llm_control.py
Adds _is_minimax_anthropic_base and uses Authorization: Bearer <api_key> for MiniMax Anthropic model-list requests; non-MiniMax Anthropic bases still use x-api-key. anthropic-version remains set.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • shenminglinyi/PlotPilot#24: Implements support for Anthropic-compatible third-party proxies with base_url normalization, model-list fetching, and authentication header switching logic.

Suggested reviewers

  • shenminglinyi

Poem

🐰 MiniMax hops into the fold,
New keys and URLs tucked in bold,
Presets set and headers switched,
Models fetched, the flow unhitched,
A happy rabbit code-snack, bright and gold.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description provides implementation details but lacks completion of required template sections: change type checkbox, architecture impact, and test results are unfilled. Complete the required template sections: check the 'feat' type checkbox, specify affected layers (application/interfaces), confirm no database changes, and provide actual test command results.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding MiniMax Anthropic-compatible preset support to the AI control panel.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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 | 🟠 Major

Seed 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 to protocol='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

📥 Commits

Reviewing files that changed from the base of the PR and between 6dab93a and 65cd882.

📒 Files selected for processing (3)
  • .env.example
  • application/ai/llm_control_service.py
  • interfaces/api/v1/workbench/llm_control.py

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 04457a6 and 8841271.

📒 Files selected for processing (2)
  • application/ai/llm_control_service.py
  • interfaces/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。',
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.

Comment on lines +602 to +611
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
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant