modelmix 4.5.26 → 4.5.28

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
@@ -136,6 +136,7 @@ Here's a comprehensive list of available methods:
136
136
 
137
137
  | Method | Provider | Model | Price (I/O) per 1 M tokens |
138
138
  | ------------------- | ---------- | ---------------------------- | -------------------------- |
139
+ | `gpt55()` | OpenAI | gpt-5.5 | [\$5.00 / \$30.00][1] |
139
140
  | `gpt54()` | OpenAI | gpt-5.4 | [\$2.50 / \$15.00][1] |
140
141
  | `gpt54mini()` | OpenAI | gpt-5.4-mini | [\$0.75 / \$4.50][1] |
141
142
  | `gpt54nano()` | OpenAI | gpt-5.4-nano | [\$0.20 / \$1.25][1] |
@@ -148,8 +149,10 @@ Here's a comprehensive list of available methods:
148
149
  | `gpt41mini()` | OpenAI | gpt-4.1-mini | [\$0.40 / \$1.60][1] |
149
150
  | `gpt41nano()` | OpenAI | gpt-4.1-nano | [\$0.10 / \$0.40][1] |
150
151
  | `gptOss()` | Together | gpt-oss-120B | [\$0.15 / \$0.60][7] |
152
+ | `opus48[think]()` | Anthropic | claude-opus-4-8 | [\$5.00 / \$25.00][2] |
151
153
  | `opus47[think]()` | Anthropic | claude-opus-4-7 | [\$5.00 / \$25.00][2] |
152
154
  | `opus46[think]()` | Anthropic | claude-opus-4-6 | [\$5.00 / \$25.00][2] |
155
+ | `sonnet5[think]()` | Anthropic | claude-sonnet-5 | [\$3.00 / \$15.00][2] |
153
156
  | `sonnet46[think]()` | Anthropic | claude-sonnet-4-6 | [\$3.00 / \$15.00][2] |
154
157
  | `haiku45[think]()` | Anthropic | claude-haiku-4-5-20251001 | [\$1.00 / \$5.00][2] |
155
158
  | `gemini31pro()` | Google | gemini-3.1-pro-preview | [\$2.00 / \$12.00][3] |
package/index.js CHANGED
@@ -58,9 +58,10 @@ const MODEL_PRICING = {
58
58
  'gpt-oss-120b': [0.15, 0.60],
59
59
  'openai/gpt-oss-120b:free': [0, 0],
60
60
  // Anthropic
61
+ 'claude-sonnet-5': [3.00, 15.00],
62
+ 'claude-opus-4-8': [5.00, 25.00],
61
63
  'claude-opus-4-7': [5.00, 25.00],
62
64
  'claude-opus-4-6': [5.00, 25.00],
63
- 'claude-opus-4-5-20251101': [5.00, 25.00],
64
65
  'claude-opus-4-1-20250805': [15.00, 75.00],
65
66
  'claude-sonnet-4-6': [3.00, 15.00],
66
67
  'claude-sonnet-4-5-20250929': [3.00, 15.00],
@@ -344,6 +345,10 @@ class ModelMix {
344
345
  if (mix.openrouter) this.attach('openai/gpt-oss-120b:free', new MixOpenRouter({ options, config }));
345
346
  return this;
346
347
  }
348
+ opus48think({ options = {}, config = {} } = {}) {
349
+ options = { ...MixAnthropic.thinkingOptions, ...options };
350
+ return this.attach('claude-opus-4-8', new MixAnthropic({ options, config }));
351
+ }
347
352
  opus47think({ options = {}, config = {} } = {}) {
348
353
  options = { ...MixAnthropic.thinkingOptions, ...options };
349
354
  return this.attach('claude-opus-4-7', new MixAnthropic({ options, config }));
@@ -352,9 +357,8 @@ class ModelMix {
352
357
  options = { ...MixAnthropic.thinkingOptions, ...options };
353
358
  return this.attach('claude-opus-4-6', new MixAnthropic({ options, config }));
354
359
  }
355
- opus45think({ options = {}, config = {} } = {}) {
356
- options = { ...MixAnthropic.thinkingOptions, ...options };
357
- return this.attach('claude-opus-4-5-20251101', new MixAnthropic({ options, config }));
360
+ opus48({ options = {}, config = {} } = {}) {
361
+ return this.attach('claude-opus-4-8', new MixAnthropic({ options, config }));
358
362
  }
359
363
  opus47({ options = {}, config = {} } = {}) {
360
364
  return this.attach('claude-opus-4-7', new MixAnthropic({ options, config }));
@@ -362,9 +366,6 @@ class ModelMix {
362
366
  opus46({ options = {}, config = {} } = {}) {
363
367
  return this.attach('claude-opus-4-6', new MixAnthropic({ options, config }));
364
368
  }
365
- opus45({ options = {}, config = {} } = {}) {
366
- return this.attach('claude-opus-4-5-20251101', new MixAnthropic({ options, config }));
367
- }
368
369
  opus41({ options = {}, config = {} } = {}) {
369
370
  return this.attach('claude-opus-4-1-20250805', new MixAnthropic({ options, config }));
370
371
  }
@@ -372,6 +373,13 @@ class ModelMix {
372
373
  options = { ...MixAnthropic.thinkingOptions, ...options };
373
374
  return this.attach('claude-opus-4-1-20250805', new MixAnthropic({ options, config }));
374
375
  }
376
+ sonnet5({ options = {}, config = {} } = {}) {
377
+ return this.attach('claude-sonnet-5', new MixAnthropic({ options, config }));
378
+ }
379
+ sonnet5think({ options = {}, config = {} } = {}) {
380
+ options = { ...MixAnthropic.thinkingOptions, ...options };
381
+ return this.attach('claude-sonnet-5', new MixAnthropic({ options, config }));
382
+ }
375
383
  sonnet4({ options = {}, config = {} } = {}) {
376
384
  return this.attach('claude-sonnet-4-20250514', new MixAnthropic({ options, config }));
377
385
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "modelmix",
3
- "version": "4.5.26",
3
+ "version": "4.5.28",
4
4
  "description": "🧬 Reliable interface with automatic fallback for AI LLMs.",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -49,15 +49,15 @@
49
49
  "dependencies": {
50
50
  "@modelcontextprotocol/sdk": "^1.29.0",
51
51
  "bottleneck": "^2.19.5",
52
- "file-type": "^21.3.3",
53
- "lemonlog": "^1.2.0",
54
- "ws": "^8.20.1"
52
+ "file-type": "^21.3.4",
53
+ "lemonlog": "^1.2.2",
54
+ "ws": "^8.21.0"
55
55
  },
56
56
  "devDependencies": {
57
- "chai": "^5.2.1",
57
+ "chai": "^5.3.3",
58
58
  "mocha": "^11.7.5",
59
- "nock": "^14.0.9",
60
- "sinon": "^21.0.1"
59
+ "nock": "^14.0.15",
60
+ "sinon": "^21.1.2"
61
61
  },
62
62
  "scripts": {
63
63
  "test": "mocha test/**/*.js --timeout 10000 --require test/setup.js",
@@ -70,6 +70,6 @@
70
70
  "test:live": "mocha test/live.test.js --timeout 10000 --require test/setup.js",
71
71
  "test:live.mcp": "mocha test/live.mcp.js --timeout 60000 --require test/setup.js",
72
72
  "test:tokens": "mocha test/tokens.test.js --timeout 10000 --require test/setup.js",
73
- "test:offline": "mocha test/json.test.js test/fallback.test.js test/templates.test.js test/images.test.js test/bottleneck.test.js test/tokens.test.js test/history.test.js --timeout 10000 --require test/setup.js"
73
+ "test:offline": "mocha test/json.test.js test/fallback.test.js test/templates.test.js test/images.test.js test/bottleneck.test.js test/tokens.test.js test/history.test.js test/anthropic.test.js --timeout 10000 --require test/setup.js"
74
74
  }
75
75
  }
@@ -1,3 +1,7 @@
1
+ minimumReleaseAgeExclude:
2
+ - ws@8.21.0
3
+ - hono@4.12.25
4
+ - js-yaml@4.1.2
1
5
  overrides:
2
6
  diff: 8.0.4
3
7
  ip-address: 10.2.0
@@ -96,9 +96,9 @@ If `sonnet46` fails, it automatically tries `gpt52`, then `gemini3flash`.
96
96
  `gpt52()` `gpt52chat()` `gpt51()` `gpt5()` `gpt5mini()` `gpt5nano()` `gpt45()` `gpt41()` `gpt41mini()` `gpt41nano()` `o3()` `o4mini()`
97
97
 
98
98
  ### Anthropic
99
- `opus46()` `opus45()` `opus41()` `sonnet46()` `sonnet45()` `sonnet4()` `haiku45()` `haiku35()`
99
+ `opus48()` `opus47()` `opus46()` `opus41()` `sonnet5()` `sonnet46()` `sonnet45()` `sonnet4()` `haiku45()` `haiku35()`
100
100
 
101
- Thinking variants: append `think` — e.g. `opus46think()` `sonnet46think()` `sonnet45think()` `sonnet4think()` `opus45think()` `opus41think()` `haiku45think()`
101
+ Thinking variants: append `think` — e.g. `opus48think()` `opus47think()` `opus46think()` `sonnet5think()` `sonnet46think()` `sonnet45think()` `sonnet4think()` `opus41think()` `haiku45think()`
102
102
 
103
103
  ### Google
104
104
  `gemini3pro()` `gemini3flash()` `gemini35flash()` `gemini25pro()` `gemini25flash()`
@@ -0,0 +1,46 @@
1
+ const { expect } = require('chai');
2
+ const { ModelMix, MixAnthropic } = require('../index.js');
3
+
4
+ describe('Anthropic Model Registration Tests', () => {
5
+ it('should register Claude Opus 4.8', () => {
6
+ const model = ModelMix.new();
7
+ model.opus48();
8
+
9
+ expect(model.models).to.have.length(1);
10
+ expect(model.models[0].key).to.equal('claude-opus-4-8');
11
+ expect(model.models[0].provider).to.be.instanceOf(MixAnthropic);
12
+ });
13
+
14
+ it('should register Claude Opus 4.8 with thinking enabled', () => {
15
+ const model = ModelMix.new();
16
+ model.opus48think();
17
+
18
+ expect(model.models).to.have.length(1);
19
+ expect(model.models[0].key).to.equal('claude-opus-4-8');
20
+ expect(model.models[0].provider.options.thinking).to.deep.equal({
21
+ type: 'enabled',
22
+ budget_tokens: 1638
23
+ });
24
+ });
25
+
26
+ it('should register Claude Sonnet 5', () => {
27
+ const model = ModelMix.new();
28
+ model.sonnet5();
29
+
30
+ expect(model.models).to.have.length(1);
31
+ expect(model.models[0].key).to.equal('claude-sonnet-5');
32
+ expect(model.models[0].provider).to.be.instanceOf(MixAnthropic);
33
+ });
34
+
35
+ it('should register Claude Sonnet 5 with thinking enabled', () => {
36
+ const model = ModelMix.new();
37
+ model.sonnet5think();
38
+
39
+ expect(model.models).to.have.length(1);
40
+ expect(model.models[0].key).to.equal('claude-sonnet-5');
41
+ expect(model.models[0].provider.options.thinking).to.deep.equal({
42
+ type: 'enabled',
43
+ budget_tokens: 1638
44
+ });
45
+ });
46
+ });