modelmix 4.5.24 → 4.5.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/MODELS.md CHANGED
@@ -352,4 +352,4 @@ All providers inherit from `MixCustom` base class which provides common function
352
352
  - Uses OpenAI-compatible API interface
353
353
  - Requires `MINIMAX_API_KEY` environment variable
354
354
  - Inherits all OpenAI functionality including tool calling
355
- - Available models: `MiniMax-M2.5`, `MiniMax-M2.7`
355
+ - Available models: `MiniMax-M2.5`, `MiniMax-M2.7`, `MiniMax-M3`
package/README.md CHANGED
@@ -161,7 +161,9 @@ Here's a comprehensive list of available methods:
161
161
  | `grok41[think]()` | Grok | grok-4-1-fast | [\$0.20 / \$0.50][6] |
162
162
  | `qwen36plus()` | Fireworks/Together | qwen3p6-plus / Qwen3.6-Plus | [\$0.50 / \$3.00][10] |
163
163
  | `deepseekV4Pro()` | Fireworks | models/deepseek-v4-pro | [\$1.74 / \$3.48][10] |
164
+ | `GLM52()` | Together | zai-org/GLM-5.2 | [\$1.40 / \$4.40][7] |
164
165
  | `GLM51()` | Fireworks | models/glm-5p1 | [\$1.05 / \$3.50][10] |
166
+ | `minimaxM3()` | MiniMax | MiniMax-M3 | [\$0.30 / \$1.20][9] |
165
167
  | `minimaxM27()` | MiniMax | MiniMax-M2.7 | [\$0.30 / \$1.20][9] |
166
168
  | `sonar()` | Perplexity | sonar | [\$1.00 / \$1.00][4] |
167
169
  | `sonarPro()` | Perplexity | sonar-pro | [\$3.00 / \$15.00][4] |
package/demo/images.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ModelMix } from '../index.js';
2
2
  try { process.loadEnvFile(); } catch {}
3
3
 
4
- const model = ModelMix.new({ config: { max_history: 2, debug: 2 } }).scout()
4
+ const model = ModelMix.new({ config: { max_history: 2, debug: 2 } }).grok43()
5
5
  // model.addImageFromUrl('https://pbs.twimg.com/media/F6-GsjraAAADDGy?format=jpg');
6
6
  model.addImage('./img.png');
7
7
  model.addText('in one word, which is the main color of the image?');
package/demo/json.js CHANGED
@@ -4,7 +4,6 @@ try { process.loadEnvFile(); } catch {}
4
4
  const model = await ModelMix.new({ options: { max_tokens: 10000 }, config: { debug: 3 } })
5
5
  .gpt54nano()
6
6
  // .gptOss()
7
- // .scout({ config: { temperature: 0 } })
8
7
  // .o4mini()
9
8
  // .gpt45()
10
9
  // .gemini25flash()
package/index.js CHANGED
@@ -87,6 +87,7 @@ const MODEL_PRICING = {
87
87
  'deepseek-ai/DeepSeek-V4-Pro': [2.10, 4.40],
88
88
  'accounts/fireworks/models/glm-4p7': [0.55, 2.19],
89
89
  'accounts/fireworks/models/glm-5p1': [1.05, 3.50],
90
+ 'zai-org/GLM-5.2': [1.40, 4.40],
90
91
  'accounts/fireworks/models/kimi-k2p5': [0.50, 2.80],
91
92
  'accounts/fireworks/models/qwen3p6-plus': [0.50, 3.00],
92
93
  'Qwen/Qwen3.6-Plus': [0.50, 3.00],
@@ -94,19 +95,14 @@ const MODEL_PRICING = {
94
95
  // MiniMax
95
96
  'MiniMax-M2.5': [0.30, 1.20],
96
97
  'MiniMax-M2.7': [0.30, 1.20],
98
+ 'MiniMax-M3': [0.30, 1.20],
97
99
  'fireworks/minimax-m2p5': [0.30, 1.20],
98
100
  'minimax/minimax-m2.7': [0.30, 1.20],
101
+ 'minimax/minimax-m3': [0.30, 1.20],
102
+ 'MiniMaxAI/MiniMax-M3': [0.30, 1.20],
99
103
  // Perplexity
100
104
  'sonar': [1.00, 1.00],
101
105
  'sonar-pro': [3.00, 15.00],
102
- // Scout (Groq/Together/Cerebras)
103
- 'meta-llama/llama-4-scout-17b-16e-instruct': [0.11, 0.34],
104
- 'meta-llama/Llama-4-Scout-17B-16E-Instruct': [0.11, 0.34],
105
- 'llama-4-scout-17b-16e-instruct': [0.11, 0.34],
106
- // Maverick (Groq/Together/Lambda)
107
- 'meta-llama/llama-4-maverick-17b-128e-instruct': [0.20, 0.60],
108
- 'meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8': [0.20, 0.60],
109
- 'llama-4-maverick-17b-128e-instruct-fp8': [0.20, 0.60],
110
106
  // Hermes3 (Lambda/OpenRouter)
111
107
  'Hermes-3-Llama-3.1-405B-FP8': [0.80, 0.80],
112
108
  'nousresearch/hermes-3-llama-3.1-405b:free': [0, 0],
@@ -468,20 +464,6 @@ class ModelMix {
468
464
  return this;
469
465
  }
470
466
 
471
- scout({ options = {}, config = {}, mix = {} } = {}) {
472
- mix = { ...this.mix, ...mix };
473
- if (mix.groq) this.attach('meta-llama/llama-4-scout-17b-16e-instruct', new MixGroq({ options, config }));
474
- if (mix.together) this.attach('meta-llama/Llama-4-Scout-17B-16E-Instruct', new MixTogether({ options, config }));
475
- if (mix.cerebras) this.attach('llama-4-scout-17b-16e-instruct', new MixCerebras({ options, config }));
476
- return this;
477
- }
478
- maverick({ options = {}, config = {}, mix = {} } = {}) {
479
- mix = { ...this.mix, ...mix };
480
- if (mix.together) this.attach('meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8', new MixTogether({ options, config }));
481
- if (mix.lambda) this.attach('llama-4-maverick-17b-128e-instruct-fp8', new MixLambda({ options, config }));
482
- return this;
483
- }
484
-
485
467
  deepseekR1({ options = {}, config = {}, mix = {} } = {}) {
486
468
  mix = { ...this.mix, ...mix };
487
469
  if (mix.groq) this.attach('deepseek-r1-distill-llama-70b', new MixGroq({ options, config }));
@@ -506,6 +488,12 @@ class ModelMix {
506
488
  return this;
507
489
  }
508
490
 
491
+ kimiK27Code({ options = {}, config = {}, mix = { together: true } } = {}) {
492
+ mix = { ...this.mix, ...mix };
493
+ if (mix.together) this.attach('moonshotai/Kimi-K2.7-Code', new MixTogether({ options, config }));
494
+ return this;
495
+ }
496
+
509
497
  kimiK25think({ options = {}, config = {}, mix = { together: true } } = {}) {
510
498
  mix = { ...this.mix, ...mix };
511
499
  if (mix.together) this.attach('moonshotai/Kimi-K2.5', new MixTogether({ options, config }));
@@ -535,17 +523,25 @@ class ModelMix {
535
523
  return this;
536
524
  }
537
525
 
526
+ minimaxM3({ options = {}, config = {}, mix = { minimax: true, openrouter: false } } = {}) {
527
+ mix = { ...this.mix, ...mix };
528
+ if (mix.minimax) this.attach('MiniMax-M3', new MixMiniMax({ options, config }));
529
+ if (mix.openrouter) this.attach('minimax/minimax-m3', new MixOpenRouter({ options, config }));
530
+ if (mix.together) this.attach('MiniMaxAI/MiniMax-M3', new MixTogether({ options, config }));
531
+ return this;
532
+ }
533
+
538
534
  mimo25({ options = {}, config = {}, mix = { openrouter: true } } = {}) {
539
535
  mix = { ...this.mix, ...mix };
540
- if (mix.openrouter) this.attach('xiaomi/mimo-v2.5', new MixOpenRouter({ options, config }));
541
536
  if (mix.mimo) this.attach('mimo-v2.5', new MixMiMo({ options, config }));
537
+ if (mix.openrouter) this.attach('xiaomi/mimo-v2.5', new MixOpenRouter({ options, config }));
542
538
  return this;
543
539
  }
544
540
 
545
541
  mimo25pro({ options = {}, config = {}, mix = { openrouter: true } } = {}) {
546
542
  mix = { ...this.mix, ...mix };
547
- if (mix.openrouter) this.attach('xiaomi/mimo-v2.5-pro', new MixOpenRouter({ options, config }));
548
543
  if (mix.mimo) this.attach('mimo-v2.5-pro', new MixMiMo({ options, config }));
544
+ if (mix.openrouter) this.attach('xiaomi/mimo-v2.5-pro', new MixOpenRouter({ options, config }));
549
545
  return this;
550
546
  }
551
547
 
@@ -573,6 +569,12 @@ class ModelMix {
573
569
  return this;
574
570
  }
575
571
 
572
+ GLM52({ options = {}, config = {}, mix = { together: true } } = {}) {
573
+ mix = { ...this.mix, ...mix };
574
+ if (mix.together) this.attach('zai-org/GLM-5.2', new MixTogether({ options, config }));
575
+ return this;
576
+ }
577
+
576
578
  GLM5({ options = {}, config = {}, mix = { fireworks: true } } = {}) {
577
579
  mix = { ...this.mix, ...mix };
578
580
  if (mix.fireworks) this.attach('fireworks/glm-5', new MixFireworks({ options, config }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "modelmix",
3
- "version": "4.5.24",
3
+ "version": "4.5.26",
4
4
  "description": "🧬 Reliable interface with automatic fallback for AI LLMs.",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -109,14 +109,11 @@ Thinking variants: append `think` — e.g. `opus46think()` `sonnet46think()` `so
109
109
  ### Perplexity
110
110
  `sonar()` `sonarPro()`
111
111
 
112
- ### Groq
113
- `scout()` `maverick()`
114
-
115
112
  ### Together
116
- `qwen36plus()` `kimiK25think()` `gptOss()`
113
+ `qwen36plus()` `GLM52()` `kimiK25think()` `gptOss()`
117
114
 
118
115
  ### MiniMax
119
- `minimaxM25()` `minimaxM27()`
116
+ `minimaxM25()` `minimaxM27()` `minimaxM3()`
120
117
 
121
118
  ### Fireworks
122
119
  `deepseekV32()` `GLM5()` `GLM47()`
@@ -128,7 +125,7 @@ Thinking variants: append `think` — e.g. `opus46think()` `sonnet46think()` `so
128
125
  `GLM45()`
129
126
 
130
127
  ### Multi-provider (auto-fallback across free/paid tiers)
131
- `deepseekR1()` `hermes3()` `scout()` `maverick()` `kimiK25think()` `GLM47()`
128
+ `deepseekR1()` `hermes3()` `kimiK25think()` `GLM47()`
132
129
 
133
130
  ### Local
134
131
  `lmstudio()` — for LM Studio local models
@@ -0,0 +1,12 @@
1
+ const { expect } = require('chai');
2
+ const { ModelMix } = require('../index.js');
3
+
4
+ describe('GLM Model Registration Tests', () => {
5
+ it('should register Together GLM 5.2 by default', () => {
6
+ const model = ModelMix.new();
7
+ model.GLM52();
8
+
9
+ expect(model.models).to.have.length(1);
10
+ expect(model.models[0].key).to.equal('zai-org/GLM-5.2');
11
+ });
12
+ });
@@ -0,0 +1,13 @@
1
+ const { expect } = require('chai');
2
+ const { ModelMix, MixTogether } = require('../index.js');
3
+
4
+ describe('Kimi Model Registration Tests', () => {
5
+ it('should register Together Kimi K2.7 Code by default', () => {
6
+ const model = ModelMix.new();
7
+ model.kimiK27Code();
8
+
9
+ expect(model.models).to.have.length(1);
10
+ expect(model.models[0].key).to.equal('moonshotai/Kimi-K2.7-Code');
11
+ expect(model.models[0].provider).to.be.instanceOf(MixTogether);
12
+ });
13
+ });
package/test/live.mcp.js CHANGED
@@ -254,46 +254,6 @@ describe('Live MCP Integration Tests', function () {
254
254
  expect(response).to.match(/[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i);
255
255
  });
256
256
 
257
- it('should use MCP tools with Scout model', async function () {
258
- const model = ModelMix.new(setup).scout();
259
-
260
- // Add text processing tool
261
- model.addTool({
262
- name: "text_analysis",
263
- description: "Analyze text and provide statistics",
264
- inputSchema: {
265
- type: "object",
266
- properties: {
267
- text: {
268
- type: "string",
269
- description: "Text to analyze"
270
- }
271
- },
272
- required: ["text"]
273
- }
274
- }, async ({ text }) => {
275
- const words = text.split(/\s+/).filter(word => word.length > 0);
276
- const chars = text.length;
277
- const sentences = text.split(/[.!?]+/).filter(s => s.trim().length > 0).length;
278
-
279
- return `Text Analysis:
280
- - Characters: ${chars}
281
- - Words: ${words.length}
282
- - Sentences: ${sentences}
283
- - Average word length: ${(chars / words.length).toFixed(1)} characters`;
284
- });
285
-
286
- model.setSystem('You are a text analysis assistant. Use the text_analysis tool to analyze text.');
287
- model.addText('Analyze this text: "Hello world! This is a test sentence for analysis. How many words are there?"');
288
-
289
- const response = await model.message();
290
- console.log(`Scout with MCP tools: ${response}`);
291
-
292
- expect(response).to.be.a('string');
293
- expect(response).to.include('Characters:');
294
- expect(response).to.include('Words:');
295
- });
296
-
297
257
  it('should use MCP tools with GPT-5 Mini', async function () {
298
258
  const model = ModelMix.new(setup).gpt5mini();
299
259
 
package/test/live.test.js CHANGED
@@ -31,7 +31,7 @@ describe('Live Integration Tests', function () {
31
31
 
32
32
  describe('Image Processing', function () {
33
33
 
34
- it('should process images with OpenAI GPT-5nano', async function () {
34
+ it('should process images with OpenAI GPT-5 Nano', async function () {
35
35
  const model = ModelMix.new(setup).gpt5nano();
36
36
 
37
37
  model.addImageFromUrl(blueSquareBase64)
@@ -180,18 +180,6 @@ describe('Live Integration Tests', function () {
180
180
 
181
181
  describe('Additional Model Tests', function () {
182
182
 
183
- it('should work with Scout model', async function () {
184
- const model = ModelMix.new(setup).scout();
185
-
186
- model.addText('Say "scout test successful" and nothing else.');
187
-
188
- const response = await model.message();
189
- console.log(`Scout response: ${response}`);
190
-
191
- expect(response).to.be.a('string');
192
- expect(response.toLowerCase()).to.include('scout test successful');
193
- });
194
-
195
183
  it('should work with GPT-OSS model', async function () {
196
184
  const model = ModelMix.new(setup).gptOss();
197
185
 
@@ -240,26 +228,6 @@ describe('Live Integration Tests', function () {
240
228
 
241
229
  describe('Image Processing with JSON Output', function () {
242
230
 
243
- it('should process images and return JSON with Scout', async function () {
244
- const model = ModelMix.new(setup).scout();
245
- model.addImageFromUrl(blueSquareBase64)
246
- .addText('Analyze this image and provide details in JSON format.');
247
-
248
- const result = await model.json({
249
- color: "string",
250
- shape: "string",
251
- description: "string"
252
- });
253
-
254
- console.log(`Scout image JSON result:`, result);
255
-
256
- expect(result).to.be.an('object');
257
- expect(result).to.have.property('color');
258
- expect(result).to.have.property('shape');
259
- expect(result).to.have.property('description');
260
- expect(result.color).to.be.a('string').and.not.empty;
261
- });
262
-
263
231
  it('should process images and return JSON with Grok 4.3', async function () {
264
232
  const model = ModelMix.new(setup).grok43();
265
233
 
@@ -285,28 +253,6 @@ describe('Live Integration Tests', function () {
285
253
 
286
254
  describe('JSON Structured Output for New Models', function () {
287
255
 
288
- it('should return structured JSON with Scout', async function () {
289
- const model = ModelMix.new(setup).scout();
290
-
291
- model.addText('Generate information about a fictional animal.');
292
-
293
- const result = await model.json({
294
- name: "Dragon",
295
- type: "Mythical",
296
- abilities: ["Fire breathing", "Flight"],
297
- habitat: "Mountains"
298
- });
299
-
300
- console.log(`Scout JSON result:`, result);
301
-
302
- expect(result).to.be.an('object');
303
- expect(result).to.have.property('name');
304
- expect(result).to.have.property('type');
305
- expect(result).to.have.property('abilities');
306
- expect(result).to.have.property('habitat');
307
- expect(result.abilities).to.be.an('array');
308
- });
309
-
310
256
  it('should return structured JSON with KimiK25 Thinking', async function () {
311
257
  const model = ModelMix.new(setup).kimiK25think();
312
258