modelmix 5.1.4 → 5.1.6

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/README.md CHANGED
@@ -151,7 +151,7 @@ ModelMix provides convenient shorthand methods for quickly accessing different A
151
151
  | `gpt51()` | OpenAI | gpt-5.1 | [\$1.25][1] | [\$10.00][1] |
152
152
  | `gpt5mini()` | OpenAI | gpt-5-mini | [\$0.25][1] | [\$2.00][1] |
153
153
  | `gpt5nano()` | OpenAI | gpt-5-nano | [\$0.05][1] | [\$0.40][1] |
154
- | `gptOss()` | Together | gpt-oss-120B | [\$0.15][7] | [\$0.60][7] |
154
+ | `gptOss()` | Cerebras/Groq/OpenRouter | gpt-oss-120B | [\$0.15][7] | [\$0.60][7] |
155
155
  | `fable5()` | Anthropic | claude-fable-5 | [\$10.00][2] | [\$50.00][2] |
156
156
  | `opus5()` | Anthropic | claude-opus-5 | [\$5.00][2] | [\$25.00][2] |
157
157
  | `opus48()` | Anthropic | claude-opus-4-8 | [\$5.00][2] | [\$25.00][2] |
@@ -171,8 +171,9 @@ ModelMix provides convenient shorthand methods for quickly accessing different A
171
171
  | `grok43()` | Grok | grok-4.3 | [\$1.25][6] | [\$2.50][6] |
172
172
  | `grok420multiAgent()` | Grok | grok-4.20-multi-agent-0309 | [\$1.25][6] | [\$2.50][6] |
173
173
  | `grok420()` | Grok | grok-4.20-0309 (†) | [\$1.25][6] | [\$2.50][6] |
174
+ | `museGlimmer30b()` | Fireworks | models/muse-glimmer-30b | [\$0.35][17] | [\$1.50][17] |
174
175
  | `qwen35397b()` | OpenRouter | qwen/qwen3.5-397b-a17b | [\$0.385][14] | [\$2.45][14] |
175
- | `qwen36plus()` | Fireworks | qwen3p6-plus | [\$0.50][10] | [\$3.00][10] |
176
+ | `qwen36plus()` | OpenRouter | qwen/qwen3.6-plus | [\$0.325][18] | [\$1.95][18] |
176
177
  | `qwen37plus()` | Fireworks | models/qwen3p7-plus | [\$0.40][10] | [\$1.60][10] |
177
178
  | `qwen38max()` | Fireworks | qwen3p8-2p4t-a95b | [\$2.00][10] | [\$6.00][10] |
178
179
  | `qwen3827b()` | OpenRouter | qwen/qwen3.8-27b | [\$0.45][15] | [\$3.20][15] |
@@ -180,7 +181,6 @@ ModelMix provides convenient shorthand methods for quickly accessing different A
180
181
  | `deepseekV4Pro()` | Fireworks | models/deepseek-v4-pro-0813 | [\$1.32][12] | [\$3.96][12] |
181
182
  | `GLM53()` | OpenRouter | z-ai/glm-5.3 | [\$1.40][16] | [\$4.40][16] |
182
183
  | `GLM52()` | Together | zai-org/GLM-5.2 | [\$1.40][7] | [\$4.40][7] |
183
- | `GLM51()` | Fireworks | models/glm-5p1 | [\$1.05][10] | [\$3.50][10] |
184
184
  | `minimaxM3()` | MiniMax | MiniMax-M3 | [\$0.30][9] | [\$1.20][9] |
185
185
  | `minimaxM27()` | MiniMax | MiniMax-M2.7 | [\$0.30][9] | [\$1.20][9] |
186
186
  | `sonar()` | Perplexity | sonar | [\$1.00][4] | [\$1.00][4] |
@@ -189,11 +189,16 @@ ModelMix provides convenient shorthand methods for quickly accessing different A
189
189
  | `hermes4405b()` | OpenRouter | nousresearch/hermes-4-405b | [\$1.00][13] | [\$3.00][13] |
190
190
  | `hermes3()` | Lambda | Hermes-3-Llama-3.1-405B-FP8 | [\$0.80][8] | [\$0.80][8] |
191
191
  | `kimiK3()` | Moonshot | kimi-k3 | [\$3.00][11] | [\$15.00][11] |
192
+ | `kimiK27Code()` | Together | Kimi-K2.7-Code | [\$0.95][7] | [\$4.00][7] |
192
193
  | `kimiK25()` | Together | Kimi-K2.5 | [\$0.50][7] | [\$2.80][7] |
193
194
  | `kimiK26()` | Fireworks | models/kimi-k2p6 | [\$0.95][10] | [\$4.00][10] |
194
195
 
195
196
  Gemini 3.7 Flash and 3.6 Flash use Google's introductory standard pricing through December 31, 2026; standard rates double on January 1, 2027.
196
197
 
198
+ `museGlimmer30b()` uses Fireworks first and OpenRouter as its default fallback. NVIDIA NIM and Together are also available through `mix.nvidia` and `mix.together`; disable either default provider with `mix.fireworks: false` or `mix.openrouter: false`.
199
+
200
+ The multi-provider shortcuts also expose the current catalog alternatives: `gptOss()` supports NVIDIA and Fireworks; `qwen37plus()` supports Together; `kimiK27Code()` supports Fireworks and OpenRouter; `kimiK3()` supports Fireworks, OpenRouter, and Together; `GLM52()` supports Fireworks and OpenRouter; and both MiniMax shortcuts support Fireworks. `minimaxM27()` keeps every enabled provider in its fallback chain. `qwen36plus()` now defaults to OpenRouter because Fireworks retired its serverless deployment; Fireworks remains available explicitly for private or on-demand deployments.
201
+
197
202
  [1]: https://platform.openai.com/docs/pricing "Pricing | OpenAI"
198
203
  [2]: https://docs.anthropic.com/en/docs/about-claude/pricing "Pricing - Anthropic"
199
204
  [3]: https://ai.google.dev/gemini-api/docs/pricing "Google AI for Developers"
@@ -210,6 +215,8 @@ Gemini 3.7 Flash and 3.6 Flash use Google's introductory standard pricing throug
210
215
  [14]: https://openrouter.ai/qwen/qwen3.5-397b-a17b "Qwen3.5 397B A17B on OpenRouter"
211
216
  [15]: https://openrouter.ai/qwen/qwen3.8-27b "Qwen3.8 27B on OpenRouter"
212
217
  [16]: https://openrouter.ai/z-ai/glm-5.3 "GLM 5.3 on OpenRouter"
218
+ [17]: https://fireworks.ai/models/fireworks/muse-glimmer-30b "Muse Glimmer 30B on Fireworks"
219
+ [18]: https://openrouter.ai/qwen/qwen3.6-plus "Qwen 3.6 Plus on OpenRouter"
213
220
 
214
221
  Each method accepts optional `options`, `config`, and (for multi-provider methods) `mix` parameters to customize behavior.
215
222
 
package/demo/custom.js CHANGED
@@ -50,8 +50,8 @@ class MixTogether extends MixCustom {
50
50
  }
51
51
  }
52
52
 
53
- mmix.attach('Qwen/Qwen3-235B-A22B-fp8-tput', new MixTogether());
53
+ mmix.attach('Qwen/Qwen3.6-Plus', new MixTogether());
54
54
 
55
55
  let r = mmix.addText('hi there');
56
56
  r = await r.addText('do you like cats?').message();
57
- console.log(r);
57
+ console.log(r);
package/demo/short.js CHANGED
@@ -17,8 +17,9 @@ const mmix = await ModelMix.new(setup)
17
17
  .qwen35397b() // (fallback 5) OpenRouter qwen/qwen3.5-397b-a17b
18
18
  .qwen3827b() // (fallback 6) OpenRouter qwen/qwen3.8-27b
19
19
  .GLM53() // (fallback 7) OpenRouter z-ai/glm-5.3
20
- .hermes470b() // (fallback 8) OpenRouter nousresearch/hermes-4-70b
21
- .hermes4405b() // (fallback 9) OpenRouter nousresearch/hermes-4-405b
20
+ .museGlimmer30b({ mix: { fireworks: false, openrouter: true } }) // (fallback 8) OpenRouter meta/muse-glimmer-30b
21
+ .hermes470b() // (fallback 9) OpenRouter nousresearch/hermes-4-70b
22
+ .hermes4405b() // (fallback 10) OpenRouter nousresearch/hermes-4-405b
22
23
  .addText("What's your name?");
23
24
 
24
25
  console.log(await mmix.message());
package/effort.js CHANGED
@@ -45,6 +45,9 @@ const OPENAI_MODEL_LEVELS = {
45
45
  'gpt-5.6-sol': ['none', 'low', 'medium', 'high', 'xhigh', 'max'],
46
46
  'gpt-5.6-terra': ['none', 'low', 'medium', 'high', 'xhigh', 'max'],
47
47
  'gpt-5.6-luna': ['none', 'low', 'medium', 'high', 'xhigh', 'max'],
48
+ 'meta/muse-glimmer-30b': ['low', 'medium', 'high'],
49
+ 'accounts/fireworks/models/muse-glimmer-30b': ['low', 'medium', 'high', 'xhigh'],
50
+ 'meta-models/Muse-Glimmer-30B': ['low', 'medium', 'high', 'xhigh'],
48
51
  'accounts/fireworks/models/qwen3p8-2p4t-a95b': ['none', 'low', 'medium', 'high'],
49
52
  'qwen/qwen3.8-27b': ['low', 'medium', 'xhigh'],
50
53
  'z-ai/glm-5.3': ['low', 'high', 'max'],
@@ -55,6 +58,14 @@ const OPENAI_MODEL_LEVELS = {
55
58
  'gpt-5.3-codex': ['low', 'medium', 'high', 'xhigh'],
56
59
  'gpt-oss-120b': ['low', 'medium', 'high'],
57
60
  'openai/gpt-oss-120b': ['low', 'medium', 'high'],
61
+ 'accounts/fireworks/models/gpt-oss-120b': ['low', 'medium', 'high'],
62
+ 'kimi-k3': ['low', 'high', 'max'],
63
+ 'moonshotai/kimi-k3': ['low', 'high', 'max'],
64
+ 'accounts/fireworks/models/kimi-k3': ['low', 'high', 'max'],
65
+ 'moonshotai/Kimi-K3': ['low', 'high', 'max'],
66
+ 'zai-org/GLM-5.2': ['high', 'xhigh'],
67
+ 'accounts/fireworks/models/glm-5p2': ['high', 'xhigh'],
68
+ 'z-ai/glm-5.2': ['high', 'xhigh'],
58
69
  };
59
70
 
60
71
  /**
package/index.d.ts CHANGED
@@ -496,7 +496,7 @@ export declare class ModelMix {
496
496
  grok420(args?: ModelAttachArgs): this;
497
497
 
498
498
  // Multi-provider
499
- qwen3(args?: ModelAttachArgs): this;
499
+ museGlimmer30b(args?: ModelAttachArgs): this;
500
500
  qwen35397b(args?: ModelAttachArgs): this;
501
501
  qwen36plus(args?: ModelAttachArgs): this;
502
502
  qwen37plus(args?: ModelAttachArgs): this;
@@ -516,7 +516,6 @@ export declare class ModelMix {
516
516
  mimo25pro(args?: ModelAttachArgs): this;
517
517
  deepseekV4Pro(args?: ModelAttachArgs): this;
518
518
  deepseekV4Flash(args?: ModelAttachArgs): this;
519
- GLM51(args?: ModelAttachArgs): this;
520
519
  GLM52(args?: ModelAttachArgs): this;
521
520
  GLM53(args?: ModelAttachArgs): this;
522
521
 
package/index.js CHANGED
@@ -490,6 +490,8 @@ class ModelMix {
490
490
  }
491
491
  gptOss({ options = {}, config = {}, mix = {} } = {}) {
492
492
  mix = { ...this.mix, ...mix };
493
+ if (mix.nvidia) this.attach('openai/gpt-oss-120b', new MixNVIDIA({ options, config }));
494
+ if (mix.fireworks) this.attach('accounts/fireworks/models/gpt-oss-120b', new MixFireworks({ options, config }));
493
495
  if (mix.together) this.attach('openai/gpt-oss-120b', new MixTogether({ options, config }));
494
496
  if (mix.cerebras) this.attach('gpt-oss-120b', new MixCerebras({ options, config }));
495
497
  if (mix.groq) this.attach('openai/gpt-oss-120b', new MixGroq({ options, config }));
@@ -574,9 +576,12 @@ class ModelMix {
574
576
  return this.attach('grok-4.20-0309', new MixGrok({ options, config }));
575
577
  }
576
578
 
577
- qwen3({ options = {}, config = {}, mix = { together: true, cerebras: false } } = {}) {
578
- if (mix.together) this.attach('Qwen/Qwen3-235B-A22B-fp8-tput', new MixTogether({ options, config }));
579
- if (mix.cerebras) this.attach('qwen-3-32b', new MixCerebras({ options, config }));
579
+ museGlimmer30b({ options = {}, config = {}, mix = { fireworks: true } } = {}) {
580
+ mix = { ...this.mix, ...mix };
581
+ if (mix.nvidia) this.attach('meta/muse-glimmer-30b', new MixNVIDIA({ options, config }));
582
+ if (mix.fireworks) this.attach('accounts/fireworks/models/muse-glimmer-30b', new MixFireworks({ options, config }));
583
+ if (mix.openrouter) this.attach('meta/muse-glimmer-30b', new MixOpenRouter({ options, config }));
584
+ if (mix.together) this.attach('meta-models/Muse-Glimmer-30B', new MixTogether({ options, config }));
580
585
  return this;
581
586
  }
582
587
 
@@ -584,9 +589,10 @@ class ModelMix {
584
589
  return this.attach('qwen/qwen3.5-397b-a17b', new MixOpenRouter({ options, config }));
585
590
  }
586
591
 
587
- qwen36plus({ options = {}, config = {}, mix = { fireworks: true } } = {}) {
592
+ qwen36plus({ options = {}, config = {}, mix = { fireworks: false, openrouter: true } } = {}) {
588
593
  mix = { ...this.mix, ...mix };
589
594
  if (mix.fireworks) this.attach('accounts/fireworks/models/qwen3p6-plus', new MixFireworks({ options, config }));
595
+ if (mix.openrouter) this.attach('qwen/qwen3.6-plus', new MixOpenRouter({ options, config }));
590
596
  if (mix.together) this.attach('Qwen/Qwen3.6-Plus', new MixTogether({ options, config }));
591
597
  return this;
592
598
  }
@@ -595,6 +601,7 @@ class ModelMix {
595
601
  mix = { ...this.mix, ...mix };
596
602
  if (mix.fireworks) this.attach('accounts/fireworks/models/qwen3p7-plus', new MixFireworks({ options, config }));
597
603
  if (mix.openrouter) this.attach('qwen/qwen3.7-plus', new MixOpenRouter({ options, config }));
604
+ if (mix.together) this.attach('Qwen/Qwen3.7-Plus', new MixTogether({ options, config }));
598
605
  return this;
599
606
  }
600
607
 
@@ -635,13 +642,17 @@ class ModelMix {
635
642
  kimiK27Code({ options = {}, config = {}, mix = { together: true } } = {}) {
636
643
  mix = { ...this.mix, ...mix };
637
644
  if (mix.together) this.attach('moonshotai/Kimi-K2.7-Code', new MixTogether({ options, config }));
645
+ if (mix.fireworks) this.attach('accounts/fireworks/models/kimi-k2p7-code', new MixFireworks({ options, config }));
646
+ if (mix.openrouter) this.attach('moonshotai/kimi-k2.7-code', new MixOpenRouter({ options, config }));
638
647
  return this;
639
648
  }
640
649
 
641
650
  kimiK3({ options = {}, config = {}, mix = { moonshot: true, openrouter: false } } = {}) {
642
651
  mix = { ...this.mix, ...mix };
643
652
  if (mix.moonshot) this.attach('kimi-k3', new MixKimi({ options, config }));
653
+ if (mix.fireworks) this.attach('accounts/fireworks/models/kimi-k3', new MixFireworks({ options, config }));
644
654
  if (mix.openrouter) this.attach('moonshotai/kimi-k3', new MixOpenRouter({ options, config }));
655
+ if (mix.together) this.attach('moonshotai/Kimi-K3', new MixTogether({ options, config }));
645
656
  return this;
646
657
  }
647
658
 
@@ -661,14 +672,16 @@ class ModelMix {
661
672
  minimaxM27({ options = {}, config = {}, mix = { openrouter: true, minimax: true } } = {}) {
662
673
  mix = { ...this.mix, ...mix };
663
674
  if (mix.nvidia) this.attach('minimaxai/minimax-m2.7', new MixNVIDIA({ options, config }));
664
- if (mix.openrouter) return this.attach('minimax/minimax-m2.7', new MixOpenRouter({ options, config }));
665
- if (mix.minimax) return this.attach('MiniMax-M2.7', new MixMiniMax({ options, config }));
666
- if (mix.together) return this.attach('MiniMaxAI/MiniMax-M2.7', new MixTogether({ options, config }));
675
+ if (mix.fireworks) this.attach('accounts/fireworks/models/minimax-m2p7', new MixFireworks({ options, config }));
676
+ if (mix.openrouter) this.attach('minimax/minimax-m2.7', new MixOpenRouter({ options, config }));
677
+ if (mix.minimax) this.attach('MiniMax-M2.7', new MixMiniMax({ options, config }));
678
+ if (mix.together) this.attach('MiniMaxAI/MiniMax-M2.7', new MixTogether({ options, config }));
667
679
  return this;
668
680
  }
669
681
 
670
682
  minimaxM3({ options = {}, config = {}, mix = { minimax: true, openrouter: false } } = {}) {
671
683
  mix = { ...this.mix, ...mix };
684
+ if (mix.fireworks) this.attach('accounts/fireworks/models/minimax-m3', new MixFireworks({ options, config }));
672
685
  if (mix.openrouter) this.attach('minimax/minimax-m3', new MixOpenRouter({ options, config }));
673
686
  if (mix.minimax) this.attach('MiniMax-M3', new MixMiniMax({ options, config }));
674
687
  if (mix.together) this.attach('MiniMaxAI/MiniMax-M3', new MixTogether({ options, config }));
@@ -707,18 +720,11 @@ class ModelMix {
707
720
  return this;
708
721
  }
709
722
 
710
- GLM51({ options = {}, config = {}, mix = { fireworks: true } } = {}) {
711
- mix = { ...this.mix, ...mix };
712
- if (mix.nvidia) this.attach('z-ai/glm-5.1', new MixNVIDIA({ options, config }));
713
- if (mix.fireworks) this.attach('accounts/fireworks/models/glm-5p1', new MixFireworks({ options, config }));
714
- if (mix.openrouter) this.attach('z-ai/glm-5.1', new MixOpenRouter({ options, config }));
715
- if (mix.together) this.attach('zai-org/GLM-5.1', new MixTogether({ options, config }));
716
- return this;
717
- }
718
-
719
723
  GLM52({ options = {}, config = {}, mix = { together: true } } = {}) {
720
724
  mix = { ...this.mix, ...mix };
721
725
  if (mix.together) this.attach('zai-org/GLM-5.2', new MixTogether({ options, config }));
726
+ if (mix.fireworks) this.attach('accounts/fireworks/models/glm-5p2', new MixFireworks({ options, config }));
727
+ if (mix.openrouter) this.attach('z-ai/glm-5.2', new MixOpenRouter({ options, config }));
722
728
  return this;
723
729
  }
724
730
 
@@ -10,11 +10,12 @@ const CHAIN_MODEL_SHORTCUTS = new Set([
10
10
  'gemini31pro', 'gemini37flash', 'gemini36flash', 'gemini35flash',
11
11
  'gemini35flashLite', 'gemini31flashLite', 'sonarPro', 'sonar',
12
12
  'grok46', 'grok45', 'grok43', 'grok420multiAgent', 'grok420',
13
- 'qwen3', 'qwen35397b', 'qwen36plus', 'qwen37plus', 'qwen38max', 'qwen3827b',
13
+ 'museGlimmer30b',
14
+ 'qwen35397b', 'qwen36plus', 'qwen37plus', 'qwen38max', 'qwen3827b',
14
15
  'hermes470b', 'hermes4405b', 'hermes3',
15
16
  'kimiK26', 'kimiK27Code', 'kimiK3', 'kimiK25',
16
17
  'minimaxM27', 'minimaxM3', 'mimo25', 'mimo25pro',
17
- 'deepseekV4Pro', 'deepseekV4Flash', 'GLM51', 'GLM52', 'GLM53'
18
+ 'deepseekV4Pro', 'deepseekV4Flash', 'GLM52', 'GLM53'
18
19
  ]);
19
20
 
20
21
  function parseChainModels(modelSpecs) {
@@ -42,9 +42,10 @@ const MODEL_PRICING = {
42
42
  'gpt-4.1': { input: 2.00, cachedInput: 0.50, output: 8.00 },
43
43
  'gpt-4.1-mini': { input: 0.40, cachedInput: 0.10, output: 1.60 },
44
44
  'gpt-4.1-nano': { input: 0.10, cachedInput: 0.025, output: 0.40 },
45
- // gptOss (Together/Groq/Cerebras/OpenRouter)
45
+ // gptOss (NVIDIA/Fireworks/Together/Groq/Cerebras/OpenRouter)
46
46
  'openai/gpt-oss-120b': { input: 0.15, output: 0.60 },
47
47
  'gpt-oss-120b': { input: 0.15, output: 0.60 },
48
+ 'accounts/fireworks/models/gpt-oss-120b': { input: 0.15, cachedInput: 0.014, output: 0.60 },
48
49
  // Anthropic
49
50
  'claude-fable-5': { input: 10.00, cachedInput: 1.00, cacheWrite: 12.50, cacheWrite1h: 20.00, output: 50.00 },
50
51
  'claude-opus-5': { input: 5.00, cachedInput: 0.50, cacheWrite: 6.25, cacheWrite1h: 10.00, output: 25.00 },
@@ -74,6 +75,10 @@ const MODEL_PRICING = {
74
75
  'grok-4.20-0309': { input: 1.25, output: 2.50 },
75
76
  'grok-4.20-0309-reasoning': { input: 1.25, output: 2.50 },
76
77
  'grok-4.20-0309-non-reasoning': { input: 1.25, output: 2.50 },
78
+ // Muse Glimmer 30B (NVIDIA/OpenRouter, Fireworks, Together)
79
+ 'meta/muse-glimmer-30b': { input: 0.35, cachedInput: 0.04, output: 1.50 },
80
+ 'accounts/fireworks/models/muse-glimmer-30b': { input: 0.35, cachedInput: 0.04, output: 1.50 },
81
+ 'meta-models/Muse-Glimmer-30B': { input: 0.35, cachedInput: 0.04, output: 1.50 },
77
82
  // Fireworks
78
83
  'accounts/fireworks/models/deepseek-v4-flash': { input: 0.14, output: 0.28 },
79
84
  'accounts/fireworks/models/deepseek-v4-pro': { input: 1.74, output: 3.48 },
@@ -82,15 +87,29 @@ const MODEL_PRICING = {
82
87
  'deepseek-ai/DeepSeek-V4-Pro': { input: 2.10, output: 4.40 },
83
88
  'deepseek/deepseek-v4-flash': { input: 0.09, output: 0.18 },
84
89
  'accounts/fireworks/models/glm-4p7': { input: 0.55, output: 2.19 },
85
- 'accounts/fireworks/models/glm-5p1': { input: 1.05, output: 3.50 },
86
- 'zai-org/GLM-5.2': { input: 1.40, output: 4.40 },
90
+ 'zai-org/GLM-5.2': { input: 1.40, cachedInput: 0.26, output: 4.40 },
91
+ 'accounts/fireworks/models/glm-5p2': { input: 1.40, cachedInput: 0.14, output: 4.40 },
92
+ 'z-ai/glm-5.2': { input: 0.966, cachedInput: 0.1932, output: 3.036 },
87
93
  'z-ai/glm-5.3': { input: 1.40, cachedInput: 0.26, output: 4.40 },
88
94
  'accounts/fireworks/models/kimi-k2p5': { input: 0.50, output: 2.80 },
89
95
  'qwen/qwen3.5-397b-a17b': { input: 0.385, output: 2.45 },
90
96
  'accounts/fireworks/models/qwen3p6-plus': { input: 0.50, output: 3.00 },
91
97
  'Qwen/Qwen3.6-Plus': { input: 0.50, output: 3.00 },
98
+ 'qwen/qwen3.6-plus': {
99
+ input: 0.325,
100
+ cacheWrite: 0.40625,
101
+ output: 1.95,
102
+ longContext: { inputThreshold: 256_000, inputMultiplier: 4, outputMultiplier: 2, inclusive: true }
103
+ },
92
104
  'accounts/fireworks/models/qwen3p7-plus': { input: 0.40, output: 1.60 },
93
- 'qwen/qwen3.7-plus': { input: 0.32, output: 1.28 },
105
+ 'qwen/qwen3.7-plus': {
106
+ input: 0.32,
107
+ cachedInput: 0.064,
108
+ cacheWrite: 0.40,
109
+ output: 1.28,
110
+ longContext: { inputThreshold: 256_000, inputMultiplier: 3, outputMultiplier: 3, inclusive: true }
111
+ },
112
+ 'Qwen/Qwen3.7-Plus': { input: 0.32, output: 1.28 },
94
113
  'accounts/fireworks/models/qwen3p8-2p4t-a95b': { input: 2.00, cachedInput: 0.25, output: 6.00 },
95
114
  'qwen/qwen3.8-max': { input: 2.00, output: 6.00 },
96
115
  'qwen/qwen3.8-27b': { input: 0.45, cachedInput: 0.05, output: 3.20 },
@@ -100,7 +119,11 @@ const MODEL_PRICING = {
100
119
  'MiniMax-M3': { input: 0.30, output: 1.20 },
101
120
  'minimax/minimax-m2.7': { input: 0.30, output: 1.20 },
102
121
  'minimax/minimax-m3': { input: 0.30, output: 1.20 },
122
+ 'minimaxai/minimax-m2.7': { input: 0.30, output: 1.20 },
123
+ 'MiniMaxAI/MiniMax-M2.7': { input: 0.30, output: 1.20 },
103
124
  'MiniMaxAI/MiniMax-M3': { input: 0.30, output: 1.20 },
125
+ 'accounts/fireworks/models/minimax-m2p7': { input: 0.30, cachedInput: 0.059, output: 1.20 },
126
+ 'accounts/fireworks/models/minimax-m3': { input: 0.30, cachedInput: 0.059, output: 1.20 },
104
127
  // Perplexity
105
128
  'sonar': { input: 1.00, output: 1.00 },
106
129
  'sonar-pro': { input: 3.00, output: 15.00 },
@@ -110,15 +133,18 @@ const MODEL_PRICING = {
110
133
  // Hermes 3 (Lambda/OpenRouter)
111
134
  'Hermes-3-Llama-3.1-405B-FP8': { input: 0.80, output: 0.80 },
112
135
  'nousresearch/hermes-3-llama-3.1-405b:free': { input: 0, output: 0 },
113
- // Qwen3 (Together/Cerebras)
114
- 'Qwen/Qwen3-235B-A22B-fp8-tput': { input: 0.20, output: 0.60 },
115
- 'qwen-3-32b': { input: 0.20, output: 0.60 },
116
136
  // Kimi K2.5 (Together/Fireworks/OpenRouter)
117
137
  'moonshotai/Kimi-K2.5': { input: 0.50, output: 2.80 },
118
138
  'moonshotai/kimi-k2.5': { input: 0.50, output: 2.80 },
119
139
  // Kimi K3
120
- 'kimi-k3': { input: 3.00, output: 15.00 },
121
- 'moonshotai/kimi-k3': { input: 3.00, output: 15.00 },
140
+ 'kimi-k3': { input: 3.00, cachedInput: 0.30, output: 15.00 },
141
+ 'moonshotai/kimi-k3': { input: 3.00, cachedInput: 0.30, output: 15.00 },
142
+ 'accounts/fireworks/models/kimi-k3': { input: 3.00, cachedInput: 0.30, output: 15.00 },
143
+ 'moonshotai/Kimi-K3': { input: 3.00, cachedInput: 0.30, output: 15.00 },
144
+ // Kimi K2.7 Code
145
+ 'moonshotai/Kimi-K2.7-Code': { input: 0.95, cachedInput: 0.19, output: 4.00 },
146
+ 'accounts/fireworks/models/kimi-k2p7-code': { input: 0.95, cachedInput: 0.19, output: 4.00 },
147
+ 'moonshotai/kimi-k2.7-code': { input: 0.71, cachedInput: 0.15, output: 3.50 },
122
148
  // GLM 4.7 (OpenRouter/Cerebras)
123
149
  'z-ai/glm-4.7': { input: 0.55, output: 2.19 },
124
150
  'zai-glm-4.7': { input: 0.55, output: 2.19 },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "modelmix",
3
- "version": "5.1.4",
3
+ "version": "5.1.6",
4
4
  "description": "🧬 Reliable interface with automatic fallback for AI LLMs.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -168,22 +168,25 @@ Use `.effort(n)` (or `config.effort`) to enable Anthropic thinking — e.g. `.ef
168
168
  `sonar()` `sonarPro()`
169
169
 
170
170
  ### Together
171
- `qwen36plus()` `GLM52()` `kimiK25()` `kimiK26()` `gptOss()`
171
+ `museGlimmer30b()` `qwen36plus()` `qwen37plus()` `GLM52()` `kimiK25()` `kimiK26()` `kimiK27Code()` `kimiK3()` `minimaxM27()` `minimaxM3()` `gptOss()`
172
+
173
+ ### NVIDIA
174
+ `museGlimmer30b()` `gptOss()` `minimaxM27()`
172
175
 
173
176
  ### Moonshot
174
- `kimiK3()` — requires `MOONSHOT_API_KEY`; use `{ mix: { moonshot: false, openrouter: true } }` for OpenRouter.
177
+ `kimiK3()` — requires `MOONSHOT_API_KEY`; Fireworks, OpenRouter, and Together are available through `mix`.
175
178
 
176
179
  ### MiniMax
177
180
  `minimaxM27()` `minimaxM3()`
178
181
 
179
182
  ### Fireworks
180
- `qwen36plus()` `qwen37plus()` `qwen38max()` `deepseekV4Flash()` `deepseekV4Pro()` `kimiK26()`
183
+ `museGlimmer30b()` `gptOss()` `qwen36plus()` (private/on-demand only) `qwen37plus()` `qwen38max()` `deepseekV4Flash()` `deepseekV4Pro()` `kimiK26()` `kimiK27Code()` `kimiK3()` `minimaxM27()` `minimaxM3()` `GLM52()`
181
184
 
182
185
  ### Cerebras
183
186
  `GLM46()`
184
187
 
185
188
  ### OpenRouter
186
- `qwen35397b()` `qwen3827b()` `hermes470b()` `hermes4405b()` `qwen38max()` `GLM45()` `GLM53()`
189
+ `museGlimmer30b()` `gptOss()` `qwen35397b()` `qwen36plus()` `qwen37plus()` `qwen3827b()` `hermes470b()` `hermes4405b()` `qwen38max()` `kimiK27Code()` `kimiK3()` `minimaxM27()` `minimaxM3()` `GLM45()` `GLM52()` `GLM53()`
187
190
 
188
191
  ### Multi-provider (auto-fallback across free/paid tiers)
189
192
  `hermes3()` `kimiK25()`
@@ -96,6 +96,42 @@ describe('Unified effort scale', () => {
96
96
  expect(mapEffort('openai', 100, key)).to.deep.equal({ reasoning_effort: 'high' });
97
97
  });
98
98
 
99
+ it('maps the new GPT OSS providers to low, medium, and high reasoning', () => {
100
+ expect(mapEffort('openai', 0, 'accounts/fireworks/models/gpt-oss-120b')).to.deep.equal({
101
+ reasoning_effort: 'low'
102
+ });
103
+ expect(mapEffort('openai', 50, 'openai/gpt-oss-120b')).to.deep.equal({
104
+ reasoning_effort: 'medium'
105
+ });
106
+ expect(mapEffort('openai', 100, 'accounts/fireworks/models/gpt-oss-120b')).to.deep.equal({
107
+ reasoning_effort: 'high'
108
+ });
109
+ });
110
+
111
+ it('maps Kimi K3 and GLM 5.2 to their provider-supported levels', () => {
112
+ expect(mapEffort('openai', 100, 'moonshotai/Kimi-K3')).to.deep.equal({
113
+ reasoning_effort: 'max'
114
+ });
115
+ expect(mapEffort('openai', 0, 'accounts/fireworks/models/glm-5p2')).to.deep.equal({
116
+ reasoning_effort: 'high'
117
+ });
118
+ expect(mapEffort('openai', 100, 'z-ai/glm-5.2')).to.deep.equal({
119
+ reasoning_effort: 'xhigh'
120
+ });
121
+ });
122
+
123
+ it('maps Muse Glimmer 30B to provider-supported reasoning levels', () => {
124
+ expect(mapEffort('openai', 0, 'accounts/fireworks/models/muse-glimmer-30b')).to.deep.equal({
125
+ reasoning_effort: 'low'
126
+ });
127
+ expect(mapEffort('openai', 100, 'accounts/fireworks/models/muse-glimmer-30b')).to.deep.equal({
128
+ reasoning_effort: 'xhigh'
129
+ });
130
+ expect(mapEffort('openai', 100, 'meta/muse-glimmer-30b')).to.deep.equal({
131
+ reasoning_effort: 'high'
132
+ });
133
+ });
134
+
99
135
  it('maps Qwen 3.8 27B to its supported reasoning levels', () => {
100
136
  const key = 'qwen/qwen3.8-27b';
101
137
  expect(mapEffort('openai', 0, key)).to.deep.equal({ reasoning_effort: 'low' });
@@ -64,7 +64,7 @@ describe('Provider Fallback Chain Tests', () => {
64
64
  for (const shortcut of [
65
65
  'gpt41', 'gpt41mini', 'gpt41nano',
66
66
  'gemini25flash', 'gemini25pro', 'gemini3pro', 'gemini3flash',
67
- 'minimaxM25'
67
+ 'minimaxM25', 'qwen3', 'GLM51'
68
68
  ]) {
69
69
  expect(model[shortcut]).to.equal(undefined);
70
70
  expect(() => model.chain(shortcut))
package/test/glm.test.js CHANGED
@@ -1,13 +1,37 @@
1
1
  const { expect } = require('chai');
2
- const { ModelMix, MixOpenRouter } = require('../index.js');
2
+ const { ModelMix, MixFireworks, MixOpenRouter, MixTogether } = require('../index.js');
3
3
 
4
4
  describe('GLM Model Registration Tests', () => {
5
- it('should register Together GLM 5.2 by default', () => {
5
+ it('should register Together GLM 5.2 before the OpenRouter fallback by default', () => {
6
6
  const model = ModelMix.new();
7
7
  model.GLM52();
8
8
 
9
- expect(model.models).to.have.length(1);
10
- expect(model.models[0].key).to.equal('zai-org/GLM-5.2');
9
+ expect(model.models.map(({ key }) => key)).to.deep.equal([
10
+ 'zai-org/GLM-5.2',
11
+ 'z-ai/glm-5.2'
12
+ ]);
13
+ expect(model.models[0].provider).to.be.instanceOf(MixTogether);
14
+ expect(model.models[1].provider).to.be.instanceOf(MixOpenRouter);
15
+ });
16
+
17
+ it('should register every requested GLM 5.2 provider', () => {
18
+ const model = ModelMix.new().GLM52({
19
+ mix: { together: true, fireworks: true, openrouter: true }
20
+ });
21
+
22
+ expect(model.models.map(({ key }) => key)).to.deep.equal([
23
+ 'zai-org/GLM-5.2',
24
+ 'accounts/fireworks/models/glm-5p2',
25
+ 'z-ai/glm-5.2'
26
+ ]);
27
+ expect(model.models[0].provider).to.be.instanceOf(MixTogether);
28
+ expect(model.models[1].provider).to.be.instanceOf(MixFireworks);
29
+ expect(model.models[2].provider).to.be.instanceOf(MixOpenRouter);
30
+ expect(ModelMix.calculateCost('accounts/fireworks/models/glm-5p2', {
31
+ input: 1_000_000,
32
+ cached: 500_000,
33
+ output: 1_000_000
34
+ })).to.equal(5.17);
11
35
  });
12
36
 
13
37
  it('should register GLM 5.3 through OpenRouter', () => {
package/test/kimi.test.js CHANGED
@@ -1,15 +1,32 @@
1
1
  const { expect } = require('chai');
2
2
  const nock = require('nock');
3
- const { ModelMix, MixKimi, MixOpenRouter, MixTogether } = require('../index.js');
3
+ const { ModelMix, MixFireworks, MixKimi, MixOpenRouter, MixTogether } = require('../index.js');
4
4
 
5
5
  describe('Kimi Model Registration Tests', () => {
6
- it('should register Together Kimi K2.7 Code by default', () => {
6
+ it('should register Together Kimi K2.7 Code before the OpenRouter fallback by default', () => {
7
7
  const model = ModelMix.new();
8
8
  model.kimiK27Code();
9
9
 
10
- expect(model.models).to.have.length(1);
11
- expect(model.models[0].key).to.equal('moonshotai/Kimi-K2.7-Code');
10
+ expect(model.models.map(({ key }) => key)).to.deep.equal([
11
+ 'moonshotai/Kimi-K2.7-Code',
12
+ 'moonshotai/kimi-k2.7-code'
13
+ ]);
12
14
  expect(model.models[0].provider).to.be.instanceOf(MixTogether);
15
+ expect(model.models[1].provider).to.be.instanceOf(MixOpenRouter);
16
+ });
17
+
18
+ it('should register every requested Kimi K2.7 Code provider', () => {
19
+ const model = ModelMix.new().kimiK27Code({
20
+ mix: { together: true, fireworks: true, openrouter: true }
21
+ });
22
+
23
+ expect(model.models.map(({ key }) => key)).to.deep.equal([
24
+ 'moonshotai/Kimi-K2.7-Code',
25
+ 'accounts/fireworks/models/kimi-k2p7-code',
26
+ 'moonshotai/kimi-k2.7-code'
27
+ ]);
28
+ expect(model.models[1].provider).to.be.instanceOf(MixFireworks);
29
+ expect(model.models[2].provider).to.be.instanceOf(MixOpenRouter);
13
30
  });
14
31
 
15
32
  it('should register Kimi K3 with the native Moonshot provider by default', () => {
@@ -45,6 +62,19 @@ describe('Kimi Model Registration Tests', () => {
45
62
  }
46
63
  });
47
64
 
65
+ it('should register Fireworks and Together Kimi K3 when requested', () => {
66
+ const model = ModelMix.new().kimiK3({
67
+ mix: { moonshot: false, fireworks: true, openrouter: false, together: true }
68
+ });
69
+
70
+ expect(model.models.map(({ key }) => key)).to.deep.equal([
71
+ 'accounts/fireworks/models/kimi-k3',
72
+ 'moonshotai/Kimi-K3'
73
+ ]);
74
+ expect(model.models[0].provider).to.be.instanceOf(MixFireworks);
75
+ expect(model.models[1].provider).to.be.instanceOf(MixTogether);
76
+ });
77
+
48
78
  it('should adapt Kimi K3 requests to its fixed sampling API', async () => {
49
79
  const originalMoonshotApiKey = process.env.MOONSHOT_API_KEY;
50
80
  process.env.MOONSHOT_API_KEY = 'test-moonshot-key';
@@ -0,0 +1,61 @@
1
+ const { expect } = require('chai');
2
+ const {
3
+ ModelMix,
4
+ MixFireworks,
5
+ MixNVIDIA,
6
+ MixOpenRouter,
7
+ MixTogether
8
+ } = require('../index.js');
9
+
10
+ describe('Muse Glimmer Model Registration Tests', () => {
11
+ it('registers Fireworks before the OpenRouter fallback by default', () => {
12
+ const model = ModelMix.new().museGlimmer30b();
13
+
14
+ expect(model.models.map(({ key }) => key)).to.deep.equal([
15
+ 'accounts/fireworks/models/muse-glimmer-30b',
16
+ 'meta/muse-glimmer-30b'
17
+ ]);
18
+ expect(model.models[0].provider).to.be.instanceOf(MixFireworks);
19
+ expect(model.models[1].provider).to.be.instanceOf(MixOpenRouter);
20
+ });
21
+
22
+ it('registers every supported provider in fallback order', () => {
23
+ const model = ModelMix.new().museGlimmer30b({
24
+ mix: { nvidia: true, fireworks: true, openrouter: true, together: true }
25
+ });
26
+
27
+ expect(model.models.map(({ key }) => key)).to.deep.equal([
28
+ 'meta/muse-glimmer-30b',
29
+ 'accounts/fireworks/models/muse-glimmer-30b',
30
+ 'meta/muse-glimmer-30b',
31
+ 'meta-models/Muse-Glimmer-30B'
32
+ ]);
33
+ expect(model.models.map(({ provider }) => provider.constructor)).to.deep.equal([
34
+ MixNVIDIA,
35
+ MixFireworks,
36
+ MixOpenRouter,
37
+ MixTogether
38
+ ]);
39
+ });
40
+
41
+ it('calculates cached input pricing for every provider model ID', () => {
42
+ const usage = { input: 1_000_000, cached: 250_000, output: 1_000_000 };
43
+
44
+ for (const key of [
45
+ 'meta/muse-glimmer-30b',
46
+ 'accounts/fireworks/models/muse-glimmer-30b',
47
+ 'meta-models/Muse-Glimmer-30B'
48
+ ]) {
49
+ expect(ModelMix.calculateCost(key, usage)).to.equal(1.7725);
50
+ }
51
+ });
52
+
53
+ it('supports Muse Glimmer 30B in chain()', () => {
54
+ const model = ModelMix.new().chain('museGlimmer30b');
55
+
56
+ expect(model.models.map(({ key }) => key)).to.deep.equal([
57
+ 'accounts/fireworks/models/muse-glimmer-30b',
58
+ 'meta/muse-glimmer-30b'
59
+ ]);
60
+ });
61
+ });
@@ -0,0 +1,83 @@
1
+ const { expect } = require('chai');
2
+ const {
3
+ ModelMix,
4
+ MixFireworks,
5
+ MixMiniMax,
6
+ MixNVIDIA,
7
+ MixOpenRouter,
8
+ MixTogether
9
+ } = require('../index.js');
10
+
11
+ describe('Provider expansion regressions', () => {
12
+ it('should retain every enabled GPT OSS provider, including shared model keys', () => {
13
+ const model = ModelMix.new().gptOss({
14
+ mix: {
15
+ nvidia: true,
16
+ fireworks: true,
17
+ together: true,
18
+ cerebras: true,
19
+ groq: true,
20
+ openrouter: true
21
+ }
22
+ });
23
+
24
+ expect(model.models.map(({ key }) => key)).to.deep.equal([
25
+ 'openai/gpt-oss-120b',
26
+ 'accounts/fireworks/models/gpt-oss-120b',
27
+ 'openai/gpt-oss-120b',
28
+ 'gpt-oss-120b',
29
+ 'openai/gpt-oss-120b',
30
+ 'openai/gpt-oss-120b'
31
+ ]);
32
+ expect(model.models[0].provider).to.be.instanceOf(MixNVIDIA);
33
+ expect(model.models[1].provider).to.be.instanceOf(MixFireworks);
34
+ expect(ModelMix.calculateCost('accounts/fireworks/models/gpt-oss-120b', {
35
+ input: 1_000_000,
36
+ cached: 500_000,
37
+ output: 1_000_000
38
+ })).to.equal(0.682);
39
+ });
40
+
41
+ it('should retain every enabled MiniMax M2.7 provider in fallback order', () => {
42
+ const originalMiniMaxApiKey = process.env.MINIMAX_API_KEY;
43
+ process.env.MINIMAX_API_KEY = 'test-minimax-key';
44
+
45
+ try {
46
+ const model = ModelMix.new().minimaxM27({
47
+ mix: {
48
+ nvidia: true,
49
+ fireworks: true,
50
+ openrouter: true,
51
+ minimax: true,
52
+ together: true
53
+ }
54
+ });
55
+
56
+ expect(model.models.map(({ key }) => key)).to.deep.equal([
57
+ 'minimaxai/minimax-m2.7',
58
+ 'accounts/fireworks/models/minimax-m2p7',
59
+ 'minimax/minimax-m2.7',
60
+ 'MiniMax-M2.7',
61
+ 'MiniMaxAI/MiniMax-M2.7'
62
+ ]);
63
+ expect(model.models[0].provider).to.be.instanceOf(MixNVIDIA);
64
+ expect(model.models[1].provider).to.be.instanceOf(MixFireworks);
65
+ expect(model.models[2].provider).to.be.instanceOf(MixOpenRouter);
66
+ expect(model.models[3].provider).to.be.instanceOf(MixMiniMax);
67
+ expect(model.models[4].provider).to.be.instanceOf(MixTogether);
68
+ } finally {
69
+ if (originalMiniMaxApiKey === undefined) delete process.env.MINIMAX_API_KEY;
70
+ else process.env.MINIMAX_API_KEY = originalMiniMaxApiKey;
71
+ }
72
+ });
73
+
74
+ it('should register Fireworks for MiniMax M3 without changing its default', () => {
75
+ const model = ModelMix.new().minimaxM3({
76
+ mix: { fireworks: true, openrouter: false, minimax: false, together: false }
77
+ });
78
+
79
+ expect(model.models).to.have.length(1);
80
+ expect(model.models[0].key).to.equal('accounts/fireworks/models/minimax-m3');
81
+ expect(model.models[0].provider).to.be.instanceOf(MixFireworks);
82
+ });
83
+ });
package/test/qwen.test.js CHANGED
@@ -1,13 +1,22 @@
1
1
  const { expect } = require('chai');
2
- const { ModelMix, MixOpenRouter } = require('../index.js');
2
+ const { ModelMix, MixFireworks, MixOpenRouter, MixTogether } = require('../index.js');
3
3
 
4
4
  describe('Qwen Model Registration Tests', () => {
5
- it('should register Fireworks Qwen 3.6 Plus by default', () => {
5
+ it('should register OpenRouter Qwen 3.6 Plus by default', () => {
6
+ const model = ModelMix.new().qwen36plus();
7
+
8
+ expect(model.models).to.have.length(1);
9
+ expect(model.models[0].key).to.equal('qwen/qwen3.6-plus');
10
+ expect(model.models[0].provider).to.be.instanceOf(MixOpenRouter);
11
+ });
12
+
13
+ it('should retain Fireworks Qwen 3.6 Plus as an explicit deployment option', () => {
6
14
  const model = ModelMix.new();
7
- model.qwen36plus({ mix: { fireworks: true, together: false } });
15
+ model.qwen36plus({ mix: { fireworks: true, openrouter: false, together: false } });
8
16
 
9
17
  expect(model.models).to.have.length(1);
10
18
  expect(model.models[0].key).to.equal('accounts/fireworks/models/qwen3p6-plus');
19
+ expect(model.models[0].provider).to.be.instanceOf(MixFireworks);
11
20
  });
12
21
 
13
22
  it('should register Together Qwen 3.6 Plus when together mix is enabled', () => {
@@ -38,6 +47,26 @@ describe('Qwen Model Registration Tests', () => {
38
47
  expect(model.models[0].key).to.equal('qwen/qwen3.7-plus');
39
48
  });
40
49
 
50
+ it('should register Together Qwen 3.7 Plus when together mix is enabled', () => {
51
+ const model = ModelMix.new();
52
+ model.qwen37plus({ mix: { fireworks: false, openrouter: false, together: true } });
53
+
54
+ expect(model.models).to.have.length(1);
55
+ expect(model.models[0].key).to.equal('Qwen/Qwen3.7-Plus');
56
+ expect(model.models[0].provider).to.be.instanceOf(MixTogether);
57
+ });
58
+
59
+ it('should apply OpenRouter long-context pricing to Qwen 3.6 and 3.7 Plus', () => {
60
+ expect(ModelMix.calculateCost('qwen/qwen3.6-plus', {
61
+ input: 256_000,
62
+ output: 1_000_000
63
+ })).to.equal(4.2328);
64
+ expect(ModelMix.calculateCost('qwen/qwen3.7-plus', {
65
+ input: 256_000,
66
+ output: 1_000_000
67
+ })).to.equal(4.08576);
68
+ });
69
+
41
70
  it('should register Fireworks Qwen 3.8 Max before the OpenRouter fallback by default', () => {
42
71
  const model = ModelMix.new();
43
72
  model.qwen38max();