modelmix 5.1.8 → 5.1.10

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()` | Cerebras/Groq/OpenRouter | gpt-oss-120B | [\$0.15][7] | [\$0.60][7] |
154
+ | `gptOss()` | Multi-provider | 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] |
@@ -177,9 +177,11 @@ ModelMix provides convenient shorthand methods for quickly accessing different A
177
177
  | `qwen37plus()` | Fireworks | models/qwen3p7-plus | [\$0.40][10] | [\$1.60][10] |
178
178
  | `qwen38max()` | Fireworks | qwen3p8-2p4t-a95b | [\$2.00][10] | [\$6.00][10] |
179
179
  | `qwen3827b()` | OpenRouter | qwen/qwen3.8-27b | [\$0.45][15] | [\$3.20][15] |
180
+ | `qwen38flash()` | OpenRouter | qwen/qwen3.8-flash | [\$0.16][19] | [\$0.47][19] |
180
181
  | `deepseekV4Flash()` | Fireworks | models/deepseek-v4-flash | [\$0.14][10] | [\$0.28][10] |
181
182
  | `deepseekV4Pro()` | Fireworks | models/deepseek-v4-pro-0813 | [\$1.32][12] | [\$3.96][12] |
182
183
  | `GLM53()` | OpenRouter | z-ai/glm-5.3 | [\$1.40][16] | [\$4.40][16] |
184
+ | `GLM53Flash()` | OpenRouter | z-ai/glm-5.3-flash | [\$0.075][20] | [\$0.25][20] |
183
185
  | `GLM52()` | Together | zai-org/GLM-5.2 | [\$1.40][7] | [\$4.40][7] |
184
186
  | `minimaxM3()` | MiniMax | MiniMax-M3 | [\$0.30][9] | [\$1.20][9] |
185
187
  | `minimaxM27()` | MiniMax | MiniMax-M2.7 | [\$0.30][9] | [\$1.20][9] |
@@ -217,6 +219,8 @@ The multi-provider shortcuts also expose the current catalog alternatives: `gptO
217
219
  [16]: https://openrouter.ai/z-ai/glm-5.3 "GLM 5.3 on OpenRouter"
218
220
  [17]: https://fireworks.ai/models/fireworks/muse-glimmer-30b "Muse Glimmer 30B on Fireworks"
219
221
  [18]: https://openrouter.ai/qwen/qwen3.6-plus "Qwen 3.6 Plus on OpenRouter"
222
+ [19]: https://openrouter.ai/qwen/qwen3.8-flash "Qwen3.8 Flash on OpenRouter"
223
+ [20]: https://openrouter.ai/z-ai/glm-5.3-flash "GLM 5.3 Flash on OpenRouter"
220
224
 
221
225
  Each method accepts optional `options`, `config`, and (for multi-provider methods) `mix` parameters to customize behavior.
222
226
 
@@ -257,8 +261,8 @@ ModelMix.new().effort(-1).minimaxM3().addText('...').message();
257
261
 
258
262
  - **Gemini:** Gemini 3+ uses bands 0–24 / 25–49 / 50–74 / 75–100. Gemini 3.7 Flash clamps these bands to `low` / `low` / `medium` / `high`; `-1` leaves its native `medium` default unchanged. Gemini 2.5 maps 0–100 to `thinkingBudget`.
259
263
  - **GPT-5.6:** `100` maps to `max`; 80–99 remains `xhigh`.
260
- - **Qwen 3.8 27B:** 0–39 / 40–79 / 80–100 map to `low` / `medium` / `xhigh`; `-1` leaves the native `xhigh` default unchanged.
261
- - **GLM 5.3:** reasoning is mandatory; 0–39 / 40–79 / 80–100 map to `low` / `high` / `max`; `-1` leaves the native `max` default unchanged.
264
+ - **Qwen 3.8 27B and Flash:** 0–39 / 40–79 / 80–100 map to `low` / `medium` / `xhigh`; `-1` leaves the native `xhigh` default unchanged. Qwen 3.8 Flash is the managed production version based on the open-weight Flash-Next architecture.
265
+ - **GLM 5.3 and GLM 5.3 Flash:** reasoning is mandatory; 0–39 / 40–79 / 80–100 map to `low` / `high` / `max`; `-1` leaves the native `max` default unchanged.
262
266
  - **DeepSeek:** `↑` means thinking is enabled; `off` means it is disabled.
263
267
  - **MiniMax:** `off` maps to `thinking.disabled`; `adaptive` maps to `thinking.type=adaptive`.
264
268
  - **Anthropic:** Claude 5, Fable, Opus 4.6+, and Sonnet 4.6+ use adaptive thinking with `output_config.effort`. Sonnet 4.5 and Haiku 4.5 use `thinking.type=enabled` with `budget_tokens`.
package/demo/short.js CHANGED
@@ -16,10 +16,12 @@ const mmix = await ModelMix.new(setup)
16
16
  .grok46() // (fallback 4) Grok grok-4.6
17
17
  .qwen35397b() // (fallback 5) OpenRouter qwen/qwen3.5-397b-a17b
18
18
  .qwen3827b() // (fallback 6) OpenRouter qwen/qwen3.8-27b
19
- .GLM53() // (fallback 7) OpenRouter z-ai/glm-5.3
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
19
+ .qwen38flash() // (fallback 7) OpenRouter qwen/qwen3.8-flash
20
+ .GLM53() // (fallback 8) OpenRouter z-ai/glm-5.3
21
+ .GLM53Flash() // (fallback 9) OpenRouter z-ai/glm-5.3-flash
22
+ .museGlimmer30b({ mix: { fireworks: false, openrouter: true } }) // (fallback 10) OpenRouter meta/muse-glimmer-30b
23
+ .hermes470b() // (fallback 11) OpenRouter nousresearch/hermes-4-70b
24
+ .hermes4405b() // (fallback 12) OpenRouter nousresearch/hermes-4-405b
23
25
  .addText("What's your name?");
24
26
 
25
27
  console.log(await mmix.message());
package/effort.js CHANGED
@@ -50,7 +50,9 @@ const OPENAI_MODEL_LEVELS = {
50
50
  'meta-models/Muse-Glimmer-30B': ['low', 'medium', 'high', 'xhigh'],
51
51
  'accounts/fireworks/models/qwen3p8-2p4t-a95b': ['none', 'low', 'medium', 'high'],
52
52
  'qwen/qwen3.8-27b': ['low', 'medium', 'xhigh'],
53
+ 'qwen/qwen3.8-flash': ['low', 'medium', 'xhigh'],
53
54
  'z-ai/glm-5.3': ['low', 'high', 'max'],
55
+ 'z-ai/glm-5.3-flash': ['low', 'high', 'max'],
54
56
  'grok-4.6': ['low', 'medium', 'high', 'xhigh'],
55
57
  'gpt-5': ['minimal', 'low', 'medium', 'high'],
56
58
  'gpt-5-mini': ['minimal', 'low', 'medium', 'high'],
@@ -396,7 +398,7 @@ function mapEffort(providerFamily, effort, modelKey) {
396
398
  return null;
397
399
  }
398
400
  const supported = supportedOpenAILevels(modelKey);
399
- const desired = modelKey === 'z-ai/glm-5.3'
401
+ const desired = modelKey === 'z-ai/glm-5.3' || modelKey === 'z-ai/glm-5.3-flash'
400
402
  ? levelFromBands(normalized, GLM53_BANDS)
401
403
  : normalized === 100 && supported.includes('max')
402
404
  ? 'max'
package/index.d.ts CHANGED
@@ -502,6 +502,7 @@ export declare class ModelMix {
502
502
  qwen37plus(args?: ModelAttachArgs): this;
503
503
  qwen38max(args?: ModelAttachArgs): this;
504
504
  qwen3827b(args?: ModelAttachArgs): this;
505
+ qwen38flash(args?: ModelAttachArgs): this;
505
506
  hermes470b(args?: ModelAttachArgs): this;
506
507
  hermes4405b(args?: ModelAttachArgs): this;
507
508
  hermes3(args?: ModelAttachArgs): this;
@@ -518,6 +519,7 @@ export declare class ModelMix {
518
519
  deepseekV4Flash(args?: ModelAttachArgs): this;
519
520
  GLM52(args?: ModelAttachArgs): this;
520
521
  GLM53(args?: ModelAttachArgs): this;
522
+ GLM53Flash(args?: ModelAttachArgs): this;
521
523
 
522
524
  addText(text: string, options?: RoleOptions): this;
523
525
  addTextFromFile(filePath: string, options?: RoleOptions): this;
package/index.js CHANGED
@@ -616,6 +616,10 @@ class ModelMix {
616
616
  return this.attach('qwen/qwen3.8-27b', new MixOpenRouter({ options, config }));
617
617
  }
618
618
 
619
+ qwen38flash({ options = {}, config = {} } = {}) {
620
+ return this.attach('qwen/qwen3.8-flash', new MixOpenRouter({ options, config }));
621
+ }
622
+
619
623
  hermes470b({ options = {}, config = {} } = {}) {
620
624
  return this.attach('nousresearch/hermes-4-70b', new MixOpenRouter({ options, config }));
621
625
  }
@@ -732,6 +736,10 @@ class ModelMix {
732
736
  return this.attach('z-ai/glm-5.3', new MixOpenRouter({ options, config }));
733
737
  }
734
738
 
739
+ GLM53Flash({ options = {}, config = {} } = {}) {
740
+ return this.attach('z-ai/glm-5.3-flash', new MixOpenRouter({ options, config }));
741
+ }
742
+
735
743
  addText(text, { role = "user", cache } = {}) {
736
744
  return this._addText(text, {
737
745
  role,
@@ -11,11 +11,11 @@ const CHAIN_MODEL_SHORTCUTS = new Set([
11
11
  'gemini35flashLite', 'gemini31flashLite', 'sonarPro', 'sonar',
12
12
  'grok46', 'grok45', 'grok43', 'grok420multiAgent', 'grok420',
13
13
  'museGlimmer30b',
14
- 'qwen35397b', 'qwen36plus', 'qwen37plus', 'qwen38max', 'qwen3827b',
14
+ 'qwen35397b', 'qwen36plus', 'qwen37plus', 'qwen38max', 'qwen3827b', 'qwen38flash',
15
15
  'hermes470b', 'hermes4405b', 'hermes3',
16
16
  'kimiK26', 'kimiK27Code', 'kimiK3', 'kimiK25',
17
17
  'minimaxM27', 'minimaxM3', 'mimo25', 'mimo25pro',
18
- 'deepseekV4Pro', 'deepseekV4Flash', 'GLM52', 'GLM53'
18
+ 'deepseekV4Pro', 'deepseekV4Flash', 'GLM52', 'GLM53', 'GLM53Flash'
19
19
  ]);
20
20
 
21
21
  function parseChainModels(modelSpecs) {
@@ -91,6 +91,7 @@ const MODEL_PRICING = {
91
91
  'accounts/fireworks/models/glm-5p2': { input: 1.40, cachedInput: 0.14, output: 4.40 },
92
92
  'z-ai/glm-5.2': { input: 0.966, cachedInput: 0.1932, output: 3.036 },
93
93
  'z-ai/glm-5.3': { input: 1.40, cachedInput: 0.26, output: 4.40 },
94
+ 'z-ai/glm-5.3-flash': { input: 0.075, cachedInput: 0.015, output: 0.25 },
94
95
  'accounts/fireworks/models/kimi-k2p5': { input: 0.50, output: 2.80 },
95
96
  'qwen/qwen3.5-397b-a17b': { input: 0.385, output: 2.45 },
96
97
  'accounts/fireworks/models/qwen3p6-plus': { input: 0.50, output: 3.00 },
@@ -113,6 +114,7 @@ const MODEL_PRICING = {
113
114
  'accounts/fireworks/models/qwen3p8-2p4t-a95b': { input: 2.00, cachedInput: 0.25, output: 6.00 },
114
115
  'qwen/qwen3.8-max': { input: 2.00, output: 6.00 },
115
116
  'qwen/qwen3.8-27b': { input: 0.45, cachedInput: 0.05, output: 3.20 },
117
+ 'qwen/qwen3.8-flash': { input: 0.16, cachedInput: 0.016, cacheWrite: 0.20, output: 0.47 },
116
118
  // MiniMax
117
119
  'MiniMax-M2.5': { input: 0.30, output: 1.20 },
118
120
  'MiniMax-M2.7': { input: 0.30, output: 1.20 },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "modelmix",
3
- "version": "5.1.8",
3
+ "version": "5.1.10",
4
4
  "description": "🧬 Reliable interface with automatic fallback for AI LLMs.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -143,7 +143,7 @@ ModelMix.new({ config: { effort: 80 } })
143
143
  | DeepSeek V4 | off | `low`↑ | `high`↑ | `high`↑ | `max`↑ | — |
144
144
  | MiniMax M3 | off | adaptive | adaptive | adaptive | adaptive | adaptive |
145
145
 
146
- \* GPT-5.6 maps `100` to `max`; 80–99 remains `xhigh`. Qwen 3.8 27B maps 0–39 / 40–79 / 80–100 to `low` / `medium` / `xhigh`. GLM 5.3 requires reasoning and maps those bands to `low` / `high` / `max`. Gemini bands: 0–24 / 25–49 / 50–74 / 75–100. Gemini 3.7 Flash supports only `low` / `medium` / `high`, so the first two bands clamp to `low`; `-1` keeps its native `medium` default. DeepSeek `↑` = thinking on; `off` = thinking disabled. MiniMax `off`/`adaptive` = `thinking.disabled` / `thinking.type=adaptive`. Gemini 2.5 maps 0–100 to `thinkingBudget`. Anthropic: adaptive + `output_config.effort` on Claude 5 / Fable / Opus 4.6+ / Sonnet 4.6+; Sonnet 4.5 / Haiku 4.5 use `thinking.type=enabled` + `budget_tokens`. Grok 4.6 maps 0–39 / 40–59 / 60–79 / 80–100 to `low` / `medium` / `high` / `xhigh`; without effort it uses native `high`. `-1` = adaptive/dynamic when available, else no-op. Levels clamp per model. Former `*think()` methods are removed — use `.effort(n).<model>()`. Kimi: `kimiK25()` / `kimiK26()`. Grok 4.20: `.grok420()` non-reasoning; `.effort(20+|-1).grok420()` selects reasoning.
146
+ \* GPT-5.6 maps `100` to `max`; 80–99 remains `xhigh`. Qwen 3.8 27B and Flash map 0–39 / 40–79 / 80–100 to `low` / `medium` / `xhigh`; Qwen 3.8 Flash is the managed production version based on Flash-Next. GLM 5.3 and GLM 5.3 Flash require reasoning and map those bands to `low` / `high` / `max`. Gemini bands: 0–24 / 25–49 / 50–74 / 75–100. Gemini 3.7 Flash supports only `low` / `medium` / `high`, so the first two bands clamp to `low`; `-1` keeps its native `medium` default. DeepSeek `↑` = thinking on; `off` = thinking disabled. MiniMax `off`/`adaptive` = `thinking.disabled` / `thinking.type=adaptive`. Gemini 2.5 maps 0–100 to `thinkingBudget`. Anthropic: adaptive + `output_config.effort` on Claude 5 / Fable / Opus 4.6+ / Sonnet 4.6+; Sonnet 4.5 / Haiku 4.5 use `thinking.type=enabled` + `budget_tokens`. Grok 4.6 maps 0–39 / 40–59 / 60–79 / 80–100 to `low` / `medium` / `high` / `xhigh`; without effort it uses native `high`. `-1` = adaptive/dynamic when available, else no-op. Levels clamp per model. Former `*think()` methods are removed — use `.effort(n).<model>()`. Kimi: `kimiK25()` / `kimiK26()`. Grok 4.20: `.grok420()` non-reasoning; `.effort(20+|-1).grok420()` selects reasoning.
147
147
 
148
148
  ## Available Model Shorthands
149
149
 
@@ -186,7 +186,7 @@ Use `.effort(n)` (or `config.effort`) to enable Anthropic thinking — e.g. `.ef
186
186
  `GLM46()`
187
187
 
188
188
  ### OpenRouter
189
- `museGlimmer30b()` `gptOss()` `qwen35397b()` `qwen36plus()` `qwen37plus()` `qwen3827b()` `hermes470b()` `hermes4405b()` `qwen38max()` `kimiK27Code()` `kimiK3()` `minimaxM27()` `minimaxM3()` `GLM45()` `GLM52()` `GLM53()`
189
+ `museGlimmer30b()` `gptOss()` `qwen35397b()` `qwen36plus()` `qwen37plus()` `qwen3827b()` `qwen38flash()` `hermes470b()` `hermes4405b()` `qwen38max()` `kimiK27Code()` `kimiK3()` `minimaxM27()` `minimaxM3()` `GLM45()` `GLM52()` `GLM53()` `GLM53Flash()`
190
190
 
191
191
  ### Multi-provider (auto-fallback across free/paid tiers)
192
192
  `hermes3()` `kimiK25()`
@@ -140,6 +140,14 @@ describe('Unified effort scale', () => {
140
140
  expect(mapEffort('openai', -1, key)).to.equal(null);
141
141
  });
142
142
 
143
+ it('maps Qwen 3.8 Flash to its supported reasoning levels', () => {
144
+ const key = 'qwen/qwen3.8-flash';
145
+ expect(mapEffort('openai', 0, key)).to.deep.equal({ reasoning_effort: 'low' });
146
+ expect(mapEffort('openai', 50, key)).to.deep.equal({ reasoning_effort: 'medium' });
147
+ expect(mapEffort('openai', 100, key)).to.deep.equal({ reasoning_effort: 'xhigh' });
148
+ expect(mapEffort('openai', -1, key)).to.equal(null);
149
+ });
150
+
143
151
  it('maps GLM 5.3 to mandatory low, high, and max reasoning', () => {
144
152
  const key = 'z-ai/glm-5.3';
145
153
  expect(mapEffort('openai', 39, key)).to.deep.equal({ reasoning_effort: 'low' });
@@ -149,6 +157,15 @@ describe('Unified effort scale', () => {
149
157
  expect(mapEffort('openai', -1, key)).to.equal(null);
150
158
  });
151
159
 
160
+ it('maps GLM 5.3 Flash to mandatory low, high, and max reasoning', () => {
161
+ const key = 'z-ai/glm-5.3-flash';
162
+ expect(mapEffort('openai', 39, key)).to.deep.equal({ reasoning_effort: 'low' });
163
+ expect(mapEffort('openai', 40, key)).to.deep.equal({ reasoning_effort: 'high' });
164
+ expect(mapEffort('openai', 79, key)).to.deep.equal({ reasoning_effort: 'high' });
165
+ expect(mapEffort('openai', 80, key)).to.deep.equal({ reasoning_effort: 'max' });
166
+ expect(mapEffort('openai', -1, key)).to.equal(null);
167
+ });
168
+
152
169
  it('maps Anthropic adaptive models to thinking + output_config.effort', () => {
153
170
  expect(mapEffort('anthropic', 10, 'claude-opus-5')).to.deep.equal({
154
171
  thinking: { type: 'adaptive', display: 'summarized' },
package/test/glm.test.js CHANGED
@@ -53,4 +53,24 @@ describe('GLM Model Registration Tests', () => {
53
53
  expect(model.models).to.have.length(1);
54
54
  expect(model.models[0].key).to.equal('z-ai/glm-5.3');
55
55
  });
56
+
57
+ it('should register GLM 5.3 Flash through OpenRouter', () => {
58
+ const model = ModelMix.new().GLM53Flash();
59
+
60
+ expect(model.models).to.have.length(1);
61
+ expect(model.models[0].key).to.equal('z-ai/glm-5.3-flash');
62
+ expect(model.models[0].provider).to.be.instanceOf(MixOpenRouter);
63
+ expect(ModelMix.calculateCost('z-ai/glm-5.3-flash', {
64
+ input: 1_000_000,
65
+ cached: 500_000,
66
+ output: 1_000_000
67
+ })).to.equal(0.295);
68
+ });
69
+
70
+ it('should support GLM 5.3 Flash in chain()', () => {
71
+ const model = ModelMix.new().chain('GLM53Flash');
72
+
73
+ expect(model.models).to.have.length(1);
74
+ expect(model.models[0].key).to.equal('z-ai/glm-5.3-flash');
75
+ });
56
76
  });
package/test/qwen.test.js CHANGED
@@ -110,6 +110,27 @@ describe('Qwen Model Registration Tests', () => {
110
110
  expect(model.models[0].key).to.equal('qwen/qwen3.8-27b');
111
111
  });
112
112
 
113
+ it('should register Qwen 3.8 Flash through OpenRouter', () => {
114
+ const model = ModelMix.new().qwen38flash();
115
+
116
+ expect(model.models).to.have.length(1);
117
+ expect(model.models[0].key).to.equal('qwen/qwen3.8-flash');
118
+ expect(model.models[0].provider).to.be.instanceOf(MixOpenRouter);
119
+ expect(ModelMix.calculateCost('qwen/qwen3.8-flash', {
120
+ input: 1_000_000,
121
+ cached: 250_000,
122
+ cacheWrite: 100_000,
123
+ output: 1_000_000
124
+ })).to.equal(0.598);
125
+ });
126
+
127
+ it('should support Qwen 3.8 Flash in chain()', () => {
128
+ const model = ModelMix.new().chain('qwen38flash');
129
+
130
+ expect(model.models).to.have.length(1);
131
+ expect(model.models[0].key).to.equal('qwen/qwen3.8-flash');
132
+ });
133
+
113
134
  it('should register Qwen 3.5 397B A17B through OpenRouter', () => {
114
135
  const model = ModelMix.new().qwen35397b();
115
136