modelmix 4.2.4 → 4.2.6

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.
Files changed (3) hide show
  1. package/demo/verbose.js +103 -0
  2. package/index.js +44 -30
  3. package/package.json +1 -1
@@ -0,0 +1,103 @@
1
+ process.loadEnvFile();
2
+ import { ModelMix, MixOpenAI } from '../index.js';
3
+
4
+ const prompt = "Say 'Hello World' in exactly 2 words.";
5
+
6
+ console.log('═══════════════════════════════════════════════════════════════');
7
+ console.log('DEMO: Verbose Modes in ModelMix');
8
+ console.log('═══════════════════════════════════════════════════════════════\n');
9
+
10
+
11
+ // ===================================================================
12
+ // VERBOSE LEVEL 0 - Silent Mode
13
+ // ===================================================================
14
+ console.log('─────────────────────────────────────────────────────────────');
15
+ console.log('1. VERBOSE LEVEL 0 - Silent Mode');
16
+ console.log(' No output at all, only the result');
17
+ console.log('─────────────────────────────────────────────────────────────\n');
18
+
19
+ await ModelMix
20
+ .new({ config: { verbose: 0 } })
21
+ .gpt41nano()
22
+ .addText(prompt)
23
+ .message();
24
+
25
+
26
+ // ===================================================================
27
+ // VERBOSE LEVEL 1 - Minimal Mode
28
+ // ===================================================================
29
+ console.log('─────────────────────────────────────────────────────────────');
30
+ console.log('2. VERBOSE LEVEL 1 - Minimal Mode');
31
+ console.log(' Shows: → [model] #N and ✓ Success');
32
+ console.log('─────────────────────────────────────────────────────────────\n');
33
+
34
+ await ModelMix
35
+ .new({ config: { verbose: 1 } })
36
+ .gpt41nano()
37
+ .addText(prompt)
38
+ .message();
39
+
40
+ // ===================================================================
41
+ // VERBOSE LEVEL 2 - Readable Summary (DEFAULT)
42
+ // ===================================================================
43
+ console.log('─────────────────────────────────────────────────────────────');
44
+ console.log('3. VERBOSE LEVEL 2 - Readable Summary (DEFAULT)');
45
+ console.log(' Shows: model, system prompt, input, message count, output');
46
+ console.log(' Everything in compact format on 2 lines');
47
+ console.log('─────────────────────────────────────────────────────────────\n');
48
+
49
+ await ModelMix
50
+ .new({ config: { verbose: 2 } })
51
+ .gpt41nano()
52
+ .addText(prompt)
53
+ .json({ message: 'string' });
54
+
55
+ // ===================================================================
56
+ // VERBOSE LEVEL 3 - Full Debug
57
+ // ===================================================================
58
+ console.log('─────────────────────────────────────────────────────────────');
59
+ console.log('4. VERBOSE LEVEL 3 - Full Debug Mode');
60
+ console.log(' Shows: everything from level 2 + raw response, full message,');
61
+ console.log(' request details, config, and options');
62
+ console.log('─────────────────────────────────────────────────────────────\n');
63
+
64
+ await ModelMix
65
+ .new({ config: { verbose: 3 } })
66
+ .gpt41nano()
67
+ .addText(prompt)
68
+ .message();
69
+
70
+ // ===================================================================
71
+ // FALLBACK EXAMPLE (with verbose 2)
72
+ // ===================================================================
73
+ console.log('─────────────────────────────────────────────────────────────');
74
+ console.log('5. FALLBACK EXAMPLE (Verbose Level 2)');
75
+ console.log(' Shows how fallback models are displayed');
76
+ console.log('─────────────────────────────────────────────────────────────\n');
77
+
78
+ try {
79
+ const resultFallback = await ModelMix
80
+ .new({ config: { verbose: 2 } })
81
+ .attach('fake-model-that-will-fail', new MixOpenAI())
82
+ .gpt41nano() // This will be the fallback
83
+ .addText(prompt)
84
+ .message();
85
+
86
+ console.log(`Result: ${resultFallback}\n`);
87
+ } catch (error) {
88
+ console.log(`Error (should not happen): ${error.message}\n`);
89
+ }
90
+
91
+
92
+ // ===================================================================
93
+ // SUMMARY
94
+ // ===================================================================
95
+ console.log('═══════════════════════════════════════════════════════════════');
96
+ console.log('DEMO COMPLETED');
97
+ console.log('═══════════════════════════════════════════════════════════════\n');
98
+ console.log('Summary:');
99
+ console.log(' - Level 0: Silent, no logs');
100
+ console.log(' - Level 1: Minimal (→ model, ✓ Success)');
101
+ console.log(' - Level 2: Readable (1 line input + 1 line output) [DEFAULT]');
102
+ console.log(' - Level 3: Full debug (includes raw responses and configs)');
103
+ console.log('');
package/index.js CHANGED
@@ -46,7 +46,6 @@ class ModelMix {
46
46
 
47
47
  }
48
48
 
49
-
50
49
  replace(keyValues) {
51
50
  this.config.replace = { ...this.config.replace, ...keyValues };
52
51
  return this;
@@ -109,26 +108,38 @@ class ModelMix {
109
108
  inputText = lastMessage.content;
110
109
  }
111
110
 
112
- const lines = [];
113
- lines.push(` 📝 System: ${ModelMix.truncate(system, 60)}`);
114
- lines.push(` 💬 Input: ${ModelMix.truncate(inputText, 150)}`);
115
- lines.push(` 📊 Messages: ${messages.length}`);
116
- return lines.join('\n');
111
+ const systemStr = `System: ${ModelMix.truncate(system, 50)}`;
112
+ const inputStr = `Input: ${ModelMix.truncate(inputText, 120)}`;
113
+ const msgCount = `(${messages.length} msg${messages.length !== 1 ? 's' : ''})`;
114
+
115
+ return `${systemStr} \n| ${inputStr} ${msgCount}`;
117
116
  }
118
117
 
119
- static formatOutputSummary(result) {
120
- const lines = [];
118
+ static formatOutputSummary(result, verboseLevel = 2) {
119
+ const parts = [];
121
120
  if (result.message) {
122
- lines.push(` 📤 Output: ${ModelMix.truncate(result.message, 200)}`);
121
+ // Try to parse as JSON for better formatting
122
+ try {
123
+ const parsed = JSON.parse(result.message.trim());
124
+ // If it's valid JSON and verbose >= 2, show it formatted
125
+ if (verboseLevel >= 2) {
126
+ parts.push(`Output (JSON):\n${ModelMix.formatJSON(parsed)}`);
127
+ } else {
128
+ parts.push(`Output: ${ModelMix.truncate(result.message, 150)}`);
129
+ }
130
+ } catch (e) {
131
+ // Not JSON, show truncated as before
132
+ parts.push(`Output: ${ModelMix.truncate(result.message, 150)}`);
133
+ }
123
134
  }
124
135
  if (result.think) {
125
- lines.push(` 🧠 Thinking: ${ModelMix.truncate(result.think, 100)}`);
136
+ parts.push(`Thinking: ${ModelMix.truncate(result.think, 80)}`);
126
137
  }
127
138
  if (result.toolCalls && result.toolCalls.length > 0) {
128
139
  const toolNames = result.toolCalls.map(t => t.function?.name || t.name).join(', ');
129
- lines.push(` 🔧 Tools: ${toolNames}`);
140
+ parts.push(`Tools: ${toolNames}`);
130
141
  }
131
- return lines.join('\n');
142
+ return parts.join(' | ');
132
143
  }
133
144
 
134
145
  attach(key, provider) {
@@ -714,12 +725,15 @@ class ModelMix {
714
725
 
715
726
  if (verboseLevel >= 1) {
716
727
  const isPrimary = i === 0;
717
- const tag = isPrimary ? '🚀' : '🔄';
718
- console.log(`\n${tag} [${currentModelKey}] Attempt #${i + 1}` + (isPrimary ? '' : ' (Fallback)'));
719
- }
720
-
721
- if (verboseLevel >= 2) {
722
- console.log(ModelMix.formatInputSummary(this.messages, currentConfig.system));
728
+ const prefix = isPrimary ? '' : '';
729
+ const suffix = isPrimary ? '' : ' (fallback)';
730
+ const header = `\n${prefix} [${currentModelKey}] #${i + 1}${suffix}`;
731
+
732
+ if (verboseLevel >= 2) {
733
+ console.log(`${header} | ${ModelMix.formatInputSummary(this.messages, currentConfig.system)}`);
734
+ } else {
735
+ console.log(header);
736
+ }
723
737
  }
724
738
 
725
739
  try {
@@ -754,29 +768,29 @@ class ModelMix {
754
768
  }
755
769
 
756
770
  // Verbose level 1: Just success indicator
757
- if (verboseLevel >= 1) {
758
- console.log(` ✅ Success`);
771
+ if (verboseLevel === 1) {
772
+ console.log(`✓ Success`);
759
773
  }
760
774
 
761
775
  // Verbose level 2: Readable summary of output
762
776
  if (verboseLevel >= 2) {
763
- console.log(ModelMix.formatOutputSummary(result));
777
+ console.log(`✓ ${ModelMix.formatOutputSummary(result, verboseLevel).trim()}`);
764
778
  }
765
779
 
766
780
  // Verbose level 3 (debug): Full response details
767
781
  if (verboseLevel >= 3) {
768
782
  if (result.response) {
769
- console.log('\n 📦 RAW RESPONSE:');
783
+ console.log('\n[RAW RESPONSE]');
770
784
  console.log(ModelMix.formatJSON(result.response));
771
785
  }
772
786
 
773
787
  if (result.message) {
774
- console.log('\n 💬 FULL MESSAGE:');
788
+ console.log('\n[FULL MESSAGE]');
775
789
  console.log(ModelMix.formatMessage(result.message));
776
790
  }
777
791
 
778
792
  if (result.think) {
779
- console.log('\n 🧠 FULL THINKING:');
793
+ console.log('\n[FULL THINKING]');
780
794
  console.log(result.think);
781
795
  }
782
796
  }
@@ -1014,15 +1028,15 @@ class MixCustom {
1014
1028
 
1015
1029
  // Verbose level 3 (debug): Full request details
1016
1030
  if (verboseLevel >= 3) {
1017
- console.log('\n 📡 REQUEST DETAILS:');
1031
+ console.log('\n[REQUEST DETAILS]');
1018
1032
 
1019
- console.log('\n ⚙️ CONFIG:');
1033
+ console.log('\n[CONFIG]');
1020
1034
  const configToLog = { ...config };
1021
1035
  delete configToLog.debug;
1022
1036
  delete configToLog.verbose;
1023
1037
  console.log(ModelMix.formatJSON(configToLog));
1024
1038
 
1025
- console.log('\n 📋 OPTIONS:');
1039
+ console.log('\n[OPTIONS]');
1026
1040
  console.log(ModelMix.formatJSON(options));
1027
1041
  }
1028
1042
 
@@ -1845,15 +1859,15 @@ class MixGoogle extends MixCustom {
1845
1859
 
1846
1860
  // Verbose level 3 (debug): Full request details
1847
1861
  if (verboseLevel >= 3) {
1848
- console.log('\n 📡 REQUEST DETAILS (GOOGLE):');
1862
+ console.log('\n[REQUEST DETAILS - GOOGLE]');
1849
1863
 
1850
- console.log('\n ⚙️ CONFIG:');
1864
+ console.log('\n[CONFIG]');
1851
1865
  const configToLog = { ...config };
1852
1866
  delete configToLog.debug;
1853
1867
  delete configToLog.verbose;
1854
1868
  console.log(ModelMix.formatJSON(configToLog));
1855
1869
 
1856
- console.log('\n 📋 PAYLOAD:');
1870
+ console.log('\n[PAYLOAD]');
1857
1871
  console.log(ModelMix.formatJSON(payload));
1858
1872
  }
1859
1873
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "modelmix",
3
- "version": "4.2.4",
3
+ "version": "4.2.6",
4
4
  "description": "🧬 Reliable interface with automatic fallback for AI LLMs.",
5
5
  "main": "index.js",
6
6
  "repository": {