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 CHANGED
@@ -1,5 +1,5 @@
1
1
  import 'dotenv/config';
2
- import { ModelMix, MixOpenAI, MixAnthropic, MixPerplexity, MixOllama } from '../index.js';
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
- console.log(await gpt.json({ time: '24:00:00', message: 'Hello' }, { time: 'Time in format HH:MM:SS' }));
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: this.config.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: this.config.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.debug(`Request successful with model: ${currentModelKey}`);
617
- log.inspect(result.response);
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: ${JSON.stringify(error.details)}`);
670
+ if (error.details) log.warn(`Details:\n${ModelMix.formatJSON(error.details)}`);
628
671
 
629
672
  if (i === this.models.length - 1) {
630
- log.error(`All ${this.models.length} model(s) failed. Throwing last error from ${currentModelKey}.`);
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
- console.error('Unknown tool call format:', JSON.stringify(toolCall, null, 2));
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
- console.error('Tool call missing name:', JSON.stringify(toolCall, null, 2));
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.debug("config");
849
- log.info(config);
850
- log.debug("options");
851
- log.inspect(options);
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
- console.error('Anthropic API Error:', JSON.stringify(error.response.data, null, 2));
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.debug("config");
1640
- log.info(config);
1641
- log.debug("payload");
1642
- log.inspect(payload);
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "modelmix",
3
- "version": "4.0.8",
3
+ "version": "4.1.0",
4
4
  "description": "🧬 ModelMix - Unified API for Diverse AI LLM.",
5
5
  "main": "index.js",
6
6
  "repository": {