modelmix 4.0.8 → 4.1.0
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/demo/demo.js +3 -8
- package/demo/gemini.js +41 -0
- package/index.js +71 -18
- package/package.json +1 -1
package/demo/demo.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import 'dotenv/config';
|
|
2
|
-
import { ModelMix
|
|
2
|
+
import { ModelMix } from '../index.js';
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
const mmix = new ModelMix({
|
|
@@ -27,15 +27,10 @@ const pplxSettings = {
|
|
|
27
27
|
mmix.replace({ '{name}': 'ALF' });
|
|
28
28
|
|
|
29
29
|
console.log("\n" + '--------| gpt51() |--------');
|
|
30
|
-
const opt = {
|
|
31
|
-
config: {
|
|
32
|
-
temperature: 0,
|
|
33
|
-
reasoning: { effort: 'none' }
|
|
34
|
-
}
|
|
35
|
-
};
|
|
30
|
+
const opt = { reasoning_effort: 'none', verbosity: 'low' };
|
|
36
31
|
const gpt = mmix.gpt51(opt).addText("Have you ever eaten a {animal}?");
|
|
37
32
|
gpt.replace({ '{animal}': 'cat' });
|
|
38
|
-
|
|
33
|
+
await gpt.json({ time: '24:00:00', message: 'Hello' }, { time: 'Time in format HH:MM:SS' });
|
|
39
34
|
|
|
40
35
|
console.log("\n" + '--------| sonnet45() |--------');
|
|
41
36
|
const claude = mmix.new({ config: { debug: true } }).sonnet45();
|
package/demo/gemini.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
process.loadEnvFile();
|
|
2
|
+
|
|
3
|
+
import { ModelMix, MixGoogle } from '../index.js';
|
|
4
|
+
const mmix = new ModelMix({
|
|
5
|
+
options: {
|
|
6
|
+
max_tokens: 2000,
|
|
7
|
+
},
|
|
8
|
+
config: {
|
|
9
|
+
system: 'You are ALF from Melmac.',
|
|
10
|
+
max_history: 2,
|
|
11
|
+
debug: false
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// Using gemini25flash (Gemini 2.5 Flash) with built-in method
|
|
16
|
+
console.log("\n" + '--------| gemini25flash() |--------');
|
|
17
|
+
const flash = await mmix.gemini25flash()
|
|
18
|
+
.addText('Hi there! Do you like cats?')
|
|
19
|
+
.message();
|
|
20
|
+
|
|
21
|
+
console.log(flash);
|
|
22
|
+
|
|
23
|
+
// Using gemini3pro (Gemini 3 Pro) with custom config
|
|
24
|
+
console.log("\n" + '--------| gemini3pro() with JSON response |--------');
|
|
25
|
+
const pro = mmix.new().gemini3pro();
|
|
26
|
+
|
|
27
|
+
pro.addText('Give me a fun fact about cats');
|
|
28
|
+
const jsonResponse = await pro.json({
|
|
29
|
+
fact: 'A fun fact about cats',
|
|
30
|
+
category: 'animal behavior'
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
console.log(jsonResponse);
|
|
34
|
+
|
|
35
|
+
// Using attach method with MixGoogle for custom model
|
|
36
|
+
console.log("\n" + '--------| Custom Gemini with attach() |--------');
|
|
37
|
+
mmix.attach('gemini-2.5-flash', new MixGoogle());
|
|
38
|
+
|
|
39
|
+
const custom = await mmix.addText('Tell me a short joke about cats.').message();
|
|
40
|
+
console.log(custom);
|
|
41
|
+
|
package/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const axios = require('axios');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const { fromBuffer } = require('file-type');
|
|
4
|
+
const { inspect } = require('util');
|
|
4
5
|
const log = require('lemonlog')('ModelMix');
|
|
5
6
|
const Bottleneck = require('bottleneck');
|
|
6
7
|
const path = require('path');
|
|
@@ -46,7 +47,7 @@ class ModelMix {
|
|
|
46
47
|
replace(keyValues) {
|
|
47
48
|
this.config.replace = { ...this.config.replace, ...keyValues };
|
|
48
49
|
return this;
|
|
49
|
-
}
|
|
50
|
+
}
|
|
50
51
|
|
|
51
52
|
static new({ options = {}, config = {} } = {}) {
|
|
52
53
|
return new ModelMix({ options, config });
|
|
@@ -56,6 +57,26 @@ class ModelMix {
|
|
|
56
57
|
return new ModelMix({ options: this.options, config: this.config });
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
static formatJSON(obj) {
|
|
61
|
+
return inspect(obj, {
|
|
62
|
+
depth: null,
|
|
63
|
+
colors: true,
|
|
64
|
+
maxArrayLength: null,
|
|
65
|
+
breakLength: 80,
|
|
66
|
+
compact: false
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static formatMessage(message) {
|
|
71
|
+
if (typeof message !== 'string') return message;
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
return ModelMix.formatJSON(JSON.parse(message.trim()));
|
|
75
|
+
} catch (e) {
|
|
76
|
+
return message;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
59
80
|
attach(key, provider) {
|
|
60
81
|
|
|
61
82
|
if (this.models.some(model => model.key === key)) {
|
|
@@ -397,8 +418,11 @@ class ModelMix {
|
|
|
397
418
|
stream: false,
|
|
398
419
|
}
|
|
399
420
|
|
|
421
|
+
// Apply template replacements to system before adding extra instructions
|
|
422
|
+
let systemWithReplacements = this._template(this.config.system, this.config.replace);
|
|
423
|
+
|
|
400
424
|
let config = {
|
|
401
|
-
system:
|
|
425
|
+
system: systemWithReplacements,
|
|
402
426
|
}
|
|
403
427
|
|
|
404
428
|
if (schemaExample) {
|
|
@@ -424,8 +448,11 @@ class ModelMix {
|
|
|
424
448
|
}
|
|
425
449
|
|
|
426
450
|
async block({ addSystemExtra = true } = {}) {
|
|
451
|
+
// Apply template replacements to system before adding extra instructions
|
|
452
|
+
let systemWithReplacements = this._template(this.config.system, this.config.replace);
|
|
453
|
+
|
|
427
454
|
let config = {
|
|
428
|
-
system:
|
|
455
|
+
system: systemWithReplacements,
|
|
429
456
|
}
|
|
430
457
|
|
|
431
458
|
if (addSystemExtra) {
|
|
@@ -613,8 +640,24 @@ class ModelMix {
|
|
|
613
640
|
}
|
|
614
641
|
|
|
615
642
|
if (currentConfig.debug) {
|
|
616
|
-
log
|
|
617
|
-
|
|
643
|
+
console.log(`\nRequest successful: ${currentModelKey}`);
|
|
644
|
+
|
|
645
|
+
if (result.response) {
|
|
646
|
+
console.log('\nRAW RESPONSE:');
|
|
647
|
+
console.log(ModelMix.formatJSON(result.response));
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
if (result.message) {
|
|
651
|
+
console.log('\nMESSAGE:');
|
|
652
|
+
console.log(ModelMix.formatMessage(result.message));
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
if (result.think) {
|
|
656
|
+
console.log('\nTHINKING:');
|
|
657
|
+
console.log(result.think);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
console.log('');
|
|
618
661
|
}
|
|
619
662
|
|
|
620
663
|
return result;
|
|
@@ -624,10 +667,10 @@ class ModelMix {
|
|
|
624
667
|
log.warn(`Model ${currentModelKey} failed (Attempt #${i + 1}/${this.models.length}).`);
|
|
625
668
|
if (error.message) log.warn(`Error: ${error.message}`);
|
|
626
669
|
if (error.statusCode) log.warn(`Status Code: ${error.statusCode}`);
|
|
627
|
-
if (error.details) log.warn(`Details
|
|
670
|
+
if (error.details) log.warn(`Details:\n${ModelMix.formatJSON(error.details)}`);
|
|
628
671
|
|
|
629
672
|
if (i === this.models.length - 1) {
|
|
630
|
-
|
|
673
|
+
console.error(`All ${this.models.length} model(s) failed. Throwing last error from ${currentModelKey}.`);
|
|
631
674
|
throw lastError;
|
|
632
675
|
} else {
|
|
633
676
|
const nextModelKey = this.models[i + 1].key;
|
|
@@ -662,13 +705,13 @@ class ModelMix {
|
|
|
662
705
|
toolArgs = toolCall.input || toolCall.arguments || {};
|
|
663
706
|
toolId = toolCall.id;
|
|
664
707
|
} else {
|
|
665
|
-
|
|
708
|
+
log.error('Unknown tool call format:\n', toolCall);
|
|
666
709
|
continue;
|
|
667
710
|
}
|
|
668
711
|
|
|
669
712
|
// Validar que tenemos los datos necesarios
|
|
670
713
|
if (!toolName) {
|
|
671
|
-
|
|
714
|
+
log.error('Tool call missing name:\n', toolCall);
|
|
672
715
|
continue;
|
|
673
716
|
}
|
|
674
717
|
|
|
@@ -845,10 +888,15 @@ class MixCustom {
|
|
|
845
888
|
options.messages = this.convertMessages(options.messages, config);
|
|
846
889
|
|
|
847
890
|
if (config.debug) {
|
|
848
|
-
log
|
|
849
|
-
|
|
850
|
-
log
|
|
851
|
-
|
|
891
|
+
console.log('\nREQUEST:');
|
|
892
|
+
|
|
893
|
+
console.log('\nCONFIG:');
|
|
894
|
+
const configToLog = { ...config };
|
|
895
|
+
delete configToLog.debug;
|
|
896
|
+
console.log(ModelMix.formatJSON(configToLog));
|
|
897
|
+
|
|
898
|
+
console.log('\nOPTIONS:');
|
|
899
|
+
console.log(ModelMix.formatJSON(options));
|
|
852
900
|
}
|
|
853
901
|
|
|
854
902
|
if (options.stream) {
|
|
@@ -1120,7 +1168,7 @@ class MixAnthropic extends MixCustom {
|
|
|
1120
1168
|
} catch (error) {
|
|
1121
1169
|
// Log the error details for debugging
|
|
1122
1170
|
if (error.response && error.response.data) {
|
|
1123
|
-
|
|
1171
|
+
log.error('Anthropic API Error:\n', error.response.data);
|
|
1124
1172
|
}
|
|
1125
1173
|
throw error;
|
|
1126
1174
|
}
|
|
@@ -1636,10 +1684,15 @@ class MixGoogle extends MixCustom {
|
|
|
1636
1684
|
|
|
1637
1685
|
try {
|
|
1638
1686
|
if (config.debug) {
|
|
1639
|
-
log
|
|
1640
|
-
|
|
1641
|
-
log
|
|
1642
|
-
|
|
1687
|
+
console.log('\nREQUEST (GOOGLE):');
|
|
1688
|
+
|
|
1689
|
+
console.log('\nCONFIG:');
|
|
1690
|
+
const configToLog = { ...config };
|
|
1691
|
+
delete configToLog.debug;
|
|
1692
|
+
console.log(ModelMix.formatJSON(configToLog));
|
|
1693
|
+
|
|
1694
|
+
console.log('\nPAYLOAD:');
|
|
1695
|
+
console.log(ModelMix.formatJSON(payload));
|
|
1643
1696
|
}
|
|
1644
1697
|
|
|
1645
1698
|
if (options.stream) {
|