universal-llm-client 4.2.0 โ†’ 4.5.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.
Files changed (108) hide show
  1. package/CHANGELOG.md +142 -103
  2. package/LICENSE +21 -21
  3. package/README.md +640 -591
  4. package/dist/ai-model.d.ts +12 -1
  5. package/dist/ai-model.d.ts.map +1 -1
  6. package/dist/ai-model.js +36 -1
  7. package/dist/ai-model.js.map +1 -1
  8. package/dist/gemma-channel.d.ts +14 -0
  9. package/dist/gemma-channel.d.ts.map +1 -0
  10. package/dist/gemma-channel.js +38 -0
  11. package/dist/gemma-channel.js.map +1 -0
  12. package/dist/gemma-diffusion.d.ts +49 -0
  13. package/dist/gemma-diffusion.d.ts.map +1 -0
  14. package/dist/gemma-diffusion.js +147 -0
  15. package/dist/gemma-diffusion.js.map +1 -0
  16. package/dist/http.d.ts +4 -0
  17. package/dist/http.d.ts.map +1 -1
  18. package/dist/http.js +14 -1
  19. package/dist/http.js.map +1 -1
  20. package/dist/index.d.ts +2 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +4 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/interfaces.d.ts +183 -7
  25. package/dist/interfaces.d.ts.map +1 -1
  26. package/dist/interfaces.js.map +1 -1
  27. package/dist/providers/anthropic.d.ts.map +1 -1
  28. package/dist/providers/anthropic.js +28 -3
  29. package/dist/providers/anthropic.js.map +1 -1
  30. package/dist/providers/google.d.ts +22 -1
  31. package/dist/providers/google.d.ts.map +1 -1
  32. package/dist/providers/google.js +225 -13
  33. package/dist/providers/google.js.map +1 -1
  34. package/dist/providers/ollama.d.ts +2 -0
  35. package/dist/providers/ollama.d.ts.map +1 -1
  36. package/dist/providers/ollama.js +59 -30
  37. package/dist/providers/ollama.js.map +1 -1
  38. package/dist/providers/openai.d.ts +14 -0
  39. package/dist/providers/openai.d.ts.map +1 -1
  40. package/dist/providers/openai.js +200 -22
  41. package/dist/providers/openai.js.map +1 -1
  42. package/dist/router.d.ts +2 -0
  43. package/dist/router.d.ts.map +1 -1
  44. package/dist/router.js +4 -0
  45. package/dist/router.js.map +1 -1
  46. package/dist/stream-decoder.d.ts +12 -0
  47. package/dist/stream-decoder.d.ts.map +1 -1
  48. package/dist/stream-decoder.js +182 -5
  49. package/dist/stream-decoder.js.map +1 -1
  50. package/dist/thinking.d.ts +36 -0
  51. package/dist/thinking.d.ts.map +1 -0
  52. package/dist/thinking.js +52 -0
  53. package/dist/thinking.js.map +1 -0
  54. package/package.json +118 -116
  55. package/src/ai-model.ts +400 -350
  56. package/src/auditor.ts +213 -213
  57. package/src/client.ts +402 -402
  58. package/src/debug/debug-google-streaming.ts +1 -1
  59. package/src/demos/basic/universal-llm-examples.ts +3 -3
  60. package/src/demos/diffusion-gemma/.env +29 -0
  61. package/src/demos/diffusion-gemma/.env.example +27 -0
  62. package/src/demos/diffusion-gemma/CLAUDE.md +95 -0
  63. package/src/demos/diffusion-gemma/README.md +59 -0
  64. package/src/demos/diffusion-gemma/canvas.ts +1606 -0
  65. package/src/demos/diffusion-gemma/docker-compose.yml +29 -0
  66. package/src/demos/diffusion-gemma/probe-stream.ts +51 -0
  67. package/src/demos/diffusion-gemma/probe-tools.ts +55 -0
  68. package/src/demos/diffusion-gemma/server.ts +1205 -0
  69. package/src/demos/diffusion-gemma/start-vllm.sh +98 -0
  70. package/src/gemma-channel.ts +47 -0
  71. package/src/gemma-diffusion.ts +167 -0
  72. package/src/http.ts +261 -247
  73. package/src/index.ts +180 -161
  74. package/src/interfaces.ts +843 -657
  75. package/src/mcp.ts +345 -345
  76. package/src/providers/anthropic.ts +796 -762
  77. package/src/providers/google.ts +840 -620
  78. package/src/providers/index.ts +8 -8
  79. package/src/providers/ollama.ts +503 -469
  80. package/src/providers/openai.ts +587 -392
  81. package/src/router.ts +785 -780
  82. package/src/stream-decoder.ts +535 -361
  83. package/src/structured-output.ts +759 -759
  84. package/src/test-scripts/test-google-deep-research.ts +33 -0
  85. package/src/test-scripts/test-google-streaming-enhanced.ts +147 -147
  86. package/src/test-scripts/test-google-streaming.ts +1 -1
  87. package/src/test-scripts/test-google-system-prompt-comprehensive.ts +189 -189
  88. package/src/test-scripts/test-google-thinking.ts +46 -0
  89. package/src/test-scripts/test-system-message-positions.ts +163 -163
  90. package/src/test-scripts/test-system-prompt-improvement-demo.ts +83 -83
  91. package/src/test-scripts/test-vllm-qwen36.ts +256 -0
  92. package/src/tests/ai-model.test.ts +1614 -1614
  93. package/src/tests/auditor.test.ts +224 -224
  94. package/src/tests/gemma-diffusion.test.ts +115 -0
  95. package/src/tests/http.test.ts +200 -200
  96. package/src/tests/interfaces.test.ts +117 -117
  97. package/src/tests/providers/anthropic.test.ts +118 -0
  98. package/src/tests/providers/google.test.ts +841 -660
  99. package/src/tests/providers/ollama.test.ts +1034 -954
  100. package/src/tests/providers/openai.test.ts +1511 -1122
  101. package/src/tests/router.test.ts +254 -254
  102. package/src/tests/stream-decoder.test.ts +263 -179
  103. package/src/tests/structured-output.test.ts +1450 -1450
  104. package/src/tests/thinking.test.ts +65 -0
  105. package/src/tests/tools.test.ts +175 -175
  106. package/src/thinking.ts +73 -0
  107. package/src/tools.ts +246 -246
  108. package/src/zod-adapter.ts +72 -72
@@ -1,163 +1,163 @@
1
- import { AIModelFactory } from "../factory";
2
-
3
- /**
4
- * Test to demonstrate library behavior when system messages appear at different positions
5
- */
6
- async function testSystemMessagePositions() {
7
- console.log('๐Ÿงช Testing System Message Position Behavior...\n');
8
-
9
- const models = [
10
- { name: 'Gemini 2.5 Flash Lite', model: 'gemini-2.5-flash-lite', family: 'Gemini' },
11
- { name: 'Gemma 3 27B IT', model: 'gemma-3-27b-it', family: 'Gemma' }
12
- ];
13
-
14
- for (const modelInfo of models) {
15
- console.log(`\n๐Ÿค– Testing ${modelInfo.name} (${modelInfo.family} family)`);
16
- console.log('='.repeat(70));
17
-
18
- const googleModel = AIModelFactory.createGoogleChatModel(
19
- modelInfo.model,
20
- 'AIzaSyBDbo7iVNEuCcRNTgDIgRrkGpFKisXXnm0'
21
- );
22
-
23
- await testDifferentSystemPositions(googleModel, modelInfo);
24
- }
25
- }
26
-
27
- async function testDifferentSystemPositions(googleModel: any, modelInfo: any) {
28
- // Test 1: System message at the beginning (normal case)
29
- console.log('\n--- Test 1: System Message at Beginning ---');
30
- console.log('Expected: Should work normally');
31
-
32
- try {
33
- const messages1 = [
34
- { role: 'system', content: 'You are concise. Always answer in exactly 3 words.' },
35
- { role: 'user', content: 'What is TypeScript?' }
36
- ];
37
-
38
- const response1 = await googleModel.chat(messages1);
39
- console.log('๐Ÿ“ค Response:', response1.message.content);
40
- console.log('โœ… Beginning system message: Works');
41
-
42
- } catch (error) {
43
- console.error('โŒ Beginning system message failed:', error);
44
- }
45
-
46
- // Test 2: System message in the middle of conversation
47
- console.log('\n--- Test 2: System Message in Middle ---');
48
- console.log('Current behavior: ALL system messages are processed regardless of position');
49
-
50
- try {
51
- const messages2 = [
52
- { role: 'user', content: 'Hello' },
53
- { role: 'assistant', content: 'Hi there!' },
54
- { role: 'system', content: 'From now on, be very formal and professional.' }, // Middle system message
55
- { role: 'user', content: 'What is JavaScript?' }
56
- ];
57
-
58
- const response2 = await googleModel.chat(messages2);
59
- console.log('๐Ÿ“ค Response:', response2.message.content);
60
-
61
- // Check if the response is formal (indicating the middle system message was processed)
62
- const isFormal = response2.message.content.toLowerCase().includes('formal') ||
63
- response2.message.content.includes('professional') ||
64
- response2.message.content.length > 50; // Longer responses tend to be more formal
65
-
66
- console.log(`๐Ÿ” Formality detected: ${isFormal ? 'โœ…' : 'โŒ'}`);
67
- console.log('โœ… Middle system message: Processed');
68
-
69
- } catch (error) {
70
- console.error('โŒ Middle system message failed:', error);
71
- }
72
-
73
- // Test 3: Multiple system messages at different positions
74
- console.log('\n--- Test 3: Multiple System Messages at Different Positions ---');
75
- console.log('Current behavior: ALL system messages are combined');
76
-
77
- try {
78
- const messages3 = [
79
- { role: 'system', content: 'You are a helpful assistant.' },
80
- { role: 'user', content: 'Hi' },
81
- { role: 'assistant', content: 'Hello!' },
82
- { role: 'system', content: 'Always include emojis in your responses.' }, // Second system message
83
- { role: 'user', content: 'Tell me about Python programming.' },
84
- { role: 'system', content: 'Keep responses under 50 words.' } // Third system message
85
- ];
86
-
87
- const response3 = await googleModel.chat(messages3);
88
- console.log('๐Ÿ“ค Response:', response3.message.content);
89
-
90
- // Check if all system instructions were applied
91
- const hasEmojis = /[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]/u.test(response3.message.content);
92
- const isShort = response3.message.content.split(' ').length <= 50;
93
-
94
- console.log(`๐Ÿ” Emojis present: ${hasEmojis ? 'โœ…' : 'โŒ'}`);
95
- console.log(`๐Ÿ” Under 50 words: ${isShort ? 'โœ…' : 'โŒ'}`);
96
- console.log('โœ… Multiple system messages: All processed');
97
-
98
- } catch (error) {
99
- console.error('โŒ Multiple system messages failed:', error);
100
- }
101
-
102
- // Test 4: System message at the very end
103
- console.log('\n--- Test 4: System Message at End ---');
104
- console.log('Current behavior: Still processed (all system messages are collected)');
105
-
106
- try {
107
- const messages4 = [
108
- { role: 'user', content: 'What is React?' },
109
- { role: 'assistant', content: 'React is a JavaScript library for building user interfaces.' },
110
- { role: 'user', content: 'Can you explain it differently?' },
111
- { role: 'system', content: 'Explain everything using analogies to cooking.' } // End system message
112
- ];
113
-
114
- const response4 = await googleModel.chat(messages4);
115
- console.log('๐Ÿ“ค Response:', response4.message.content);
116
-
117
- // Check if cooking analogies were used
118
- const hasCookingAnalogy = response4.message.content.toLowerCase().includes('cook') ||
119
- response4.message.content.toLowerCase().includes('recipe') ||
120
- response4.message.content.toLowerCase().includes('ingredient') ||
121
- response4.message.content.toLowerCase().includes('kitchen');
122
-
123
- console.log(`๐Ÿ” Cooking analogy detected: ${hasCookingAnalogy ? 'โœ…' : 'โŒ'}`);
124
- console.log('โœ… End system message: Processed');
125
-
126
- } catch (error) {
127
- console.error('โŒ End system message failed:', error);
128
- }
129
-
130
- console.log('\n๐Ÿ“‹ Summary for ' + modelInfo.name + ':');
131
-
132
- if (modelInfo.family === 'Gemma') {
133
- console.log('โ€ข Gemma behavior: ALL system messages are combined and embedded in FIRST user message');
134
- console.log('โ€ข Position doesn\'t matter - all system messages are processed');
135
- console.log('โ€ข System instructions apply to the entire conversation');
136
- } else {
137
- console.log('โ€ข Gemini behavior: ALL system messages are combined into systemInstruction parameter');
138
- console.log('โ€ข Position doesn\'t matter - all system messages are processed');
139
- console.log('โ€ข System instructions apply to the entire conversation');
140
- }
141
- }
142
-
143
- // Run the test
144
- testSystemMessagePositions().then(() => {
145
- console.log('\n' + '='.repeat(70));
146
- console.log('๐ŸŽฏ KEY FINDINGS:');
147
- console.log('');
148
- console.log('๐Ÿ“ CURRENT BEHAVIOR:');
149
- console.log('โ€ข System messages at ANY position are processed');
150
- console.log('โ€ข ALL system messages are combined (regardless of position)');
151
- console.log('โ€ข For Gemma: Combined system messages embedded in first user message');
152
- console.log('โ€ข For Gemini: Combined system messages sent as systemInstruction parameter');
153
- console.log('');
154
- console.log('โš ๏ธ POTENTIAL CONSIDERATIONS:');
155
- console.log('โ€ข System messages in middle of conversation might be unexpected');
156
- console.log('โ€ข Some chat paradigms expect system messages only at the beginning');
157
- console.log('โ€ข Current behavior is consistent but might not match all use cases');
158
- console.log('');
159
- console.log('โœ… RECOMMENDATION:');
160
- console.log('โ€ข For best results, place system messages at the beginning');
161
- console.log('โ€ข Current implementation is robust and handles all positions');
162
- console.log('โ€ข Consider if mid-conversation system changes should be handled differently');
163
- });
1
+ import { AIModelFactory } from "../factory";
2
+
3
+ /**
4
+ * Test to demonstrate library behavior when system messages appear at different positions
5
+ */
6
+ async function testSystemMessagePositions() {
7
+ console.log('๐Ÿงช Testing System Message Position Behavior...\n');
8
+
9
+ const models = [
10
+ { name: 'Gemini 2.5 Flash Lite', model: 'gemini-2.5-flash-lite', family: 'Gemini' },
11
+ { name: 'Gemma 3 27B IT', model: 'gemma-3-27b-it', family: 'Gemma' }
12
+ ];
13
+
14
+ for (const modelInfo of models) {
15
+ console.log(`\n๐Ÿค– Testing ${modelInfo.name} (${modelInfo.family} family)`);
16
+ console.log('='.repeat(70));
17
+
18
+ const googleModel = AIModelFactory.createGoogleChatModel(
19
+ modelInfo.model,
20
+ (process.env.GOOGLE_API_KEY ?? '')
21
+ );
22
+
23
+ await testDifferentSystemPositions(googleModel, modelInfo);
24
+ }
25
+ }
26
+
27
+ async function testDifferentSystemPositions(googleModel: any, modelInfo: any) {
28
+ // Test 1: System message at the beginning (normal case)
29
+ console.log('\n--- Test 1: System Message at Beginning ---');
30
+ console.log('Expected: Should work normally');
31
+
32
+ try {
33
+ const messages1 = [
34
+ { role: 'system', content: 'You are concise. Always answer in exactly 3 words.' },
35
+ { role: 'user', content: 'What is TypeScript?' }
36
+ ];
37
+
38
+ const response1 = await googleModel.chat(messages1);
39
+ console.log('๐Ÿ“ค Response:', response1.message.content);
40
+ console.log('โœ… Beginning system message: Works');
41
+
42
+ } catch (error) {
43
+ console.error('โŒ Beginning system message failed:', error);
44
+ }
45
+
46
+ // Test 2: System message in the middle of conversation
47
+ console.log('\n--- Test 2: System Message in Middle ---');
48
+ console.log('Current behavior: ALL system messages are processed regardless of position');
49
+
50
+ try {
51
+ const messages2 = [
52
+ { role: 'user', content: 'Hello' },
53
+ { role: 'assistant', content: 'Hi there!' },
54
+ { role: 'system', content: 'From now on, be very formal and professional.' }, // Middle system message
55
+ { role: 'user', content: 'What is JavaScript?' }
56
+ ];
57
+
58
+ const response2 = await googleModel.chat(messages2);
59
+ console.log('๐Ÿ“ค Response:', response2.message.content);
60
+
61
+ // Check if the response is formal (indicating the middle system message was processed)
62
+ const isFormal = response2.message.content.toLowerCase().includes('formal') ||
63
+ response2.message.content.includes('professional') ||
64
+ response2.message.content.length > 50; // Longer responses tend to be more formal
65
+
66
+ console.log(`๐Ÿ” Formality detected: ${isFormal ? 'โœ…' : 'โŒ'}`);
67
+ console.log('โœ… Middle system message: Processed');
68
+
69
+ } catch (error) {
70
+ console.error('โŒ Middle system message failed:', error);
71
+ }
72
+
73
+ // Test 3: Multiple system messages at different positions
74
+ console.log('\n--- Test 3: Multiple System Messages at Different Positions ---');
75
+ console.log('Current behavior: ALL system messages are combined');
76
+
77
+ try {
78
+ const messages3 = [
79
+ { role: 'system', content: 'You are a helpful assistant.' },
80
+ { role: 'user', content: 'Hi' },
81
+ { role: 'assistant', content: 'Hello!' },
82
+ { role: 'system', content: 'Always include emojis in your responses.' }, // Second system message
83
+ { role: 'user', content: 'Tell me about Python programming.' },
84
+ { role: 'system', content: 'Keep responses under 50 words.' } // Third system message
85
+ ];
86
+
87
+ const response3 = await googleModel.chat(messages3);
88
+ console.log('๐Ÿ“ค Response:', response3.message.content);
89
+
90
+ // Check if all system instructions were applied
91
+ const hasEmojis = /[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]/u.test(response3.message.content);
92
+ const isShort = response3.message.content.split(' ').length <= 50;
93
+
94
+ console.log(`๐Ÿ” Emojis present: ${hasEmojis ? 'โœ…' : 'โŒ'}`);
95
+ console.log(`๐Ÿ” Under 50 words: ${isShort ? 'โœ…' : 'โŒ'}`);
96
+ console.log('โœ… Multiple system messages: All processed');
97
+
98
+ } catch (error) {
99
+ console.error('โŒ Multiple system messages failed:', error);
100
+ }
101
+
102
+ // Test 4: System message at the very end
103
+ console.log('\n--- Test 4: System Message at End ---');
104
+ console.log('Current behavior: Still processed (all system messages are collected)');
105
+
106
+ try {
107
+ const messages4 = [
108
+ { role: 'user', content: 'What is React?' },
109
+ { role: 'assistant', content: 'React is a JavaScript library for building user interfaces.' },
110
+ { role: 'user', content: 'Can you explain it differently?' },
111
+ { role: 'system', content: 'Explain everything using analogies to cooking.' } // End system message
112
+ ];
113
+
114
+ const response4 = await googleModel.chat(messages4);
115
+ console.log('๐Ÿ“ค Response:', response4.message.content);
116
+
117
+ // Check if cooking analogies were used
118
+ const hasCookingAnalogy = response4.message.content.toLowerCase().includes('cook') ||
119
+ response4.message.content.toLowerCase().includes('recipe') ||
120
+ response4.message.content.toLowerCase().includes('ingredient') ||
121
+ response4.message.content.toLowerCase().includes('kitchen');
122
+
123
+ console.log(`๐Ÿ” Cooking analogy detected: ${hasCookingAnalogy ? 'โœ…' : 'โŒ'}`);
124
+ console.log('โœ… End system message: Processed');
125
+
126
+ } catch (error) {
127
+ console.error('โŒ End system message failed:', error);
128
+ }
129
+
130
+ console.log('\n๐Ÿ“‹ Summary for ' + modelInfo.name + ':');
131
+
132
+ if (modelInfo.family === 'Gemma') {
133
+ console.log('โ€ข Gemma behavior: ALL system messages are combined and embedded in FIRST user message');
134
+ console.log('โ€ข Position doesn\'t matter - all system messages are processed');
135
+ console.log('โ€ข System instructions apply to the entire conversation');
136
+ } else {
137
+ console.log('โ€ข Gemini behavior: ALL system messages are combined into systemInstruction parameter');
138
+ console.log('โ€ข Position doesn\'t matter - all system messages are processed');
139
+ console.log('โ€ข System instructions apply to the entire conversation');
140
+ }
141
+ }
142
+
143
+ // Run the test
144
+ testSystemMessagePositions().then(() => {
145
+ console.log('\n' + '='.repeat(70));
146
+ console.log('๐ŸŽฏ KEY FINDINGS:');
147
+ console.log('');
148
+ console.log('๐Ÿ“ CURRENT BEHAVIOR:');
149
+ console.log('โ€ข System messages at ANY position are processed');
150
+ console.log('โ€ข ALL system messages are combined (regardless of position)');
151
+ console.log('โ€ข For Gemma: Combined system messages embedded in first user message');
152
+ console.log('โ€ข For Gemini: Combined system messages sent as systemInstruction parameter');
153
+ console.log('');
154
+ console.log('โš ๏ธ POTENTIAL CONSIDERATIONS:');
155
+ console.log('โ€ข System messages in middle of conversation might be unexpected');
156
+ console.log('โ€ข Some chat paradigms expect system messages only at the beginning');
157
+ console.log('โ€ข Current behavior is consistent but might not match all use cases');
158
+ console.log('');
159
+ console.log('โœ… RECOMMENDATION:');
160
+ console.log('โ€ข For best results, place system messages at the beginning');
161
+ console.log('โ€ข Current implementation is robust and handles all positions');
162
+ console.log('โ€ข Consider if mid-conversation system changes should be handled differently');
163
+ });
@@ -1,83 +1,83 @@
1
- import { AIModelFactory } from "../factory";
2
-
3
- /**
4
- * Demonstration of improved Gemma system prompt handling
5
- * Shows the difference between Gemini (systemInstruction) and Gemma (embedded) approaches
6
- */
7
- async function demonstrateSystemPromptImprovement() {
8
- console.log('๐Ÿ”ฌ Demonstrating Improved System Prompt Handling\n');
9
- console.log('๐Ÿ“š Based on Google\'s documentation: https://ai.google.dev/gemma/docs/core/prompt-structure\n');
10
-
11
- // Test the same system prompt with both model types
12
- const systemPrompt = 'You are a helpful cooking assistant. Always provide step-by-step recipes.';
13
- const userPrompt = 'How do I make scrambled eggs?';
14
-
15
- console.log('๐Ÿงช Testing System Prompt:', systemPrompt);
16
- console.log('โ“ User Question:', userPrompt);
17
- console.log('\n' + '='.repeat(80));
18
-
19
- // Test 1: Gemini model (uses systemInstruction parameter)
20
- console.log('\n๐Ÿค– GEMINI 2.5 FLASH LITE');
21
- console.log('๐Ÿ“‹ Method: Uses Google\'s systemInstruction parameter');
22
- console.log('โœจ System prompt is sent separately from user content\n');
23
-
24
- const geminiModel = AIModelFactory.createGoogleChatModel(
25
- 'gemini-2.5-flash-lite',
26
- 'AIzaSyBDbo7iVNEuCcRNTgDIgRrkGpFKisXXnm0'
27
- );
28
-
29
- try {
30
- const geminiResponse = await geminiModel.chat([
31
- { role: 'system', content: systemPrompt },
32
- { role: 'user', content: userPrompt }
33
- ]);
34
-
35
- console.log('๐Ÿ“ค Response:', geminiResponse.message.content);
36
- console.log('โœ… Gemini system prompt working correctly\n');
37
-
38
- } catch (error) {
39
- console.error('โŒ Gemini test failed:', error);
40
- }
41
-
42
- console.log('='.repeat(80));
43
-
44
- // Test 2: Gemma model (embeds system prompt in user message)
45
- console.log('\n๐Ÿค– GEMMA 3 27B IT');
46
- console.log('๐Ÿ“‹ Method: Embeds system instructions directly in user message');
47
- console.log('โœจ System prompt is combined with first user message\n');
48
-
49
- const gemmaModel = AIModelFactory.createGoogleChatModel(
50
- 'gemma-3-27b-it',
51
- 'AIzaSyBDbo7iVNEuCcRNTgDIgRrkGpFKisXXnm0'
52
- );
53
-
54
- try {
55
- const gemmaResponse = await gemmaModel.chat([
56
- { role: 'system', content: systemPrompt },
57
- { role: 'user', content: userPrompt }
58
- ]);
59
-
60
- console.log('๐Ÿ“ค Response:', gemmaResponse.message.content);
61
- console.log('โœ… Gemma system prompt working correctly\n');
62
-
63
- } catch (error) {
64
- console.error('โŒ Gemma test failed:', error);
65
- }
66
-
67
- console.log('='.repeat(80));
68
- console.log('\n๐ŸŽฏ KEY IMPROVEMENTS:');
69
- console.log('โ€ข Gemini models: Use Google\'s systemInstruction parameter (official way)');
70
- console.log('โ€ข Gemma models: Embed system prompts in user messages (as documented)');
71
- console.log('โ€ข Automatic detection: Code detects model type and uses correct approach');
72
- console.log('โ€ข Better compliance: Follows Google\'s official documentation');
73
- console.log('โ€ข More reliable: Each model family gets the format it expects');
74
-
75
- console.log('\n๐Ÿ“– References:');
76
- console.log('โ€ข Gemma Prompt Structure: https://ai.google.dev/gemma/docs/core/prompt-structure');
77
- console.log('โ€ข Gemini API Documentation: https://ai.google.dev/gemini-api/docs');
78
- }
79
-
80
- // Run the demonstration
81
- demonstrateSystemPromptImprovement().then(() => {
82
- console.log('\n๐ŸŽ‰ Demonstration completed! Both model families now work optimally.');
83
- });
1
+ import { AIModelFactory } from "../factory";
2
+
3
+ /**
4
+ * Demonstration of improved Gemma system prompt handling
5
+ * Shows the difference between Gemini (systemInstruction) and Gemma (embedded) approaches
6
+ */
7
+ async function demonstrateSystemPromptImprovement() {
8
+ console.log('๐Ÿ”ฌ Demonstrating Improved System Prompt Handling\n');
9
+ console.log('๐Ÿ“š Based on Google\'s documentation: https://ai.google.dev/gemma/docs/core/prompt-structure\n');
10
+
11
+ // Test the same system prompt with both model types
12
+ const systemPrompt = 'You are a helpful cooking assistant. Always provide step-by-step recipes.';
13
+ const userPrompt = 'How do I make scrambled eggs?';
14
+
15
+ console.log('๐Ÿงช Testing System Prompt:', systemPrompt);
16
+ console.log('โ“ User Question:', userPrompt);
17
+ console.log('\n' + '='.repeat(80));
18
+
19
+ // Test 1: Gemini model (uses systemInstruction parameter)
20
+ console.log('\n๐Ÿค– GEMINI 2.5 FLASH LITE');
21
+ console.log('๐Ÿ“‹ Method: Uses Google\'s systemInstruction parameter');
22
+ console.log('โœจ System prompt is sent separately from user content\n');
23
+
24
+ const geminiModel = AIModelFactory.createGoogleChatModel(
25
+ 'gemini-2.5-flash-lite',
26
+ (process.env.GOOGLE_API_KEY ?? '')
27
+ );
28
+
29
+ try {
30
+ const geminiResponse = await geminiModel.chat([
31
+ { role: 'system', content: systemPrompt },
32
+ { role: 'user', content: userPrompt }
33
+ ]);
34
+
35
+ console.log('๐Ÿ“ค Response:', geminiResponse.message.content);
36
+ console.log('โœ… Gemini system prompt working correctly\n');
37
+
38
+ } catch (error) {
39
+ console.error('โŒ Gemini test failed:', error);
40
+ }
41
+
42
+ console.log('='.repeat(80));
43
+
44
+ // Test 2: Gemma model (embeds system prompt in user message)
45
+ console.log('\n๐Ÿค– GEMMA 3 27B IT');
46
+ console.log('๐Ÿ“‹ Method: Embeds system instructions directly in user message');
47
+ console.log('โœจ System prompt is combined with first user message\n');
48
+
49
+ const gemmaModel = AIModelFactory.createGoogleChatModel(
50
+ 'gemma-3-27b-it',
51
+ (process.env.GOOGLE_API_KEY ?? '')
52
+ );
53
+
54
+ try {
55
+ const gemmaResponse = await gemmaModel.chat([
56
+ { role: 'system', content: systemPrompt },
57
+ { role: 'user', content: userPrompt }
58
+ ]);
59
+
60
+ console.log('๐Ÿ“ค Response:', gemmaResponse.message.content);
61
+ console.log('โœ… Gemma system prompt working correctly\n');
62
+
63
+ } catch (error) {
64
+ console.error('โŒ Gemma test failed:', error);
65
+ }
66
+
67
+ console.log('='.repeat(80));
68
+ console.log('\n๐ŸŽฏ KEY IMPROVEMENTS:');
69
+ console.log('โ€ข Gemini models: Use Google\'s systemInstruction parameter (official way)');
70
+ console.log('โ€ข Gemma models: Embed system prompts in user messages (as documented)');
71
+ console.log('โ€ข Automatic detection: Code detects model type and uses correct approach');
72
+ console.log('โ€ข Better compliance: Follows Google\'s official documentation');
73
+ console.log('โ€ข More reliable: Each model family gets the format it expects');
74
+
75
+ console.log('\n๐Ÿ“– References:');
76
+ console.log('โ€ข Gemma Prompt Structure: https://ai.google.dev/gemma/docs/core/prompt-structure');
77
+ console.log('โ€ข Gemini API Documentation: https://ai.google.dev/gemini-api/docs');
78
+ }
79
+
80
+ // Run the demonstration
81
+ demonstrateSystemPromptImprovement().then(() => {
82
+ console.log('\n๐ŸŽ‰ Demonstration completed! Both model families now work optimally.');
83
+ });