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
2 changes: 1 addition & 1 deletion restored-src/src/entrypoints/sdk/coreSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,7 @@ export const AccountInfoSchema = lazySchema(() =>
tokenSource: z.string().optional(),
apiKeySource: z.string().optional(),
apiProvider: z
.enum(['firstParty', 'bedrock', 'vertex', 'foundry'])
.enum(['firstParty', 'bedrock', 'vertex', 'foundry', 'minimax'])
.optional()
.describe(
'Active API backend. Anthropic OAuth login only applies when "firstParty"; for 3P providers the other fields are absent and auth is external (AWS creds, gcloud ADC, etc.).',
Expand Down
15 changes: 15 additions & 0 deletions restored-src/src/utils/model/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import type { APIProvider } from './providers.js'

export type ModelConfig = Record<APIProvider, ModelName>

export const MINIMAX_MODEL_IDS = ['MiniMax-M3', 'MiniMax-M2.7'] as const
export const MINIMAX_DEFAULT_MODEL = MINIMAX_MODEL_IDS[0]
export const MINIMAX_FAST_MODEL = MINIMAX_MODEL_IDS[1]

// @[MODEL LAUNCH]: Add a new CLAUDE_*_CONFIG constant here. Double check the correct model strings
// here since the pattern may change.

Expand All @@ -11,76 +15,87 @@ export const CLAUDE_3_7_SONNET_CONFIG = {
bedrock: 'us.anthropic.claude-3-7-sonnet-20250219-v1:0',
vertex: 'claude-3-7-sonnet@20250219',
foundry: 'claude-3-7-sonnet',
minimax: MINIMAX_DEFAULT_MODEL,
} as const satisfies ModelConfig

export const CLAUDE_3_5_V2_SONNET_CONFIG = {
firstParty: 'claude-3-5-sonnet-20241022',
bedrock: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
vertex: 'claude-3-5-sonnet-v2@20241022',
foundry: 'claude-3-5-sonnet',
minimax: MINIMAX_DEFAULT_MODEL,
} as const satisfies ModelConfig

export const CLAUDE_3_5_HAIKU_CONFIG = {
firstParty: 'claude-3-5-haiku-20241022',
bedrock: 'us.anthropic.claude-3-5-haiku-20241022-v1:0',
vertex: 'claude-3-5-haiku@20241022',
foundry: 'claude-3-5-haiku',
minimax: MINIMAX_FAST_MODEL,
} as const satisfies ModelConfig

export const CLAUDE_HAIKU_4_5_CONFIG = {
firstParty: 'claude-haiku-4-5-20251001',
bedrock: 'us.anthropic.claude-haiku-4-5-20251001-v1:0',
vertex: 'claude-haiku-4-5@20251001',
foundry: 'claude-haiku-4-5',
minimax: MINIMAX_FAST_MODEL,
} as const satisfies ModelConfig

export const CLAUDE_SONNET_4_CONFIG = {
firstParty: 'claude-sonnet-4-20250514',
bedrock: 'us.anthropic.claude-sonnet-4-20250514-v1:0',
vertex: 'claude-sonnet-4@20250514',
foundry: 'claude-sonnet-4',
minimax: MINIMAX_DEFAULT_MODEL,
} as const satisfies ModelConfig

export const CLAUDE_SONNET_4_5_CONFIG = {
firstParty: 'claude-sonnet-4-5-20250929',
bedrock: 'us.anthropic.claude-sonnet-4-5-20250929-v1:0',
vertex: 'claude-sonnet-4-5@20250929',
foundry: 'claude-sonnet-4-5',
minimax: MINIMAX_DEFAULT_MODEL,
} as const satisfies ModelConfig

export const CLAUDE_OPUS_4_CONFIG = {
firstParty: 'claude-opus-4-20250514',
bedrock: 'us.anthropic.claude-opus-4-20250514-v1:0',
vertex: 'claude-opus-4@20250514',
foundry: 'claude-opus-4',
minimax: MINIMAX_DEFAULT_MODEL,
} as const satisfies ModelConfig

export const CLAUDE_OPUS_4_1_CONFIG = {
firstParty: 'claude-opus-4-1-20250805',
bedrock: 'us.anthropic.claude-opus-4-1-20250805-v1:0',
vertex: 'claude-opus-4-1@20250805',
foundry: 'claude-opus-4-1',
minimax: MINIMAX_DEFAULT_MODEL,
} as const satisfies ModelConfig

export const CLAUDE_OPUS_4_5_CONFIG = {
firstParty: 'claude-opus-4-5-20251101',
bedrock: 'us.anthropic.claude-opus-4-5-20251101-v1:0',
vertex: 'claude-opus-4-5@20251101',
foundry: 'claude-opus-4-5',
minimax: MINIMAX_DEFAULT_MODEL,
} as const satisfies ModelConfig

export const CLAUDE_OPUS_4_6_CONFIG = {
firstParty: 'claude-opus-4-6',
bedrock: 'us.anthropic.claude-opus-4-6-v1',
vertex: 'claude-opus-4-6',
foundry: 'claude-opus-4-6',
minimax: MINIMAX_DEFAULT_MODEL,
} as const satisfies ModelConfig

export const CLAUDE_SONNET_4_6_CONFIG = {
firstParty: 'claude-sonnet-4-6',
bedrock: 'us.anthropic.claude-sonnet-4-6',
vertex: 'claude-sonnet-4-6',
foundry: 'claude-sonnet-4-6',
minimax: MINIMAX_DEFAULT_MODEL,
} as const satisfies ModelConfig

// @[MODEL LAUNCH]: Register the new config here.
Expand Down
3 changes: 3 additions & 0 deletions restored-src/src/utils/model/deprecation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const DEPRECATED_MODELS: Record<string, DeprecationEntry> = {
bedrock: 'January 15, 2026',
vertex: 'January 5, 2026',
foundry: 'January 5, 2026',
minimax: null,
},
},
'claude-3-7-sonnet': {
Expand All @@ -47,6 +48,7 @@ const DEPRECATED_MODELS: Record<string, DeprecationEntry> = {
bedrock: 'April 28, 2026',
vertex: 'May 11, 2026',
foundry: 'February 19, 2026',
minimax: null,
},
},
'claude-3-5-haiku': {
Expand All @@ -56,6 +58,7 @@ const DEPRECATED_MODELS: Record<string, DeprecationEntry> = {
bedrock: null,
vertex: null,
foundry: null,
minimax: null,
},
},
}
Expand Down
27 changes: 22 additions & 5 deletions restored-src/src/utils/model/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
} from '../context.js'
import { isEnvTruthy } from '../envUtils.js'
import { getModelStrings, resolveOverriddenModel } from './modelStrings.js'
import { MINIMAX_MODEL_IDS } from './configs.js'
import { formatModelPricing, getOpus46CostTier } from '../modelCost.js'
import { getSettings_DEPRECATED } from '../settings/settings.js'
import type { PermissionMode } from '../permissions/PermissionMode.js'
Expand All @@ -33,6 +34,13 @@ export type ModelShortName = string
export type ModelName = string
export type ModelSetting = ModelName | ModelAlias | null

function getMiniMaxModelDisplayName(model: ModelName): string | null {
const normalizedModel = model.toLowerCase()
return (
MINIMAX_MODEL_IDS.find(id => id.toLowerCase() === normalizedModel) ?? null
)
}

export function getSmallFastModel(): ModelName {
return process.env.ANTHROPIC_SMALL_FAST_MODEL || getDefaultHaikuModel()
}
Expand Down Expand Up @@ -347,6 +355,10 @@ export function renderModelSetting(setting: ModelName | ModelAlias): string {
* if the model is not recognized as a public model.
*/
export function getPublicModelDisplayName(model: ModelName): string | null {
const miniMaxModel = getMiniMaxModelDisplayName(model)
if (miniMaxModel) {
return miniMaxModel
}
switch (model) {
case getModelStrings().opus46:
return 'Opus 4.6'
Expand Down Expand Up @@ -416,13 +428,14 @@ export function renderModelName(model: ModelName): string {

/**
* Returns a safe author name for public display (e.g., in git commit trailers).
* Returns "Claude {ModelName}" for publicly known models, or "Claude ({model})"
* for unknown/internal models so the exact model name is preserved.
*
* @param model The full model name
* @returns "Claude {ModelName}" for public models, or "Claude ({model})" for non-public models
* Known external model IDs are returned unchanged. Other public models use the
* CLI author prefix, while unknown models preserve their exact identifier.
*/
export function getPublicModelName(model: ModelName): string {
const miniMaxModel = getMiniMaxModelDisplayName(model)
if (miniMaxModel) {
return miniMaxModel
}
const publicName = getPublicModelDisplayName(model)
if (publicName) {
return `Claude ${publicName}`
Expand Down Expand Up @@ -568,6 +581,10 @@ export function modelDisplayString(model: ModelSetting): string {

// @[MODEL LAUNCH]: Add a marketing name mapping for the new model below.
export function getMarketingNameForModel(modelId: string): string | undefined {
const miniMaxModel = getMiniMaxModelDisplayName(modelId)
if (miniMaxModel) {
return miniMaxModel
}
if (getAPIProvider() === 'foundry') {
// deployment ID is user-defined in Foundry, so it may have no relation to the actual model
return undefined
Expand Down
24 changes: 24 additions & 0 deletions restored-src/src/utils/model/modelOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
isTeamPremiumSubscriber,
} from '../auth.js'
import { getModelStrings } from './modelStrings.js'
import { MINIMAX_MODEL_IDS } from './configs.js'
import {
COST_TIER_3_15,
COST_HAIKU_35,
Expand Down Expand Up @@ -55,6 +56,18 @@ export function getDefaultOptionForUser(fastMode = false): ModelOption {
}
}

if (getAPIProvider() === 'minimax') {
const currentModel = renderDefaultModelSetting(
getDefaultMainLoopModelSetting(),
)
return {
value: null,
label: 'Default (recommended)',
description: `Use the default model (currently ${currentModel})`,
descriptionForModel: `Default model (currently ${currentModel})`,
}
}

// Subscribers
if (isClaudeAISubscriber()) {
return {
Expand Down Expand Up @@ -287,6 +300,17 @@ function getModelOptionsBase(fastMode = false): ModelOption[] {
]
}

if (getAPIProvider() === 'minimax') {
return [
getDefaultOptionForUser(fastMode),
...MINIMAX_MODEL_IDS.map(model => ({
value: model,
label: model,
description: model,
})),
]
}

if (isClaudeAISubscriber()) {
if (isMaxSubscriber() || isTeamPremiumSubscriber()) {
// Max and Team Premium users: Opus is default, show Sonnet as alternative
Expand Down
30 changes: 28 additions & 2 deletions restored-src/src/utils/model/providers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
import type { AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS } from '../../services/analytics/index.js'
import { isEnvTruthy } from '../envUtils.js'

export type APIProvider = 'firstParty' | 'bedrock' | 'vertex' | 'foundry'
export type APIProvider =
| 'firstParty'
| 'bedrock'
| 'vertex'
| 'foundry'
| 'minimax'

const MINIMAX_ANTHROPIC_BASE_URLS = new Set([
'https://api.minimax.io/anthropic',
'https://api.minimaxi.com/anthropic',
])

export function isMiniMaxAnthropicBaseUrl(): boolean {
const baseUrl = process.env.ANTHROPIC_BASE_URL
if (!baseUrl) {
return false
}
try {
const url = new URL(baseUrl)
const normalizedPath = url.pathname.replace(/\/+$/, '')
return MINIMAX_ANTHROPIC_BASE_URLS.has(`${url.origin}${normalizedPath}`)
} catch {
return false
}
}

export function getAPIProvider(): APIProvider {
return isEnvTruthy(process.env.CLAUDE_CODE_USE_BEDROCK)
Expand All @@ -10,7 +34,9 @@ export function getAPIProvider(): APIProvider {
? 'vertex'
: isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY)
? 'foundry'
: 'firstParty'
: isMiniMaxAnthropicBaseUrl()
? 'minimax'
: 'firstParty'
}

export function getAPIProviderForStatsig(): AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS {
Expand Down
11 changes: 10 additions & 1 deletion restored-src/src/utils/status.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ export function buildAPIProviderProperties(): Property[] {
const providerLabel = {
bedrock: 'AWS Bedrock',
vertex: 'Google Vertex AI',
foundry: 'Microsoft Foundry'
foundry: 'Microsoft Foundry',
minimax: 'MiniMax'
}[apiProvider];
properties.push({
label: 'API provider',
Expand All @@ -259,6 +260,14 @@ export function buildAPIProviderProperties(): Property[] {
value: anthropicBaseUrl
});
}
} else if (apiProvider === 'minimax') {
const miniMaxBaseUrl = process.env.ANTHROPIC_BASE_URL;
if (miniMaxBaseUrl) {
properties.push({
label: 'MiniMax base URL',
value: miniMaxBaseUrl
});
}
} else if (apiProvider === 'bedrock') {
const bedrockBaseUrl = process.env.BEDROCK_BASE_URL;
if (bedrockBaseUrl) {
Expand Down