diff --git a/.env.example b/.env.example index 44eb01b..50d02e0 100644 --- a/.env.example +++ b/.env.example @@ -36,7 +36,7 @@ LLM_PROVIDER= # Not needed for codex (uses ~/.codex/auth.json) LLM_API_KEY= # Optional override. Each provider has a sensible default: -# anthropic: claude-sonnet-4-6 | openai: gpt-5.4 | gemini: gemini-3.1-pro | codex: gpt-5.3-codex | openrouter: openrouter/auto | minimax: MiniMax-M2.5 +# anthropic: claude-sonnet-4-6 | openai: gpt-5.4 | gemini: gemini-3.1-pro | codex: gpt-5.3-codex | openrouter: openrouter/auto | minimax: MiniMax-M2.7 LLM_MODEL= # === Telegram Alerts (optional, requires LLM) === diff --git a/README.md b/README.md index 6bb7538..024f0fd 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,7 @@ Set `LLM_PROVIDER` to one of: `anthropic`, `openai`, `gemini`, `codex`, `openrou | `gemini` | `LLM_API_KEY` | gemini-3.1-pro | | `openrouter` | `LLM_API_KEY` | openrouter/auto | | `codex` | None (uses `~/.codex/auth.json`) | gpt-5.3-codex | -| `minimax` | `LLM_API_KEY` | MiniMax-M2.5 | +| `minimax` | `LLM_API_KEY` | MiniMax-M2.7 | For Codex, run `npx @openai/codex login` to authenticate via your ChatGPT subscription. @@ -280,7 +280,7 @@ crucix/ │ │ ├── gemini.mjs # Gemini │ │ ├── openrouter.mjs # OpenRouter (Unified API) │ │ ├── codex.mjs # Codex (ChatGPT subscription) -│ │ ├── minimax.mjs # MiniMax (M2.5, 204K context) +│ │ ├── minimax.mjs # MiniMax (M2.7, latest flagship model) │ │ ├── ideas.mjs # LLM-powered trade idea generation │ │ └── index.mjs # Factory: createLLMProvider() │ ├── delta/ # Change tracking between sweeps diff --git a/lib/llm/minimax.mjs b/lib/llm/minimax.mjs index 7c9160b..c474067 100644 --- a/lib/llm/minimax.mjs +++ b/lib/llm/minimax.mjs @@ -8,7 +8,7 @@ export class MiniMaxProvider extends LLMProvider { super(config); this.name = 'minimax'; this.apiKey = config.apiKey; - this.model = config.model || 'MiniMax-M2.5'; + this.model = config.model || 'MiniMax-M2.7'; } get isConfigured() { return !!this.apiKey; } diff --git a/test/llm-minimax-integration.test.mjs b/test/llm-minimax-integration.test.mjs index 08b0c7c..0c0449d 100644 --- a/test/llm-minimax-integration.test.mjs +++ b/test/llm-minimax-integration.test.mjs @@ -9,8 +9,8 @@ import { MiniMaxProvider } from '../lib/llm/minimax.mjs'; const API_KEY = process.env.MINIMAX_API_KEY; describe('MiniMax integration', { skip: !API_KEY && 'MINIMAX_API_KEY not set' }, () => { - it('should complete a prompt with MiniMax-M2.5', async () => { - const provider = new MiniMaxProvider({ apiKey: API_KEY, model: 'MiniMax-M2.5' }); + it('should complete a prompt with MiniMax-M2.7', async () => { + const provider = new MiniMaxProvider({ apiKey: API_KEY, model: 'MiniMax-M2.7' }); assert.equal(provider.isConfigured, true); const result = await provider.complete( diff --git a/test/llm-minimax.test.mjs b/test/llm-minimax.test.mjs index f2d3b7d..4eafe4b 100644 --- a/test/llm-minimax.test.mjs +++ b/test/llm-minimax.test.mjs @@ -12,13 +12,13 @@ describe('MiniMaxProvider', () => { it('should set defaults correctly', () => { const provider = new MiniMaxProvider({ apiKey: 'sk-test' }); assert.equal(provider.name, 'minimax'); - assert.equal(provider.model, 'MiniMax-M2.5'); + assert.equal(provider.model, 'MiniMax-M2.7'); assert.equal(provider.isConfigured, true); }); it('should accept custom model', () => { - const provider = new MiniMaxProvider({ apiKey: 'sk-test', model: 'MiniMax-M2.5-highspeed' }); - assert.equal(provider.model, 'MiniMax-M2.5-highspeed'); + const provider = new MiniMaxProvider({ apiKey: 'sk-test', model: 'MiniMax-M2.7-highspeed' }); + assert.equal(provider.model, 'MiniMax-M2.7-highspeed'); }); it('should report not configured without API key', () => { @@ -50,7 +50,7 @@ describe('MiniMaxProvider', () => { const mockResponse = { choices: [{ message: { content: 'Hello from MiniMax' } }], usage: { prompt_tokens: 10, completion_tokens: 5 }, - model: 'MiniMax-M2.5', + model: 'MiniMax-M2.7', }; const originalFetch = globalThis.fetch; globalThis.fetch = mock.fn(() => @@ -61,14 +61,14 @@ describe('MiniMaxProvider', () => { assert.equal(result.text, 'Hello from MiniMax'); assert.equal(result.usage.inputTokens, 10); assert.equal(result.usage.outputTokens, 5); - assert.equal(result.model, 'MiniMax-M2.5'); + assert.equal(result.model, 'MiniMax-M2.7'); } finally { globalThis.fetch = originalFetch; } }); it('should send correct request format', async () => { - const provider = new MiniMaxProvider({ apiKey: 'sk-test-key', model: 'MiniMax-M2.5' }); + const provider = new MiniMaxProvider({ apiKey: 'sk-test-key', model: 'MiniMax-M2.7' }); let capturedUrl, capturedOpts; const originalFetch = globalThis.fetch; globalThis.fetch = mock.fn((url, opts) => { @@ -79,7 +79,7 @@ describe('MiniMaxProvider', () => { json: () => Promise.resolve({ choices: [{ message: { content: 'ok' } }], usage: { prompt_tokens: 1, completion_tokens: 1 }, - model: 'MiniMax-M2.5', + model: 'MiniMax-M2.7', }), }); }); @@ -91,7 +91,7 @@ describe('MiniMaxProvider', () => { assert.equal(headers['Content-Type'], 'application/json'); assert.equal(headers['Authorization'], 'Bearer sk-test-key'); const body = JSON.parse(capturedOpts.body); - assert.equal(body.model, 'MiniMax-M2.5'); + assert.equal(body.model, 'MiniMax-M2.7'); assert.equal(body.max_tokens, 2048); assert.equal(body.messages[0].role, 'system'); assert.equal(body.messages[0].content, 'system prompt');