modelmix 5.1.10 → 5.1.15
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 +42 -10
- package/demo/free.js +1 -3
- package/demo/short.js +15 -13
- package/effort.js +13 -7
- package/http-client.js +6 -6
- package/index.d.ts +13 -6
- package/index.js +204 -144
- package/lib/abort-signal.js +57 -0
- package/lib/model-chain.js +2 -2
- package/lib/provider-api-key.js +9 -0
- package/lib/providers/anthropic.js +24 -22
- package/lib/providers/base.js +21 -28
- package/lib/providers/google.js +12 -8
- package/lib/providers/openai-compatible.js +19 -48
- package/lib/providers/openai-options.js +16 -0
- package/lib/providers/openai.js +48 -47
- package/lib/providers.js +5 -2
- package/lib/token-usage.js +19 -4
- package/mcp-tools.js +5 -2
- package/package.json +3 -2
- package/plugins/rlm/index.d.ts +1 -0
- package/plugins/rlm/lib/budget.js +2 -7
- package/plugins/rlm/lib/isolated-vm-sandbox.js +8 -1
- package/plugins/rlm/lib/planner-prompt.js +1 -7
- package/plugins/rlm/lib/plugin.js +24 -11
- package/plugins/rlm/lib/validation.js +14 -0
- package/plugins/rlm/lib/variable-descriptors.js +1 -5
- package/plugins/rlm/lib/worker-catalog.js +1 -5
- package/plugins/rlm/test/isolated-vm-sandbox.test.js +23 -0
- package/pnpm-workspace.yaml +10 -5
- package/schema.js +0 -28
- package/skills/modelmix/SKILL.md +34 -12
- package/test/abort.test.js +517 -0
- package/test/anthropic.test.js +77 -1
- package/test/bottleneck.test.js +2 -2
- package/test/effort.test.js +24 -1
- package/test/fallback.test.js +101 -1
- package/test/glm.test.js +2 -6
- package/test/kimi.test.js +2 -6
- package/test/live.test.js +10 -5
- package/test/muse.test.js +24 -7
- package/test/provider-expansion.test.js +17 -0
- package/test/public-api.test.js +2 -2
- package/test/qwen.test.js +2 -3
- package/test/tokens.test.js +23 -8
package/README.md
CHANGED
|
@@ -95,6 +95,26 @@ const model = await ModelMix.new(setup)
|
|
|
95
95
|
console.log(await model.message());
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
+
**Cancel one execution with AbortSignal**
|
|
99
|
+
|
|
100
|
+
Pass the signal directly to the terminal method. ModelMix propagates it through
|
|
101
|
+
queued work, retries, fallbacks, provider transports, plugins, child executions,
|
|
102
|
+
and tool calls:
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
const controller = new AbortController();
|
|
106
|
+
const response = model.message(controller.signal);
|
|
107
|
+
|
|
108
|
+
controller.abort(new Error('Request cancelled'));
|
|
109
|
+
await response;
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Use `raw(signal)`, `stream(callback, signal)`, `block(options, signal)`, or
|
|
113
|
+
`json(example, description, jsonOptions, signal)` for the other output modes.
|
|
114
|
+
`execute()` accepts it as the top-level `signal` field. Never put a signal in
|
|
115
|
+
ModelMix or provider `config`/`options`; those locations are rejected because
|
|
116
|
+
they are reusable and may become provider payload fields.
|
|
117
|
+
|
|
98
118
|
The same ordered chain can be attached by passing model shortcuts directly to
|
|
99
119
|
`chain()`. Add `@effort` to override unified effort for one model; entries
|
|
100
120
|
without it inherit the chain effort, or use the provider default when the chain
|
|
@@ -119,10 +139,9 @@ console.log(ETH.price);
|
|
|
119
139
|
|
|
120
140
|
**This example uses providers with free quotas (Groq, Cerebras, and Together). OpenRouter is disabled because its GPT-OSS 120B route is no longer free. If one model runs out of quota, ModelMix automatically falls back to the next model in the chain.**
|
|
121
141
|
```javascript
|
|
122
|
-
ModelMix.new(
|
|
142
|
+
ModelMix.new()
|
|
123
143
|
.gptOss()
|
|
124
144
|
.kimiK25()
|
|
125
|
-
.hermes3()
|
|
126
145
|
.addText('What is the capital of France?');
|
|
127
146
|
```
|
|
128
147
|
|
|
@@ -143,15 +162,20 @@ ModelMix provides convenient shorthand methods for quickly accessing different A
|
|
|
143
162
|
| `gpt56terra()` | OpenAI | gpt-5.6-terra | [\$2.00][1] | [\$12.00][1] |
|
|
144
163
|
| `gpt56luna()` | OpenAI | gpt-5.6-luna | [\$0.20][1] | [\$1.20][1] |
|
|
145
164
|
| `gpt55()` | OpenAI | gpt-5.5 | [\$5.00][1] | [\$30.00][1] |
|
|
165
|
+
| `gpt55pro()` | OpenAI | gpt-5.5-pro | [\$30.00][1] | [\$180.00][1] |
|
|
146
166
|
| `gpt54()` | OpenAI | gpt-5.4 | [\$2.50][1] | [\$15.00][1] |
|
|
147
167
|
| `gpt54mini()` | OpenAI | gpt-5.4-mini | [\$0.75][1] | [\$4.50][1] |
|
|
148
168
|
| `gpt54nano()` | OpenAI | gpt-5.4-nano | [\$0.20][1] | [\$1.25][1] |
|
|
149
|
-
| `
|
|
169
|
+
| `gpt54pro()` | OpenAI | gpt-5.4-pro | [\$30.00][1] | [\$180.00][1] |
|
|
170
|
+
| `gpt53codex()` | OpenAI | gpt-5.3-codex | [\$1.75][1] | [\$14.00][1] |
|
|
171
|
+
| `gpt53chat()` | OpenAI | gpt-5.3-chat-latest | [\$1.75][1] | [\$14.00][1] |
|
|
150
172
|
| `gpt52()` | OpenAI | gpt-5.2 | [\$1.75][1] | [\$14.00][1] |
|
|
151
173
|
| `gpt51()` | OpenAI | gpt-5.1 | [\$1.25][1] | [\$10.00][1] |
|
|
174
|
+
| `gpt5()` | OpenAI | gpt-5 | [\$1.25][1] | [\$10.00][1] |
|
|
152
175
|
| `gpt5mini()` | OpenAI | gpt-5-mini | [\$0.25][1] | [\$2.00][1] |
|
|
153
176
|
| `gpt5nano()` | OpenAI | gpt-5-nano | [\$0.05][1] | [\$0.40][1] |
|
|
154
177
|
| `gptOss()` | Multi-provider | gpt-oss-120B | [\$0.15][7] | [\$0.60][7] |
|
|
178
|
+
| `fable51()` | Anthropic | claude-fable-5-1 | [\$10.00][2] | [\$50.00][2] |
|
|
155
179
|
| `fable5()` | Anthropic | claude-fable-5 | [\$10.00][2] | [\$50.00][2] |
|
|
156
180
|
| `opus5()` | Anthropic | claude-opus-5 | [\$5.00][2] | [\$25.00][2] |
|
|
157
181
|
| `opus48()` | Anthropic | claude-opus-4-8 | [\$5.00][2] | [\$25.00][2] |
|
|
@@ -172,6 +196,7 @@ ModelMix provides convenient shorthand methods for quickly accessing different A
|
|
|
172
196
|
| `grok420multiAgent()` | Grok | grok-4.20-multi-agent-0309 | [\$1.25][6] | [\$2.50][6] |
|
|
173
197
|
| `grok420()` | Grok | grok-4.20-0309 (†) | [\$1.25][6] | [\$2.50][6] |
|
|
174
198
|
| `museGlimmer30b()` | Fireworks | models/muse-glimmer-30b | [\$0.35][17] | [\$1.50][17] |
|
|
199
|
+
| `museSpark12Contributor()` | OpenRouter | meta/muse-spark-1.2-contributor | [\$0.10][22] | [\$0.20][22] |
|
|
175
200
|
| `qwen35397b()` | OpenRouter | qwen/qwen3.5-397b-a17b | [\$0.385][14] | [\$2.45][14] |
|
|
176
201
|
| `qwen36plus()` | OpenRouter | qwen/qwen3.6-plus | [\$0.325][18] | [\$1.95][18] |
|
|
177
202
|
| `qwen37plus()` | Fireworks | models/qwen3p7-plus | [\$0.40][10] | [\$1.60][10] |
|
|
@@ -197,9 +222,13 @@ ModelMix provides convenient shorthand methods for quickly accessing different A
|
|
|
197
222
|
|
|
198
223
|
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.
|
|
199
224
|
|
|
200
|
-
`museGlimmer30b()` uses Fireworks
|
|
225
|
+
`museGlimmer30b()` uses Fireworks by default. OpenRouter, NVIDIA NIM, and Together are available through `mix.openrouter`, `mix.nvidia`, and `mix.together`.
|
|
226
|
+
|
|
227
|
+
`fable51()` uses the official Anthropic API by default (`claude-fable-5-1`). Pass `mix: { openrouter: true }` to append [`anthropic/claude-fable-5.1`][21] as its fallback.
|
|
228
|
+
|
|
229
|
+
Every textual GPT-5 shortcut in the table uses the official OpenAI API by default. Pass `mix: { openrouter: true }` to `ModelMix.new()` or to an individual shortcut to append the matching [`openai/*` OpenRouter route][23] as its fallback. `gpt53chat()` maps the official `gpt-5.3-chat-latest` alias to `openai/gpt-5.3-chat`. Realtime shortcuts remain official-only because they use OpenAI's WebSocket transport.
|
|
201
230
|
|
|
202
|
-
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.
|
|
231
|
+
OpenRouter fallbacks are disabled globally by default and are appended only with `mix.openrouter: true`. Shortcuts whose primary provider is OpenRouter, such as `qwen36plus()`, are unaffected. 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 explicitly enabled provider in its fallback chain.
|
|
203
232
|
|
|
204
233
|
[1]: https://platform.openai.com/docs/pricing "Pricing | OpenAI"
|
|
205
234
|
[2]: https://docs.anthropic.com/en/docs/about-claude/pricing "Pricing - Anthropic"
|
|
@@ -221,6 +250,9 @@ The multi-provider shortcuts also expose the current catalog alternatives: `gptO
|
|
|
221
250
|
[18]: https://openrouter.ai/qwen/qwen3.6-plus "Qwen 3.6 Plus on OpenRouter"
|
|
222
251
|
[19]: https://openrouter.ai/qwen/qwen3.8-flash "Qwen3.8 Flash on OpenRouter"
|
|
223
252
|
[20]: https://openrouter.ai/z-ai/glm-5.3-flash "GLM 5.3 Flash on OpenRouter"
|
|
253
|
+
[21]: https://openrouter.ai/anthropic/claude-fable-5.1 "Claude Fable 5.1 on OpenRouter"
|
|
254
|
+
[22]: https://openrouter.ai/meta/muse-spark-1.2-contributor "Muse Spark 1.2 Contributor on OpenRouter"
|
|
255
|
+
[23]: https://openrouter.ai/openai "OpenAI Models on OpenRouter"
|
|
224
256
|
|
|
225
257
|
Each method accepts optional `options`, `config`, and (for multi-provider methods) `mix` parameters to customize behavior.
|
|
226
258
|
|
|
@@ -927,7 +959,7 @@ const model = ModelMix.new()
|
|
|
927
959
|
.addText('Summarize this request.');
|
|
928
960
|
```
|
|
929
961
|
|
|
930
|
-
A plugin may edit `context.request`, call `next()`, or return a complete ModelMix result itself.
|
|
962
|
+
A plugin may edit `context.request`, call `next()`, or return a complete ModelMix result itself. The current execution signal is available as `context.signal`, and child executions created with `context.invoke()` inherit it automatically. Local tool callbacks receive the same signal as their second argument. A plugin can also choose plugin inheritance:
|
|
931
963
|
|
|
932
964
|
```javascript
|
|
933
965
|
const child = await context.invoke({
|
|
@@ -1038,8 +1070,8 @@ new ModelMix(args = { options: {}, config: {} })
|
|
|
1038
1070
|
- `assign(keyValues)`: Assigns EJS data for messages and system prompts.
|
|
1039
1071
|
- `assignKey(key, value)`: Assigns one EJS data value.
|
|
1040
1072
|
- `assignKeyFromFile(key, filePath)`: Renders an EJS file through `include` and assigns its output to one key.
|
|
1041
|
-
- `message()`: Sends the message and returns the response.
|
|
1042
|
-
- `raw()`: Sends the message and returns the complete response data including:
|
|
1073
|
+
- `message(signal?)`: Sends the message and returns the response.
|
|
1074
|
+
- `raw(signal?)`: Sends the message and returns the complete response data including:
|
|
1043
1075
|
- `message`: The text response from the model
|
|
1044
1076
|
- `think`: Reasoning/thinking content (if available)
|
|
1045
1077
|
- `toolCalls`: Array of tool calls made by the model (if any)
|
|
@@ -1057,8 +1089,8 @@ new ModelMix(args = { options: {}, config: {} })
|
|
|
1057
1089
|
|
|
1058
1090
|
if (profile.flagged) throw new Error('Profile rejected by moderation');
|
|
1059
1091
|
```
|
|
1060
|
-
- `stream(callback)`: Sends the message and streams the response, invoking the callback with each streamed part.
|
|
1061
|
-
- `json(schemaExample, descriptions = {}, options = {})`: Forces the model to return a response in a specific JSON format.
|
|
1092
|
+
- `stream(callback, signal?)`: Sends the message and streams the response, invoking the callback with each streamed part.
|
|
1093
|
+
- `json(schemaExample, descriptions = {}, options = {}, signal?)`: Forces the model to return a response in a specific JSON format.
|
|
1062
1094
|
- `schemaExample`: Example of the JSON structure to be returned. Top-level arrays are auto-wrapped for better LLM compatibility.
|
|
1063
1095
|
- `descriptions`: Descriptions for each field — can be strings or descriptor objects with `{ description, required, enum, default }`.
|
|
1064
1096
|
- `options`: `{ addSchema: true, addExample: false, addNote: false }`
|
package/demo/free.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { ModelMix } from '../index.js';
|
|
2
2
|
try { process.loadEnvFile(); } catch {}
|
|
3
3
|
|
|
4
|
-
const ai = ModelMix.new({ config: { debug: 2 }
|
|
4
|
+
const ai = ModelMix.new({ config: { debug: 2 } })
|
|
5
5
|
.gptOss()
|
|
6
6
|
.kimiK25()
|
|
7
|
-
.hermes3()
|
|
8
7
|
.addText('What is the capital of France?');
|
|
9
8
|
|
|
10
9
|
const response = await ai.message();
|
|
11
10
|
console.log('Response from a free-tier provider:', response);
|
|
12
|
-
|
package/demo/short.js
CHANGED
|
@@ -9,19 +9,21 @@ const setup = {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
const mmix = await ModelMix.new(setup)
|
|
12
|
-
.
|
|
13
|
-
.
|
|
14
|
-
.
|
|
15
|
-
.
|
|
16
|
-
.
|
|
17
|
-
.
|
|
18
|
-
.
|
|
19
|
-
.
|
|
20
|
-
.
|
|
21
|
-
.
|
|
22
|
-
.
|
|
23
|
-
.
|
|
24
|
-
.
|
|
12
|
+
.fable51({ mix: { openrouter: true } }) // (main + provider fallback) Anthropic/OpenRouter Claude Fable 5.1
|
|
13
|
+
.sonnet46() // (fallback 2) Anthropic claude-sonnet-4-6
|
|
14
|
+
.gpt56luna({ mix: { openrouter: true } }) // (fallback 3 + provider fallback) OpenAI/OpenRouter gpt-5.6-luna
|
|
15
|
+
.gemini37flash() // (fallback 4) Google gemini-3.7-flash
|
|
16
|
+
.gpt5nano({ mix: { openrouter: true } }) // (fallback 5 + provider fallback) OpenAI/OpenRouter gpt-5-nano
|
|
17
|
+
.grok46() // (fallback 6) Grok grok-4.6
|
|
18
|
+
.qwen35397b() // (fallback 7) OpenRouter qwen/qwen3.5-397b-a17b
|
|
19
|
+
.qwen3827b() // (fallback 8) OpenRouter qwen/qwen3.8-27b
|
|
20
|
+
.qwen38flash() // (fallback 9) OpenRouter qwen/qwen3.8-flash
|
|
21
|
+
.GLM53() // (fallback 10) OpenRouter z-ai/glm-5.3
|
|
22
|
+
.GLM53Flash() // (fallback 11) OpenRouter z-ai/glm-5.3-flash
|
|
23
|
+
.museGlimmer30b({ mix: { fireworks: false, openrouter: true } }) // (fallback 12) OpenRouter meta/muse-glimmer-30b
|
|
24
|
+
.museSpark12Contributor() // (fallback 13) OpenRouter meta/muse-spark-1.2-contributor
|
|
25
|
+
.hermes470b() // (fallback 14) OpenRouter nousresearch/hermes-4-70b
|
|
26
|
+
.hermes4405b() // (fallback 15) OpenRouter nousresearch/hermes-4-405b
|
|
25
27
|
.addText("What's your name?");
|
|
26
28
|
|
|
27
29
|
console.log(await mmix.message());
|
package/effort.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const OPENAI_LEVELS = ['none', 'low', 'medium', 'high', 'xhigh'];
|
|
10
|
-
const OPENAI_LEVEL_LADDER = [
|
|
10
|
+
const OPENAI_LEVEL_LADDER = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'];
|
|
11
11
|
const ANTHROPIC_LEVELS = ['low', 'medium', 'high', 'xhigh', 'max'];
|
|
12
12
|
const GEMINI_LEVELS = ['minimal', 'low', 'medium', 'high'];
|
|
13
13
|
|
|
@@ -45,9 +45,11 @@ 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
|
+
'anthropic/claude-fable-5.1': ['low', 'medium', 'high', 'xhigh', 'max'],
|
|
48
49
|
'meta/muse-glimmer-30b': ['low', 'medium', 'high'],
|
|
49
50
|
'accounts/fireworks/models/muse-glimmer-30b': ['low', 'medium', 'high', 'xhigh'],
|
|
50
51
|
'meta-models/Muse-Glimmer-30B': ['low', 'medium', 'high', 'xhigh'],
|
|
52
|
+
'meta/muse-spark-1.2-contributor': ['minimal', 'low', 'medium', 'high', 'xhigh'],
|
|
51
53
|
'accounts/fireworks/models/qwen3p8-2p4t-a95b': ['none', 'low', 'medium', 'high'],
|
|
52
54
|
'qwen/qwen3.8-27b': ['low', 'medium', 'xhigh'],
|
|
53
55
|
'qwen/qwen3.8-flash': ['low', 'medium', 'xhigh'],
|
|
@@ -87,7 +89,6 @@ const DEEPSEEK_BANDS = [
|
|
|
87
89
|
* MiniMax M3 (OpenAI-compatible): thinking.type disabled | adaptive.
|
|
88
90
|
* @see https://platform.minimax.io/docs/api-reference/text-openai-api
|
|
89
91
|
*/
|
|
90
|
-
const MINIMAX_LEVELS = ['disabled', 'adaptive'];
|
|
91
92
|
const MINIMAX_BANDS = [
|
|
92
93
|
[0, 19, 'disabled'],
|
|
93
94
|
[20, 100, 'adaptive'],
|
|
@@ -203,8 +204,11 @@ function pickNearestLevel(desired, ladder, supported) {
|
|
|
203
204
|
}
|
|
204
205
|
|
|
205
206
|
function supportedOpenAILevels(modelKey) {
|
|
206
|
-
|
|
207
|
-
|
|
207
|
+
const canonicalModelKey = typeof modelKey === 'string' && modelKey.startsWith('openai/')
|
|
208
|
+
? modelKey.slice('openai/'.length)
|
|
209
|
+
: modelKey;
|
|
210
|
+
if (canonicalModelKey && OPENAI_MODEL_LEVELS[canonicalModelKey]) {
|
|
211
|
+
return OPENAI_MODEL_LEVELS[canonicalModelKey];
|
|
208
212
|
}
|
|
209
213
|
return OPENAI_LEVELS;
|
|
210
214
|
}
|
|
@@ -400,9 +404,11 @@ function mapEffort(providerFamily, effort, modelKey) {
|
|
|
400
404
|
const supported = supportedOpenAILevels(modelKey);
|
|
401
405
|
const desired = modelKey === 'z-ai/glm-5.3' || modelKey === 'z-ai/glm-5.3-flash'
|
|
402
406
|
? levelFromBands(normalized, GLM53_BANDS)
|
|
403
|
-
:
|
|
404
|
-
?
|
|
405
|
-
:
|
|
407
|
+
: modelKey === 'anthropic/claude-fable-5.1'
|
|
408
|
+
? levelFromBands(normalized, ANTHROPIC_BANDS)
|
|
409
|
+
: normalized === 100 && supported.includes('max')
|
|
410
|
+
? 'max'
|
|
411
|
+
: levelFromBands(normalized, OPENAI_BANDS);
|
|
406
412
|
const level = pickNearestLevel(desired, OPENAI_LEVEL_LADDER, supported);
|
|
407
413
|
return { reasoning_effort: level };
|
|
408
414
|
}
|
package/http-client.js
CHANGED
|
@@ -45,8 +45,8 @@ async function buildHttpError(url, response) {
|
|
|
45
45
|
return error;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
async function fetchJsonResponse(url, { method = 'POST', headers = {}, body } = {}) {
|
|
49
|
-
const response = await fetch(url, { method, headers, body });
|
|
48
|
+
async function fetchJsonResponse(url, { method = 'POST', headers = {}, body, signal } = {}) {
|
|
49
|
+
const response = await fetch(url, { method, headers, body, signal });
|
|
50
50
|
if (!response.ok) {
|
|
51
51
|
throw await buildHttpError(url, response);
|
|
52
52
|
}
|
|
@@ -58,8 +58,8 @@ async function fetchJsonResponse(url, { method = 'POST', headers = {}, body } =
|
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
async function fetchBinaryResponse(url, { method = 'GET', headers = {}, body } = {}) {
|
|
62
|
-
const response = await fetch(url, { method, headers, body });
|
|
61
|
+
async function fetchBinaryResponse(url, { method = 'GET', headers = {}, body, signal } = {}) {
|
|
62
|
+
const response = await fetch(url, { method, headers, body, signal });
|
|
63
63
|
if (!response.ok) {
|
|
64
64
|
throw await buildHttpError(url, response);
|
|
65
65
|
}
|
|
@@ -71,8 +71,8 @@ async function fetchBinaryResponse(url, { method = 'GET', headers = {}, body } =
|
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
async function fetchStreamResponse(url, { method = 'POST', headers = {}, body } = {}) {
|
|
75
|
-
const response = await fetch(url, { method, headers, body });
|
|
74
|
+
async function fetchStreamResponse(url, { method = 'POST', headers = {}, body, signal } = {}) {
|
|
75
|
+
const response = await fetch(url, { method, headers, body, signal });
|
|
76
76
|
if (!response.ok) {
|
|
77
77
|
throw await buildHttpError(url, response);
|
|
78
78
|
}
|
package/index.d.ts
CHANGED
|
@@ -76,6 +76,7 @@ export interface ModelMixConfig {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
export interface ModelMixMixFlags {
|
|
79
|
+
anthropic?: boolean;
|
|
79
80
|
openrouter?: boolean;
|
|
80
81
|
cerebras?: boolean;
|
|
81
82
|
groq?: boolean;
|
|
@@ -258,6 +259,7 @@ export interface PluginExecutionContext {
|
|
|
258
259
|
outputMode: ModelMixOutputMode;
|
|
259
260
|
};
|
|
260
261
|
execution: Readonly<PluginExecutionMetadata>;
|
|
262
|
+
signal?: AbortSignal;
|
|
261
263
|
invoke(input: ChildInvocation): Promise<ModelMixResult>;
|
|
262
264
|
}
|
|
263
265
|
|
|
@@ -311,7 +313,8 @@ export interface ToolDefinition {
|
|
|
311
313
|
}
|
|
312
314
|
|
|
313
315
|
export type ToolCallback = (
|
|
314
|
-
args: Record<string, unknown
|
|
316
|
+
args: Record<string, unknown>,
|
|
317
|
+
signal?: AbortSignal
|
|
315
318
|
) => unknown | Promise<unknown>;
|
|
316
319
|
|
|
317
320
|
export interface ToolWithCallback {
|
|
@@ -342,6 +345,7 @@ export interface ProviderConstructorArgs {
|
|
|
342
345
|
export interface CreateArgs {
|
|
343
346
|
config?: ModelMixConfig;
|
|
344
347
|
options?: ModelMixOptions;
|
|
348
|
+
signal?: AbortSignal;
|
|
345
349
|
outputMode?: ModelMixOutputMode;
|
|
346
350
|
}
|
|
347
351
|
|
|
@@ -462,6 +466,7 @@ export declare class ModelMix {
|
|
|
462
466
|
gptOss(args?: ModelAttachArgs): this;
|
|
463
467
|
|
|
464
468
|
// Anthropic
|
|
469
|
+
fable51(args?: ModelAttachArgs): this;
|
|
465
470
|
fable50(args?: ModelAttachArgs): this;
|
|
466
471
|
fable5(args?: ModelAttachArgs): this;
|
|
467
472
|
opus50(args?: ModelAttachArgs): this;
|
|
@@ -497,6 +502,7 @@ export declare class ModelMix {
|
|
|
497
502
|
|
|
498
503
|
// Multi-provider
|
|
499
504
|
museGlimmer30b(args?: ModelAttachArgs): this;
|
|
505
|
+
museSpark12Contributor(args?: ModelAttachArgs): this;
|
|
500
506
|
qwen35397b(args?: ModelAttachArgs): this;
|
|
501
507
|
qwen36plus(args?: ModelAttachArgs): this;
|
|
502
508
|
qwen37plus(args?: ModelAttachArgs): this;
|
|
@@ -530,15 +536,16 @@ export declare class ModelMix {
|
|
|
530
536
|
addImageFromUrl(url: string, options?: RoleOptions): Promise<this>;
|
|
531
537
|
processImages(): Promise<void>;
|
|
532
538
|
|
|
533
|
-
message(): Promise<string>;
|
|
539
|
+
message(signal?: AbortSignal): Promise<string>;
|
|
534
540
|
json<T = unknown>(
|
|
535
541
|
schemaExample?: T | T[] | null,
|
|
536
542
|
schemaDescription?: SchemaDescription,
|
|
537
|
-
options?: JsonMethodOptions
|
|
543
|
+
options?: JsonMethodOptions,
|
|
544
|
+
signal?: AbortSignal
|
|
538
545
|
): Promise<T>;
|
|
539
|
-
block(options?: BlockOptions): Promise<string>;
|
|
540
|
-
raw(): Promise<ModelMixResult>;
|
|
541
|
-
stream(callback: StreamCallback): Promise<ModelMixResult>;
|
|
546
|
+
block(options?: BlockOptions, signal?: AbortSignal): Promise<string>;
|
|
547
|
+
raw(signal?: AbortSignal): Promise<ModelMixResult>;
|
|
548
|
+
stream(callback: StreamCallback, signal?: AbortSignal): Promise<ModelMixResult>;
|
|
542
549
|
|
|
543
550
|
assignKeyFromFile(key: string, filePath: string): this;
|
|
544
551
|
groupByRoles(messages: ChatMessage[]): ChatMessage[];
|