diff --git a/src-tauri/src/commands/hermes_providers.rs b/src-tauri/src/commands/hermes_providers.rs index 3bbbfc32..f22c7dcb 100644 --- a/src-tauri/src/commands/hermes_providers.rs +++ b/src-tauri/src/commands/hermes_providers.rs @@ -221,7 +221,7 @@ const P_MINIMAX: HermesProvider = HermesProvider { id: "minimax", name: "MiniMax (International)", auth_type: AUTH_API_KEY, - base_url: "https://api.minimax.io/anthropic/v1", + base_url: "https://api.minimax.io/anthropic", base_url_env_var: "MINIMAX_BASE_URL", api_key_env_vars: &["MINIMAX_API_KEY"], transport: TRANSPORT_ANTHROPIC, @@ -235,7 +235,7 @@ const P_MINIMAX_CN: HermesProvider = HermesProvider { id: "minimax-cn", name: "MiniMax (China)", auth_type: AUTH_API_KEY, - base_url: "https://api.minimaxi.com/v1", + base_url: "https://api.minimaxi.com/anthropic", base_url_env_var: "MINIMAX_CN_BASE_URL", api_key_env_vars: &["MINIMAX_CN_API_KEY"], transport: TRANSPORT_ANTHROPIC, diff --git a/src/lib/model-presets.js b/src/lib/model-presets.js index a983e016..679c0586 100644 --- a/src/lib/model-presets.js +++ b/src/lib/model-presets.js @@ -52,7 +52,7 @@ export const PROVIDER_PRESETS = [ { key: 'volcengine', label: '火山引擎', baseUrl: 'https://ark.cn-beijing.volces.com/api/v3', api: 'openai-completions', site: 'https://volcengine.com/L/Ph1OP5I3_GY', desc: '字节跳动旗下云平台,支持豆包等模型' }, { key: 'aliyun', label: '阿里云百炼', baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1', api: 'openai-completions', site: 'https://www.aliyun.com/benefit/ai/aistar?userCode=keahn2zr&clubBiz=subTask..12435175..10263..', desc: '阿里云 AI 大模型平台,支持通义千问全系列' }, { key: 'zhipu', label: '智谱 AI', baseUrl: 'https://open.bigmodel.cn/api/paas/v4', api: 'openai-completions', site: 'https://www.bigmodel.cn/glm-coding?ic=3F6F9XYKTS', desc: '国产大模型领军企业,支持 GLM-4 全系列' }, - { key: 'minimax', label: 'MiniMax', baseUrl: 'https://api.minimax.io/v1', api: 'openai-completions', site: 'https://platform.minimaxi.com/user-center/basic-information/interface-key', desc: '国产多模态大模型,支持 MiniMax-M3 / M2.7 系列' }, + { key: 'minimax', label: 'MiniMax', baseUrl: 'https://api.minimax.io/v1', api: 'openai-completions', site: 'https://platform.minimax.io/docs/api-reference/api-overview', desc: '国产多模态大模型,支持 MiniMax-M3 / M2.7 系列' }, { key: 'moonshot', label: 'Moonshot / Kimi', baseUrl: 'https://api.moonshot.ai/v1', api: 'openai-completions', site: 'https://platform.moonshot.ai/console/api-keys', desc: 'Kimi 大模型平台,支持超长上下文' }, { key: 'openai', label: 'OpenAI 官方', baseUrl: 'https://api.openai.com/v1', api: 'openai-completions', site: 'https://platform.openai.com/api-keys' }, { key: 'anthropic', label: 'Anthropic 官方', baseUrl: 'https://api.anthropic.com/v1', api: 'anthropic-messages', site: 'https://console.anthropic.com/settings/keys' }, @@ -107,8 +107,8 @@ export const MODEL_PRESETS = { { id: 'gemini-2.5-flash', name: 'Gemini 2.5 Flash', contextWindow: 1000000 }, ], minimax: [ - { id: 'MiniMax-M3', name: 'MiniMax M3', contextWindow: 524288 }, - { id: 'MiniMax-M2.7', name: 'MiniMax M2.7', contextWindow: 1000000 }, + { id: 'MiniMax-M3', name: 'MiniMax M3', contextWindow: 1000000, reasoning: true, input: ['text', 'image', 'video'], cost: { input: 0.6, output: 2.4, cacheRead: 0.12 } }, + { id: 'MiniMax-M2.7', name: 'MiniMax M2.7', contextWindow: 204800, reasoning: true, input: ['text'], cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0.375 } }, { id: 'MiniMax-M2.7-highspeed', name: 'MiniMax M2.7 Highspeed', contextWindow: 1000000 }, ], moonshot: [ diff --git a/tests/minimax-provider-endpoints.test.js b/tests/minimax-provider-endpoints.test.js new file mode 100644 index 00000000..d45a0b13 --- /dev/null +++ b/tests/minimax-provider-endpoints.test.js @@ -0,0 +1,9 @@ +import test from 'node:test' +import assert from 'node:assert/strict' +import { readFile } from 'node:fs/promises' + +test('Hermes MiniMax providers use the regional Anthropic endpoints', async () => { + const source = await readFile(new URL('../src-tauri/src/commands/hermes_providers.rs', import.meta.url), 'utf8') + assert.match(source, /id: "minimax",[\s\S]*?base_url: "https:\/\/api\.minimax\.io\/anthropic"/) + assert.match(source, /id: "minimax-cn",[\s\S]*?base_url: "https:\/\/api\.minimaxi\.com\/anthropic"/) +}) diff --git a/tests/model-presets.test.js b/tests/model-presets.test.js index 3702ccfc..6b414c86 100644 --- a/tests/model-presets.test.js +++ b/tests/model-presets.test.js @@ -50,7 +50,7 @@ test('MiniMax provider preset uses correct API base URL', () => { test('MiniMax provider preset has site and description', () => { const minimax = PROVIDER_PRESETS.find(p => p.key === 'minimax') - assert.ok(minimax.site, 'MiniMax should have a site URL') + assert.equal(minimax.site, 'https://platform.minimax.io/docs/api-reference/api-overview') assert.ok(minimax.desc, 'MiniMax should have a description') }) @@ -99,17 +99,15 @@ test('MiniMax model presets have required fields', () => { } }) -test('MiniMax M2.7 models have 1M context window', () => { +test('MiniMax models use current context windows and metadata', () => { const m27 = MODEL_PRESETS.minimax.find(m => m.id === 'MiniMax-M2.7') - assert.equal(m27.contextWindow, 1000000) - const m27hs = MODEL_PRESETS.minimax.find(m => m.id === 'MiniMax-M2.7-highspeed') - assert.equal(m27hs.contextWindow, 1000000) -}) - -test('MiniMax M3 has 524K context window', () => { + assert.equal(m27.contextWindow, 204800) + assert.deepEqual(m27.input, ['text']) + assert.deepEqual(m27.cost, { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0.375 }) const m3 = MODEL_PRESETS.minimax.find(m => m.id === 'MiniMax-M3') - assert.ok(m3, 'should include MiniMax-M3') - assert.equal(m3.contextWindow, 524288) + assert.equal(m3.contextWindow, 1000000) + assert.deepEqual(m3.input, ['text', 'image', 'video']) + assert.deepEqual(m3.cost, { input: 0.6, output: 2.4, cacheRead: 0.12 }) }) test('all model preset groups have valid structure', () => {