modelmix 5.1.1 → 5.1.2

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.
@@ -0,0 +1,338 @@
1
+ const {
2
+ GROK420_REASONING,
3
+ GROK420_NON_REASONING
4
+ } = require('../../effort');
5
+
6
+ function createCompatibleProviders({ MixCustom, MixOpenAI }) {
7
+ class MixMiniMax extends MixOpenAI {
8
+ getDefaultConfig(customConfig) {
9
+
10
+ if (!process.env.MINIMAX_API_KEY) {
11
+ throw new Error('MiniMax API key not found. Please provide it in config or set MINIMAX_API_KEY environment variable.');
12
+ }
13
+
14
+ return MixCustom.prototype.getDefaultConfig.call(this, {
15
+ url: 'https://api.minimax.io/v1/chat/completions',
16
+ apiKey: process.env.MINIMAX_API_KEY,
17
+ ...customConfig
18
+ });
19
+ }
20
+
21
+ extractDelta(data) {
22
+ // MiniMax might send different formats during streaming
23
+ if (data.choices && data.choices[0] && data.choices[0].delta && data.choices[0].delta.content) {
24
+ return data.choices[0].delta.content;
25
+ }
26
+ return '';
27
+ }
28
+ }
29
+
30
+ class MixMiMo extends MixOpenAI {
31
+ getDefaultConfig(customConfig) {
32
+ if (!process.env.MIMO_API_KEY) {
33
+ throw new Error('MiMo API key not found. Please provide it in config or set MIMO_API_KEY environment variable.');
34
+ }
35
+
36
+ return MixCustom.prototype.getDefaultConfig.call(this, {
37
+ url: 'https://api.xiaomimimo.com/v1/chat/completions',
38
+ apiKey: process.env.MIMO_API_KEY,
39
+ ...customConfig
40
+ });
41
+ }
42
+
43
+ getDefaultHeaders(customHeaders) {
44
+ return {
45
+ 'accept': 'application/json',
46
+ 'content-type': 'application/json',
47
+ 'api-key': this.config.apiKey,
48
+ ...customHeaders
49
+ };
50
+ }
51
+ }
52
+
53
+ class MixPerplexity extends MixCustom {
54
+ getDefaultConfig(customConfig) {
55
+
56
+ if (!process.env.PPLX_API_KEY) {
57
+ throw new Error('Perplexity API key not found. Please provide it in config or set PPLX_API_KEY environment variable.');
58
+ }
59
+
60
+ return super.getDefaultConfig({
61
+ url: 'https://api.perplexity.ai/chat/completions',
62
+ apiKey: process.env.PPLX_API_KEY,
63
+ ...customConfig
64
+ });
65
+ }
66
+
67
+ async create({ config = {}, options = {} } = {}) {
68
+
69
+ if (config.schema) {
70
+ options.response_format = {
71
+ type: 'json_schema',
72
+ json_schema: { schema: config.schema }
73
+ };
74
+ }
75
+
76
+ return super.create({ config, options });
77
+ }
78
+ }
79
+
80
+ class MixOllama extends MixCustom {
81
+
82
+ getDefaultConfig(customConfig) {
83
+ return super.getDefaultConfig({
84
+ url: 'http://localhost:11434/api/chat',
85
+ ...customConfig
86
+ });
87
+ }
88
+
89
+ getDefaultOptions(customOptions) {
90
+ return {
91
+ options: customOptions,
92
+ };
93
+ }
94
+
95
+ extractDelta(data) {
96
+ if (data.message && data.message.content) return data.message.content;
97
+ return '';
98
+ }
99
+
100
+ extractMessage(data) {
101
+ return data.message.content.trim();
102
+ }
103
+
104
+ convertMessages(messages, config) {
105
+ return MixOllama.convertMessages(messages, config);
106
+ }
107
+
108
+ static convertMessages(messages, config) {
109
+ const content = config.system;
110
+ messages = [{ role: 'system', content }, ...messages || []];
111
+
112
+ return messages.map(entry => {
113
+ let content = '';
114
+ let images = [];
115
+
116
+ entry.content.forEach(item => {
117
+ if (item.type === 'text') {
118
+ content += item.text + ' ';
119
+ } else if (item.type === 'image') {
120
+ images.push(item.source.data);
121
+ }
122
+ });
123
+
124
+ return {
125
+ role: entry.role,
126
+ content: content.trim(),
127
+ images: images
128
+ };
129
+ });
130
+ }
131
+ }
132
+
133
+ class MixGrok extends MixOpenAI {
134
+ getDefaultConfig(customConfig) {
135
+
136
+ if (!process.env.XAI_API_KEY) {
137
+ throw new Error('Grok API key not found. Please provide it in config or set XAI_API_KEY environment variable.');
138
+ }
139
+
140
+ return super.getDefaultConfig({
141
+ url: 'https://api.x.ai/v1/chat/completions',
142
+ apiKey: process.env.XAI_API_KEY,
143
+ ...customConfig
144
+ });
145
+ }
146
+
147
+ async create({ config = {}, options = {} } = {}) {
148
+ if (options.model === GROK420_REASONING || options.model === GROK420_NON_REASONING) {
149
+ delete options.reasoning_effort;
150
+ }
151
+ return super.create({ config, options });
152
+ }
153
+ }
154
+
155
+ class MixLambda extends MixCustom {
156
+ getDefaultConfig(customConfig) {
157
+
158
+ if (!process.env.LAMBDA_API_KEY) {
159
+ throw new Error('Lambda API key not found. Please provide it in config or set LAMBDA_API_KEY environment variable.');
160
+ }
161
+
162
+ return super.getDefaultConfig({
163
+ url: 'https://api.lambda.ai/v1/chat/completions',
164
+ apiKey: process.env.LAMBDA_API_KEY,
165
+ ...customConfig
166
+ });
167
+ }
168
+ }
169
+
170
+ class MixLMStudio extends MixCustom {
171
+ getDefaultConfig(customConfig) {
172
+ return super.getDefaultConfig({
173
+ url: 'http://localhost:1234/v1/chat/completions',
174
+ ...customConfig
175
+ });
176
+ }
177
+
178
+ create({ config = {}, options = {} } = {}) {
179
+ if (config.schema) {
180
+ options.response_format = {
181
+ type: 'json_schema',
182
+ json_schema: { schema: config.schema }
183
+ };
184
+ }
185
+ return super.create({ config, options });
186
+ }
187
+
188
+ static extractThink(data) {
189
+ const message = data.choices[0].message?.content?.trim() || '';
190
+
191
+ // Check for LMStudio special tags
192
+ const startTag = '<|channel|>analysis<|message|>';
193
+ const endTag = '<|end|><|start|>assistant<|channel|>final<|message|>';
194
+
195
+ const startIndex = message.indexOf(startTag);
196
+ const endIndex = message.indexOf(endTag);
197
+
198
+ if (startIndex !== -1 && endIndex !== -1) {
199
+ // Extract content between the special tags
200
+ const thinkContent = message.substring(startIndex + startTag.length, endIndex).trim();
201
+ return thinkContent;
202
+ }
203
+
204
+ // Fall back to default extraction method
205
+ return MixCustom.extractThink(data);
206
+ }
207
+
208
+ static extractMessage(data) {
209
+ const message = data.choices[0].message?.content?.trim() || '';
210
+
211
+ // Check for LMStudio special tags and extract final message
212
+ const endTag = '<|end|><|start|>assistant<|channel|>final<|message|>';
213
+ const endIndex = message.indexOf(endTag);
214
+
215
+ if (endIndex !== -1) {
216
+ // Return only the content after the final message tag
217
+ return message.substring(endIndex + endTag.length).trim();
218
+ }
219
+
220
+ // Fall back to default extraction method
221
+ return MixCustom.extractMessage(data);
222
+ }
223
+
224
+ processResponse(response) {
225
+ return {
226
+ message: MixLMStudio.extractMessage(response.data),
227
+ think: MixLMStudio.extractThink(response.data),
228
+ toolCalls: MixCustom.extractToolCalls(response.data),
229
+ tokens: MixCustom.extractTokens(response.data),
230
+ response: response.data
231
+ };
232
+ }
233
+ }
234
+
235
+ class MixGroq extends MixCustom {
236
+ getDefaultConfig(customConfig) {
237
+
238
+ if (!process.env.GROQ_API_KEY) {
239
+ throw new Error('Groq API key not found. Please provide it in config or set GROQ_API_KEY environment variable.');
240
+ }
241
+
242
+ return super.getDefaultConfig({
243
+ url: 'https://api.groq.com/openai/v1/chat/completions',
244
+ apiKey: process.env.GROQ_API_KEY,
245
+ ...customConfig
246
+ });
247
+ }
248
+ }
249
+
250
+ class MixTogether extends MixCustom {
251
+ getDefaultConfig(customConfig) {
252
+
253
+ if (!process.env.TOGETHER_API_KEY) {
254
+ throw new Error('Together API key not found. Please provide it in config or set TOGETHER_API_KEY environment variable.');
255
+ }
256
+
257
+ return super.getDefaultConfig({
258
+ url: 'https://api.together.xyz/v1/chat/completions',
259
+ apiKey: process.env.TOGETHER_API_KEY,
260
+ ...customConfig
261
+ });
262
+ }
263
+
264
+ getDefaultOptions(customOptions) {
265
+ return {
266
+ stop: ["<|eot_id|>", "<|eom_id|>"],
267
+ ...customOptions
268
+ };
269
+ }
270
+ }
271
+
272
+ class MixCerebras extends MixCustom {
273
+ getDefaultConfig(customConfig) {
274
+
275
+ if (!process.env.CEREBRAS_API_KEY) {
276
+ throw new Error('Together API key not found. Please provide it in config or set CEREBRAS_API_KEY environment variable.');
277
+ }
278
+
279
+ return super.getDefaultConfig({
280
+ url: 'https://api.cerebras.ai/v1/chat/completions',
281
+ apiKey: process.env.CEREBRAS_API_KEY,
282
+ ...customConfig
283
+ });
284
+ }
285
+
286
+ create({ config = {}, options = {} } = {}) {
287
+ delete options.response_format;
288
+ return super.create({ config, options });
289
+ }
290
+ }
291
+
292
+ class MixFireworks extends MixCustom {
293
+ getDefaultConfig(customConfig) {
294
+
295
+ if (!process.env.FIREWORKS_API_KEY) {
296
+ throw new Error('Fireworks API key not found. Please provide it in config or set FIREWORKS_API_KEY environment variable.');
297
+ }
298
+
299
+ return super.getDefaultConfig({
300
+ url: 'https://api.fireworks.ai/inference/v1/chat/completions',
301
+ apiKey: process.env.FIREWORKS_API_KEY,
302
+ ...customConfig
303
+ });
304
+ }
305
+ }
306
+
307
+ class MixNVIDIA extends MixCustom {
308
+ getDefaultConfig(customConfig) {
309
+
310
+ if (!process.env.NVIDIA_API_KEY) {
311
+ throw new Error('NVIDIA API key not found. Please provide it in config or set NVIDIA_API_KEY environment variable.');
312
+ }
313
+
314
+ return super.getDefaultConfig({
315
+ url: 'https://integrate.api.nvidia.com/v1/chat/completions',
316
+ apiKey: process.env.NVIDIA_API_KEY,
317
+ ...customConfig
318
+ });
319
+ }
320
+ }
321
+
322
+ return {
323
+ MixMiniMax,
324
+ MixMiMo,
325
+ MixPerplexity,
326
+ MixOllama,
327
+ MixGrok,
328
+ MixLambda,
329
+ MixLMStudio,
330
+ MixGroq,
331
+ MixTogether,
332
+ MixCerebras,
333
+ MixFireworks,
334
+ MixNVIDIA
335
+ };
336
+ }
337
+
338
+ module.exports = createCompatibleProviders;