feat(providers): add MiniMax support - #1058
Conversation
📝 WalkthroughWalkthroughMiniMax is integrated as a provider across server runtime execution, authentication, models, session synchronization, API routing, chat state, provider selection, settings, MCP, skills, documentation, and UI rendering. ChangesMiniMax provider
Sequence Diagram(s)sequenceDiagram
participant Client
participant AgentRoute
participant MiniMaxSDK
participant ClaudeSDK
Client->>AgentRoute: Request provider=minimax
AgentRoute->>MiniMaxSDK: Start MiniMax session
MiniMaxSDK->>ClaudeSDK: Execute with MiniMax runtime configuration
ClaudeSDK-->>Client: Stream provider-scoped events
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ 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.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
server/claude-sdk.js (1)
308-324: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winApply the override in the legacy usage fallback too.
The
modelUsagebranch still readsprocess.env.CONTEXT_WINDOW, so fallback MiniMax events report the wrong total context window.Proposed fix
- const contextWindow = parseInt(process.env.CONTEXT_WINDOW, 10) || 160000; + const contextWindow = Number.isFinite(contextWindowOverride) + ? contextWindowOverride + : parseInt(process.env.CONTEXT_WINDOW, 10) || 160000;🤖 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 `@server/claude-sdk.js` around lines 308 - 324, The context window override is not applied in the legacy modelUsage fallback of extractTokenBudget. Update that fallback to use contextWindowOverride when it is finite, matching the existing messageUsage branch, and only read process.env.CONTEXT_WINDOW when no valid override is provided.
🤖 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 `@server/modules/providers/list/minimax/minimax-auth.provider.ts`:
- Around line 12-19: Update checkInstalled() to retain the result returned by
spawn.sync and return false when its error property indicates the executable
failed to launch; preserve the existing true result for successful execution and
catch-based handling for thrown failures.
In `@server/modules/providers/list/minimax/minimax-models.provider.ts`:
- Around line 62-69: Update getCurrentActiveModel to read the persisted session
model override before falling back to
buildDefaultProviderCurrentActiveModel(MINIMAX_MODELS), ensuring the model
selected by changeActiveModel is returned for the current session while
retaining the catalog default when no override exists.
In `@server/modules/providers/list/minimax/minimax.provider.ts`:
- Around line 106-114: Implement MiniMaxSessionSynchronizer.synchronize() and
synchronizeFile() so MiniMax transcripts are discovered rather than returning
hardcoded no-op values. Reuse the ClaudeProvider session synchronizer/file
indexer when MiniMax transcripts share Claude artifacts; otherwise add
MiniMax-specific scanning, ensuring synchronize() reports discovered sessions
and synchronizeFile() returns the synchronized file path.
In `@src/components/provider-auth/view/ProviderLoginModal.tsx`:
- Around line 44-46: Update the MiniMax branch in the provider
command/configuration logic so its absent-customCommand default performs the
actual MiniMax credential setup or presents the API-key form, rather than
executing the diagnostic `claude --version` command. Preserve customCommand
handling for configured providers and ensure the default flow stores or applies
the MiniMax API endpoint and token required for authentication.
In
`@src/components/settings/view/tabs/agents-settings/sections/AgentCategoryContentSection.tsx`:
- Line 32: Update the permissions branch in AgentCategoryContentSection so
MiniMax does not reuse Claude’s provider context: add MiniMax-specific
permission state and handlers, pass selectedAgent through to the permissions UI,
and read/write MiniMax permissions independently. If that contract is
unavailable, restrict the branch to Claude instead of rendering MiniMax with
Claude state.
---
Outside diff comments:
In `@server/claude-sdk.js`:
- Around line 308-324: The context window override is not applied in the legacy
modelUsage fallback of extractTokenBudget. Update that fallback to use
contextWindowOverride when it is finite, matching the existing messageUsage
branch, and only read process.env.CONTEXT_WINDOW when no valid override is
provided.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 70b2e5e8-9206-4c3e-8c33-d3cc16303c81
📒 Files selected for processing (41)
.env.examplepublic/api-docs.htmlserver/claude-sdk.jsserver/index.jsserver/minimax-sdk.tsserver/modules/providers/list/claude/claude-session-synchronizer.provider.tsserver/modules/providers/list/minimax/minimax-auth.provider.tsserver/modules/providers/list/minimax/minimax-config.tsserver/modules/providers/list/minimax/minimax-models.provider.tsserver/modules/providers/list/minimax/minimax.provider.tsserver/modules/providers/provider.registry.tsserver/modules/providers/provider.routes.tsserver/modules/providers/services/provider-capabilities.service.tsserver/modules/providers/services/session-conversations-search.service.tsserver/modules/providers/services/session-synchronizer.service.tsserver/modules/providers/tests/mcp.test.tsserver/modules/providers/tests/minimax-provider.test.tsserver/routes/agent.jsserver/routes/commands.jsserver/shared/types.tssrc/components/chat/hooks/useChatComposerState.tssrc/components/chat/hooks/useChatProviderState.tssrc/components/chat/view/ChatInterface.tsxsrc/components/chat/view/subcomponents/ChatMessagesPane.tsxsrc/components/chat/view/subcomponents/CommandResultModal.tsxsrc/components/chat/view/subcomponents/MessageComponent.tsxsrc/components/chat/view/subcomponents/ProviderSelectionEmptyState.tsxsrc/components/llm-logo-provider/MiniMaxLogo.tsxsrc/components/llm-logo-provider/SessionProviderLogo.tsxsrc/components/mcp/constants.tssrc/components/onboarding/view/subcomponents/AgentConnectionsStep.tsxsrc/components/provider-auth/types.tssrc/components/provider-auth/view/ProviderLoginModal.tsxsrc/components/settings/constants/constants.tssrc/components/settings/view/tabs/agents-settings/AgentListItem.tsxsrc/components/settings/view/tabs/agents-settings/AgentsSettingsTab.tsxsrc/components/settings/view/tabs/agents-settings/sections/AgentCategoryContentSection.tsxsrc/components/settings/view/tabs/agents-settings/sections/AgentSelectorSection.tsxsrc/components/settings/view/tabs/agents-settings/sections/content/AccountContent.tsxsrc/components/skills/view/ProviderSkills.tsxsrc/types/app.ts
| private checkInstalled(): boolean { | ||
| const cliPath = resolveClaudeCodeExecutablePath(process.env.CLAUDE_CLI_PATH); | ||
| try { | ||
| spawn.sync(cliPath, ['--version'], { stdio: 'ignore', timeout: 5000 }); | ||
| return true; | ||
| } catch { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
curl -fsSL https://registry.npmjs.org/cross-spawn/7.0.3 \
| jq -r '.dist.tarball' \
| xargs -I{} curl -fsSL "{}" \
| tar -xz -C "$tmp"
rg -n -C3 'spawnSync|result\.error|spawn\.sync' "$tmp/package"Repository: siteboon/claudecodeui
Length of output: 4446
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate and inspect the referenced file and related spawn checks without running repo code.
file="server/modules/providers/list/minimax/minimax-auth.provider.ts"
if [ -f "$file" ]; then
echo "=== referenced file outline ==="
ast-grep outline "$file" --view expanded || true
echo "=== referenced file lines 1-80 ==="
sed -n '1,80p' "$file" | cat -n
else
echo "Referenced file not found: $file"
fi
echo "=== usages of checkInstalled / resolveClaudeCodeExecutablePath / CLAUDE_CLI_PATH ==="
rg -n "checkInstalled|resolveClaudeCodeExecutablePath|CLAUDE_CLI_PATH|spawn\.sync|spawnSync|error" server/modules/providers/library server/modules/providers/list/minimax -S || true
echo "=== deterministic probe of Node child_process.spawnSync behavior for missing executable ==="
node - <<'JS'
const { spawnSync } = require('child_process');
const result = spawnSync('/tmp/coderabbit-shell-logs/shell-output-SHOULD_NOT_EXIST_MISSING_EXECUTABLE_FOR_PROBE', ['--version'], { stdio: 'ignore', timeout: 5000 });
console.log(JSON.stringify({
status: result.status,
hasCode: Object.hasOwn(result, 'status'),
hasError: Object.hasOwn(result, 'error'),
errorName: result.error && result.error.name,
code: result.error && result.error.code,
errno: result.error && result.error.errno
}, null, 2));
JSRepository: siteboon/claudecodeui
Length of output: 3558
Check the synchronous spawn result for launch failures.
spawn.sync() returns a result with error when the executable cannot be launched, so checkInstalled() currently reports the CLI as installed even when it is missing.
Proposed fix
- spawn.sync(cliPath, ['--version'], { stdio: 'ignore', timeout: 5000 });
- return true;
+ const result = spawn.sync(cliPath, ['--version'], { stdio: 'ignore', timeout: 5000 });
+ return !result.error;📝 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.
| private checkInstalled(): boolean { | |
| const cliPath = resolveClaudeCodeExecutablePath(process.env.CLAUDE_CLI_PATH); | |
| try { | |
| spawn.sync(cliPath, ['--version'], { stdio: 'ignore', timeout: 5000 }); | |
| return true; | |
| } catch { | |
| return false; | |
| } | |
| private checkInstalled(): boolean { | |
| const cliPath = resolveClaudeCodeExecutablePath(process.env.CLAUDE_CLI_PATH); | |
| try { | |
| const result = spawn.sync(cliPath, ['--version'], { stdio: 'ignore', timeout: 5000 }); | |
| return !result.error; | |
| } catch { | |
| return false; | |
| } |
🤖 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 `@server/modules/providers/list/minimax/minimax-auth.provider.ts` around lines
12 - 19, Update checkInstalled() to retain the result returned by spawn.sync and
return false when its error property indicates the executable failed to launch;
preserve the existing true result for successful execution and catch-based
handling for thrown failures.
| async getCurrentActiveModel(): Promise<ProviderCurrentActiveModel> { | ||
| return buildDefaultProviderCurrentActiveModel(MINIMAX_MODELS); | ||
| } | ||
|
|
||
| async changeActiveModel( | ||
| input: ProviderChangeActiveModelInput, | ||
| ): Promise<ProviderSessionActiveModelChange> { | ||
| return writeProviderSessionActiveModelChange('minimax', input); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Read the persisted session model override.
changeActiveModel stores the requested model, but getCurrentActiveModel unconditionally returns MINIMAX_MODELS.DEFAULT. After selecting MiniMax-M2.7, active-model reads will still report MiniMax-M3. Resolve the session-scoped override before falling back to the catalog default.
🤖 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 `@server/modules/providers/list/minimax/minimax-models.provider.ts` around
lines 62 - 69, Update getCurrentActiveModel to read the persisted session model
override before falling back to
buildDefaultProviderCurrentActiveModel(MINIMAX_MODELS), ensuring the model
selected by changeActiveModel is returned for the current session while
retaining the catalog default when no override exists.
| class MiniMaxSessionSynchronizer implements IProviderSessionSynchronizer { | ||
| async synchronize(): Promise<number> { | ||
| return 0; | ||
| } | ||
|
|
||
| async synchronizeFile(): Promise<string | null> { | ||
| return null; | ||
| } | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fd -t f 'session-synchronizer.*|synchronizer.*service.*' server/modules/providers \
-x sh -c 'echo "=== $1 ==="; rg -n -C3 "sessionSynchronizer|\\.synchronize\\(" "$1"' sh {}Repository: siteboon/claudecodeui
Length of output: 1467
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== provider files mentioning MiniMax ==="
rg -n -i "MiniMax|max" server/server/modules/providers -g '*.ts' || true
echo
echo "=== providerRegistry / provider registration ==="
fd -t f 'provider.*registry|provider.*list|registry' server/modules/providers -x sh -c 'echo "=== $1 ==="; rg -n -C4 "registerProvider|listProviders|MiniMax|minimax|sessionSynchronizer" "$1" || true' sh {}
echo
echo "=== MiniMax provider file outline ==="
f=$(fd -t f 'minimax\.provider\.ts$' server | head -n1 || true)
if [ -n "${f:-}" ]; then
echo "FILE=$f"
wc -l "$f"
ast-grep outline "$f" --view expanded || true
sed -n '1,180p' "$f" | cat -n
fiRepository: siteboon/claudecodeui
Length of output: 8594
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== session synchronizer service ==="
sed -n '1,140p' server/modules/providers/services/session-synchronizer.service.ts | cat -n
echo
echo "=== MiniMax and Claude provider registrations ==="
sed -n '1,180p' server/modules/providers/list/minimax/minimax.provider.ts | cat -n >/tmp/minimax.ts
sed -n '1,140p' server/modules/providers/list/claude/claude.provider.ts | cat -n >/tmp/claude.ts
printf '\n=== MiniMax imports/exports ===\n'
sed -n '1,40p' /tmp/minimax.ts >/tmp/minimax_header.ts
cat /tmp/minimax_header.ts
printf '\n=== Claude imports/exports ===\n'
sed -n '1,40p' /tmp/claude.ts >/tmp/claude_header.ts
cat /tmp/claude_header.ts
echo
echo "=== all provider registration points ==="
rg -n "new .*Provider\(\)|providerRegistry|listProviders|sessionSynchronizer" server/modules/providers server -g '*.ts' | head -n 220Repository: siteboon/claudecodeui
Length of output: 24691
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== MiniMax provider tests ==="
sed -n '1,220p' server/modules/providers/tests/minimax-provider.test.ts | cat -n
echo
echo "=== references to MiniMax provider/sessions/synchronizer outside list ==="
rg -n "MiniMaxProvider|minimax|minimax-provider|minimax\\.|MiniMax.*Sessions|MiniMax.*Synchronizers|minimax" server/modules -g '*.ts' | rg -v "provider.registry|list/minimax|minimax.provider.ts|minimax-provider.test.ts|claude.provider.ts|shared/interfaces.ts|shared/types.ts" || trueRepository: siteboon/claudecodeui
Length of output: 4416
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Claude session synchronizer relevant sections ==="
sed -n '1,240p' server/modules/providers/list/claude/claude-session-synchronizer.provider.ts | cat -n
echo
echo "=== Claude provider relevant sections ==="
sed -n '1,160p' server/modules/providers/list/claude/claude.provider.ts | cat -n
echo
echo "=== provider registry ==="
sed -n '1,80p' server/modules/providers/provider.registry.ts | cat -nRepository: siteboon/claudecodeui
Length of output: 12684
Update MiniMax sync so it is not the only no-op provider.
sessionSynchronizerService.synchronizeSessions() calls MiniMaxProvider.sessionSynchronizer.synchronize(), so MiniMax transcript discovery will always return 0 unless MiniMax files are copied/shared through Claude artifacts and handled by ClaudeProvider.sessionSynchronizer. If MiniMax is an independent transcript source, wire its synchronizer to the Claude file indexer or implement MiniMax-specific scan logic.
🤖 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 `@server/modules/providers/list/minimax/minimax.provider.ts` around lines 106 -
114, Implement MiniMaxSessionSynchronizer.synchronize() and synchronizeFile() so
MiniMax transcripts are discovered rather than returning hardcoded no-op values.
Reuse the ClaudeProvider session synchronizer/file indexer when MiniMax
transcripts share Claude artifacts; otherwise add MiniMax-specific scanning,
ensuring synchronize() reports discovered sessions and synchronizeFile() returns
the synchronized file path.
| if (provider === 'minimax') { | ||
| return 'claude --version'; | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -eu
ast-grep outline src/components/provider-auth/view/ProviderLoginModal.tsx --items all
rg -n -C3 '\b(ProviderLoginModal|onOpenProviderLogin|customCommand)\b' src
fd -i 'minimax-auth.provider.ts' server/modules/providers/list \
-x sh -c 'echo "== $1 =="; sed -n "1,240p" "$1"' sh {}Repository: siteboon/claudecodeui
Length of output: 10816
🏁 Script executed:
#!/usr/bin/env bash
set -eu
echo "== ProviderLoginModal relevant section =="
sed -n '1,120p' src/components/provider-auth/view/ProviderLoginModal.tsx
echo
echo "== Provider auth references =="
rg -n -C4 "minimax|MiniMax|customCommand|handleProviderLoginOpen|setActiveLoginProvider|showLoginModal|setLoginProvider|onOpen" src/components provider-auth || true
echo
echo "== MiniMax provider implementation =="
fd -i 'minimax-.*provider.*\.(ts|js)$|minimax.*\.(ts|js)$' . \
-x sh -c 'echo "== $1 =="; sed -n "1,260p" "$1"' sh {}
echo
echo "== MiniMax config implementation references =="
fd -i 'minimax-config.*\.(ts|js)$' . \
-x sh -c 'echo "== $1 =="; sed -n "1,260p" "$1"' sh {}Repository: siteboon/claudecodeui
Length of output: 50378
🏁 Script executed:
#!/usr/bin/env bash
set -eu
echo "== miniMax provider files =="
fd -i 'minimax.*\.(ts|tsx|js)$' . \
-type f \
-print \
| sort | while read -r f; do
echo
echo "== $f =="
sed -n '1,260p' "$f"
done
echo
echo "== ProviderLoginModal customCommand call sites =="
rg -n -C6 "ProviderLoginModal|customCommand" src/components src/types src/hooks | sed -n '1,220p'Repository: siteboon/claudecodeui
Length of output: 9645
Use a real MiniMax setup action.
When customCommand is absent, this default login only prints claude --version and exits; MiniMax authentication is API-key endpoint/token based, so the MiniMax configuration flow cannot authenticate the provider this way. Replace it with the intended MiniMax credential/configuration flow or an API-key form.
🤖 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 `@src/components/provider-auth/view/ProviderLoginModal.tsx` around lines 44 -
46, Update the MiniMax branch in the provider command/configuration logic so its
absent-customCommand default performs the actual MiniMax credential setup or
presents the API-key form, rather than executing the diagnostic `claude
--version` command. Preserve customCommand handling for configured providers and
ensure the default flow stores or applies the MiniMax API endpoint and token
required for authentication.
| )} | ||
|
|
||
| {selectedCategory === 'permissions' && selectedAgent === 'claude' && ( | ||
| {selectedCategory === 'permissions' && (selectedAgent === 'claude' || selectedAgent === 'minimax') && ( |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Do not route MiniMax permissions through Claude state.
When selectedAgent === 'minimax', this branch still renders agent="claude" and reads/writes claudePermissions. Selecting MiniMax therefore edits Claude’s configuration and presents the wrong provider context. Add MiniMax-specific permission state/handlers and pass the selected provider, or keep MiniMax out of the permissions category until that contract exists.
🤖 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
`@src/components/settings/view/tabs/agents-settings/sections/AgentCategoryContentSection.tsx`
at line 32, Update the permissions branch in AgentCategoryContentSection so
MiniMax does not reuse Claude’s provider context: add MiniMax-specific
permission state and handlers, pass selectedAgent through to the permissions UI,
and read/write MiniMax permissions independently. If that contract is
unavailable, restrict the branch to Claude instead of rendering MiniMax with
Claude state.
Reason: Add MiniMax provider support with configured models and regional API endpoints.
Summary:
Checks:
ELECTRON_SKIP_BINARY_DOWNLOAD=1 npm cinpm run typecheckTSX_TSCONFIG_PATH=server/tsconfig.json node --import tsx --test server/modules/providers/tests/*.test.ts(47 passed)npm run lint(0 errors; existing warnings)npm run build(passed with existing build warnings)git diff --checkSummary by CodeRabbit