modelmix 5.1.2 → 5.1.4
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 +6 -0
- package/demo/short.js +4 -2
- package/effort.js +13 -3
- package/index.d.ts +2 -0
- package/index.js +8 -0
- package/lib/model-chain.js +2 -2
- package/lib/token-usage.js +2 -0
- package/package.json +1 -1
- package/skills/modelmix/SKILL.md +2 -2
- package/test/effort.test.js +17 -0
- package/test/glm.test.js +21 -1
- package/test/qwen.test.js +20 -0
package/README.md
CHANGED
|
@@ -175,8 +175,10 @@ ModelMix provides convenient shorthand methods for quickly accessing different A
|
|
|
175
175
|
| `qwen36plus()` | Fireworks | qwen3p6-plus | [\$0.50][10] | [\$3.00][10] |
|
|
176
176
|
| `qwen37plus()` | Fireworks | models/qwen3p7-plus | [\$0.40][10] | [\$1.60][10] |
|
|
177
177
|
| `qwen38max()` | Fireworks | qwen3p8-2p4t-a95b | [\$2.00][10] | [\$6.00][10] |
|
|
178
|
+
| `qwen3827b()` | OpenRouter | qwen/qwen3.8-27b | [\$0.45][15] | [\$3.20][15] |
|
|
178
179
|
| `deepseekV4Flash()` | Fireworks | models/deepseek-v4-flash | [\$0.14][10] | [\$0.28][10] |
|
|
179
180
|
| `deepseekV4Pro()` | Fireworks | models/deepseek-v4-pro-0813 | [\$1.32][12] | [\$3.96][12] |
|
|
181
|
+
| `GLM53()` | OpenRouter | z-ai/glm-5.3 | [\$1.40][16] | [\$4.40][16] |
|
|
180
182
|
| `GLM52()` | Together | zai-org/GLM-5.2 | [\$1.40][7] | [\$4.40][7] |
|
|
181
183
|
| `GLM51()` | Fireworks | models/glm-5p1 | [\$1.05][10] | [\$3.50][10] |
|
|
182
184
|
| `minimaxM3()` | MiniMax | MiniMax-M3 | [\$0.30][9] | [\$1.20][9] |
|
|
@@ -206,6 +208,8 @@ Gemini 3.7 Flash and 3.6 Flash use Google's introductory standard pricing throug
|
|
|
206
208
|
[12]: https://fireworks.ai/models/deepseek-ai/deepseek-v4-pro-0813 "DeepSeek V4 Pro 0813 Pricing"
|
|
207
209
|
[13]: https://openrouter.ai/nousresearch "Nous Research Models on OpenRouter"
|
|
208
210
|
[14]: https://openrouter.ai/qwen/qwen3.5-397b-a17b "Qwen3.5 397B A17B on OpenRouter"
|
|
211
|
+
[15]: https://openrouter.ai/qwen/qwen3.8-27b "Qwen3.8 27B on OpenRouter"
|
|
212
|
+
[16]: https://openrouter.ai/z-ai/glm-5.3 "GLM 5.3 on OpenRouter"
|
|
209
213
|
|
|
210
214
|
Each method accepts optional `options`, `config`, and (for multi-provider methods) `mix` parameters to customize behavior.
|
|
211
215
|
|
|
@@ -246,6 +250,8 @@ ModelMix.new().effort(-1).minimaxM3().addText('...').message();
|
|
|
246
250
|
|
|
247
251
|
- **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`.
|
|
248
252
|
- **GPT-5.6:** `100` maps to `max`; 80–99 remains `xhigh`.
|
|
253
|
+
- **Qwen 3.8 27B:** 0–39 / 40–79 / 80–100 map to `low` / `medium` / `xhigh`; `-1` leaves the native `xhigh` default unchanged.
|
|
254
|
+
- **GLM 5.3:** reasoning is mandatory; 0–39 / 40–79 / 80–100 map to `low` / `high` / `max`; `-1` leaves the native `max` default unchanged.
|
|
249
255
|
- **DeepSeek:** `↑` means thinking is enabled; `off` means it is disabled.
|
|
250
256
|
- **MiniMax:** `off` maps to `thinking.disabled`; `adaptive` maps to `thinking.type=adaptive`.
|
|
251
257
|
- **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
|
@@ -15,8 +15,10 @@ const mmix = await ModelMix.new(setup)
|
|
|
15
15
|
.gpt5nano() // (fallback 3) OpenAI gpt-5-nano
|
|
16
16
|
.grok46() // (fallback 4) Grok grok-4.6
|
|
17
17
|
.qwen35397b() // (fallback 5) OpenRouter qwen/qwen3.5-397b-a17b
|
|
18
|
-
.
|
|
19
|
-
.
|
|
18
|
+
.qwen3827b() // (fallback 6) OpenRouter qwen/qwen3.8-27b
|
|
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
22
|
.addText("What's your name?");
|
|
21
23
|
|
|
22
24
|
console.log(await mmix.message());
|
package/effort.js
CHANGED
|
@@ -34,12 +34,20 @@ const GEMINI_BANDS = [
|
|
|
34
34
|
[75, 100, 'high'],
|
|
35
35
|
];
|
|
36
36
|
|
|
37
|
+
const GLM53_BANDS = [
|
|
38
|
+
[0, 39, 'low'],
|
|
39
|
+
[40, 79, 'high'],
|
|
40
|
+
[80, 100, 'max'],
|
|
41
|
+
];
|
|
42
|
+
|
|
37
43
|
/** Exact model → supported OpenAI reasoning_effort values */
|
|
38
44
|
const OPENAI_MODEL_LEVELS = {
|
|
39
45
|
'gpt-5.6-sol': ['none', 'low', 'medium', 'high', 'xhigh', 'max'],
|
|
40
46
|
'gpt-5.6-terra': ['none', 'low', 'medium', 'high', 'xhigh', 'max'],
|
|
41
47
|
'gpt-5.6-luna': ['none', 'low', 'medium', 'high', 'xhigh', 'max'],
|
|
42
48
|
'accounts/fireworks/models/qwen3p8-2p4t-a95b': ['none', 'low', 'medium', 'high'],
|
|
49
|
+
'qwen/qwen3.8-27b': ['low', 'medium', 'xhigh'],
|
|
50
|
+
'z-ai/glm-5.3': ['low', 'high', 'max'],
|
|
43
51
|
'grok-4.6': ['low', 'medium', 'high', 'xhigh'],
|
|
44
52
|
'gpt-5': ['minimal', 'low', 'medium', 'high'],
|
|
45
53
|
'gpt-5-mini': ['minimal', 'low', 'medium', 'high'],
|
|
@@ -377,9 +385,11 @@ function mapEffort(providerFamily, effort, modelKey) {
|
|
|
377
385
|
return null;
|
|
378
386
|
}
|
|
379
387
|
const supported = supportedOpenAILevels(modelKey);
|
|
380
|
-
const desired =
|
|
381
|
-
?
|
|
382
|
-
:
|
|
388
|
+
const desired = modelKey === 'z-ai/glm-5.3'
|
|
389
|
+
? levelFromBands(normalized, GLM53_BANDS)
|
|
390
|
+
: normalized === 100 && supported.includes('max')
|
|
391
|
+
? 'max'
|
|
392
|
+
: levelFromBands(normalized, OPENAI_BANDS);
|
|
383
393
|
const level = pickNearestLevel(desired, OPENAI_LEVEL_LADDER, supported);
|
|
384
394
|
return { reasoning_effort: level };
|
|
385
395
|
}
|
package/index.d.ts
CHANGED
|
@@ -501,6 +501,7 @@ export declare class ModelMix {
|
|
|
501
501
|
qwen36plus(args?: ModelAttachArgs): this;
|
|
502
502
|
qwen37plus(args?: ModelAttachArgs): this;
|
|
503
503
|
qwen38max(args?: ModelAttachArgs): this;
|
|
504
|
+
qwen3827b(args?: ModelAttachArgs): this;
|
|
504
505
|
hermes470b(args?: ModelAttachArgs): this;
|
|
505
506
|
hermes4405b(args?: ModelAttachArgs): this;
|
|
506
507
|
hermes3(args?: ModelAttachArgs): this;
|
|
@@ -517,6 +518,7 @@ export declare class ModelMix {
|
|
|
517
518
|
deepseekV4Flash(args?: ModelAttachArgs): this;
|
|
518
519
|
GLM51(args?: ModelAttachArgs): this;
|
|
519
520
|
GLM52(args?: ModelAttachArgs): this;
|
|
521
|
+
GLM53(args?: ModelAttachArgs): this;
|
|
520
522
|
|
|
521
523
|
addText(text: string, options?: RoleOptions): this;
|
|
522
524
|
addTextFromFile(filePath: string, options?: RoleOptions): this;
|
package/index.js
CHANGED
|
@@ -605,6 +605,10 @@ class ModelMix {
|
|
|
605
605
|
return this;
|
|
606
606
|
}
|
|
607
607
|
|
|
608
|
+
qwen3827b({ options = {}, config = {} } = {}) {
|
|
609
|
+
return this.attach('qwen/qwen3.8-27b', new MixOpenRouter({ options, config }));
|
|
610
|
+
}
|
|
611
|
+
|
|
608
612
|
hermes470b({ options = {}, config = {} } = {}) {
|
|
609
613
|
return this.attach('nousresearch/hermes-4-70b', new MixOpenRouter({ options, config }));
|
|
610
614
|
}
|
|
@@ -718,6 +722,10 @@ class ModelMix {
|
|
|
718
722
|
return this;
|
|
719
723
|
}
|
|
720
724
|
|
|
725
|
+
GLM53({ options = {}, config = {} } = {}) {
|
|
726
|
+
return this.attach('z-ai/glm-5.3', new MixOpenRouter({ options, config }));
|
|
727
|
+
}
|
|
728
|
+
|
|
721
729
|
addText(text, { role = "user", cache } = {}) {
|
|
722
730
|
return this._addText(text, {
|
|
723
731
|
role,
|
package/lib/model-chain.js
CHANGED
|
@@ -10,11 +10,11 @@ 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',
|
|
13
|
+
'qwen3', 'qwen35397b', 'qwen36plus', 'qwen37plus', 'qwen38max', 'qwen3827b',
|
|
14
14
|
'hermes470b', 'hermes4405b', 'hermes3',
|
|
15
15
|
'kimiK26', 'kimiK27Code', 'kimiK3', 'kimiK25',
|
|
16
16
|
'minimaxM27', 'minimaxM3', 'mimo25', 'mimo25pro',
|
|
17
|
-
'deepseekV4Pro', 'deepseekV4Flash', 'GLM51', 'GLM52'
|
|
17
|
+
'deepseekV4Pro', 'deepseekV4Flash', 'GLM51', 'GLM52', 'GLM53'
|
|
18
18
|
]);
|
|
19
19
|
|
|
20
20
|
function parseChainModels(modelSpecs) {
|
package/lib/token-usage.js
CHANGED
|
@@ -84,6 +84,7 @@ const MODEL_PRICING = {
|
|
|
84
84
|
'accounts/fireworks/models/glm-4p7': { input: 0.55, output: 2.19 },
|
|
85
85
|
'accounts/fireworks/models/glm-5p1': { input: 1.05, output: 3.50 },
|
|
86
86
|
'zai-org/GLM-5.2': { input: 1.40, output: 4.40 },
|
|
87
|
+
'z-ai/glm-5.3': { input: 1.40, cachedInput: 0.26, output: 4.40 },
|
|
87
88
|
'accounts/fireworks/models/kimi-k2p5': { input: 0.50, output: 2.80 },
|
|
88
89
|
'qwen/qwen3.5-397b-a17b': { input: 0.385, output: 2.45 },
|
|
89
90
|
'accounts/fireworks/models/qwen3p6-plus': { input: 0.50, output: 3.00 },
|
|
@@ -92,6 +93,7 @@ const MODEL_PRICING = {
|
|
|
92
93
|
'qwen/qwen3.7-plus': { input: 0.32, output: 1.28 },
|
|
93
94
|
'accounts/fireworks/models/qwen3p8-2p4t-a95b': { input: 2.00, cachedInput: 0.25, output: 6.00 },
|
|
94
95
|
'qwen/qwen3.8-max': { input: 2.00, output: 6.00 },
|
|
96
|
+
'qwen/qwen3.8-27b': { input: 0.45, cachedInput: 0.05, output: 3.20 },
|
|
95
97
|
// MiniMax
|
|
96
98
|
'MiniMax-M2.5': { input: 0.30, output: 1.20 },
|
|
97
99
|
'MiniMax-M2.7': { input: 0.30, output: 1.20 },
|
package/package.json
CHANGED
package/skills/modelmix/SKILL.md
CHANGED
|
@@ -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`. 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 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.
|
|
147
147
|
|
|
148
148
|
## Available Model Shorthands
|
|
149
149
|
|
|
@@ -183,7 +183,7 @@ Use `.effort(n)` (or `config.effort`) to enable Anthropic thinking — e.g. `.ef
|
|
|
183
183
|
`GLM46()`
|
|
184
184
|
|
|
185
185
|
### OpenRouter
|
|
186
|
-
`qwen35397b()` `hermes470b()` `hermes4405b()` `qwen38max()` `GLM45()`
|
|
186
|
+
`qwen35397b()` `qwen3827b()` `hermes470b()` `hermes4405b()` `qwen38max()` `GLM45()` `GLM53()`
|
|
187
187
|
|
|
188
188
|
### Multi-provider (auto-fallback across free/paid tiers)
|
|
189
189
|
`hermes3()` `kimiK25()`
|
package/test/effort.test.js
CHANGED
|
@@ -96,6 +96,23 @@ describe('Unified effort scale', () => {
|
|
|
96
96
|
expect(mapEffort('openai', 100, key)).to.deep.equal({ reasoning_effort: 'high' });
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
+
it('maps Qwen 3.8 27B to its supported reasoning levels', () => {
|
|
100
|
+
const key = 'qwen/qwen3.8-27b';
|
|
101
|
+
expect(mapEffort('openai', 0, key)).to.deep.equal({ reasoning_effort: 'low' });
|
|
102
|
+
expect(mapEffort('openai', 50, key)).to.deep.equal({ reasoning_effort: 'medium' });
|
|
103
|
+
expect(mapEffort('openai', 100, key)).to.deep.equal({ reasoning_effort: 'xhigh' });
|
|
104
|
+
expect(mapEffort('openai', -1, key)).to.equal(null);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('maps GLM 5.3 to mandatory low, high, and max reasoning', () => {
|
|
108
|
+
const key = 'z-ai/glm-5.3';
|
|
109
|
+
expect(mapEffort('openai', 39, key)).to.deep.equal({ reasoning_effort: 'low' });
|
|
110
|
+
expect(mapEffort('openai', 40, key)).to.deep.equal({ reasoning_effort: 'high' });
|
|
111
|
+
expect(mapEffort('openai', 79, key)).to.deep.equal({ reasoning_effort: 'high' });
|
|
112
|
+
expect(mapEffort('openai', 80, key)).to.deep.equal({ reasoning_effort: 'max' });
|
|
113
|
+
expect(mapEffort('openai', -1, key)).to.equal(null);
|
|
114
|
+
});
|
|
115
|
+
|
|
99
116
|
it('maps Anthropic adaptive models to thinking + output_config.effort', () => {
|
|
100
117
|
expect(mapEffort('anthropic', 10, 'claude-opus-5')).to.deep.equal({
|
|
101
118
|
thinking: { type: 'adaptive', display: 'summarized' },
|
package/test/glm.test.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { expect } = require('chai');
|
|
2
|
-
const { ModelMix } = require('../index.js');
|
|
2
|
+
const { ModelMix, MixOpenRouter } = require('../index.js');
|
|
3
3
|
|
|
4
4
|
describe('GLM Model Registration Tests', () => {
|
|
5
5
|
it('should register Together GLM 5.2 by default', () => {
|
|
@@ -9,4 +9,24 @@ describe('GLM Model Registration Tests', () => {
|
|
|
9
9
|
expect(model.models).to.have.length(1);
|
|
10
10
|
expect(model.models[0].key).to.equal('zai-org/GLM-5.2');
|
|
11
11
|
});
|
|
12
|
+
|
|
13
|
+
it('should register GLM 5.3 through OpenRouter', () => {
|
|
14
|
+
const model = ModelMix.new().GLM53();
|
|
15
|
+
|
|
16
|
+
expect(model.models).to.have.length(1);
|
|
17
|
+
expect(model.models[0].key).to.equal('z-ai/glm-5.3');
|
|
18
|
+
expect(model.models[0].provider).to.be.instanceOf(MixOpenRouter);
|
|
19
|
+
expect(ModelMix.calculateCost('z-ai/glm-5.3', {
|
|
20
|
+
input: 1_000_000,
|
|
21
|
+
cached: 500_000,
|
|
22
|
+
output: 1_000_000
|
|
23
|
+
})).to.equal(5.23);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should support GLM 5.3 in chain()', () => {
|
|
27
|
+
const model = ModelMix.new().chain('GLM53');
|
|
28
|
+
|
|
29
|
+
expect(model.models).to.have.length(1);
|
|
30
|
+
expect(model.models[0].key).to.equal('z-ai/glm-5.3');
|
|
31
|
+
});
|
|
12
32
|
});
|
package/test/qwen.test.js
CHANGED
|
@@ -61,6 +61,26 @@ describe('Qwen Model Registration Tests', () => {
|
|
|
61
61
|
expect(model.models[0].key).to.equal('qwen/qwen3.8-max');
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
+
it('should register Qwen 3.8 27B through OpenRouter', () => {
|
|
65
|
+
const model = ModelMix.new().qwen3827b();
|
|
66
|
+
|
|
67
|
+
expect(model.models).to.have.length(1);
|
|
68
|
+
expect(model.models[0].key).to.equal('qwen/qwen3.8-27b');
|
|
69
|
+
expect(model.models[0].provider).to.be.instanceOf(MixOpenRouter);
|
|
70
|
+
expect(ModelMix.calculateCost('qwen/qwen3.8-27b', {
|
|
71
|
+
input: 1_000_000,
|
|
72
|
+
cached: 250_000,
|
|
73
|
+
output: 1_000_000
|
|
74
|
+
})).to.equal(3.55);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should support Qwen 3.8 27B in chain()', () => {
|
|
78
|
+
const model = ModelMix.new().chain('qwen3827b');
|
|
79
|
+
|
|
80
|
+
expect(model.models).to.have.length(1);
|
|
81
|
+
expect(model.models[0].key).to.equal('qwen/qwen3.8-27b');
|
|
82
|
+
});
|
|
83
|
+
|
|
64
84
|
it('should register Qwen 3.5 397B A17B through OpenRouter', () => {
|
|
65
85
|
const model = ModelMix.new().qwen35397b();
|
|
66
86
|
|