universal-llm-client 4.0.0 โ 4.2.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/dist/ai-model.d.ts +20 -22
- package/dist/ai-model.d.ts.map +1 -1
- package/dist/ai-model.js +26 -23
- package/dist/ai-model.js.map +1 -1
- package/dist/client.d.ts +5 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +17 -9
- package/dist/client.js.map +1 -1
- package/dist/http.d.ts +2 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +1 -0
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +49 -11
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js +14 -0
- package/dist/interfaces.js.map +1 -1
- package/dist/providers/anthropic.d.ts +56 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +524 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/google.d.ts +5 -0
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +64 -8
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +1 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/ollama.d.ts.map +1 -1
- package/dist/providers/ollama.js +38 -11
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +9 -7
- package/dist/providers/openai.js.map +1 -1
- package/dist/router.d.ts +13 -33
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +33 -57
- package/dist/router.js.map +1 -1
- package/dist/stream-decoder.d.ts +29 -2
- package/dist/stream-decoder.d.ts.map +1 -1
- package/dist/stream-decoder.js +39 -11
- package/dist/stream-decoder.js.map +1 -1
- package/dist/structured-output.d.ts +107 -181
- package/dist/structured-output.d.ts.map +1 -1
- package/dist/structured-output.js +137 -192
- package/dist/structured-output.js.map +1 -1
- package/dist/zod-adapter.d.ts +44 -0
- package/dist/zod-adapter.d.ts.map +1 -0
- package/dist/zod-adapter.js +61 -0
- package/dist/zod-adapter.js.map +1 -0
- package/package.json +9 -1
- package/src/ai-model.ts +350 -0
- package/src/auditor.ts +213 -0
- package/src/client.ts +402 -0
- package/src/debug/debug-google-streaming.ts +97 -0
- package/src/debug/debug-tool-execution.ts +86 -0
- package/src/debug/test-lmstudio-tools.ts +155 -0
- package/src/demos/README.md +47 -0
- package/src/demos/basic/universal-llm-examples.ts +161 -0
- package/src/demos/mcp/astrid-memory-demo.ts +295 -0
- package/src/demos/mcp/astrid-persona-memory.ts +357 -0
- package/src/demos/mcp/mcp-mongodb-demo.ts +275 -0
- package/src/demos/mcp/simple-astrid-memory.ts +148 -0
- package/src/demos/mcp/simple-mcp-demo.ts +68 -0
- package/src/demos/mcp/working-mcp-demo.ts +62 -0
- package/src/demos/model-alias-demo.ts +0 -0
- package/src/demos/tools/RAG_MEMORY_INTEGRATION.md +267 -0
- package/src/demos/tools/astrid-memory-demo.ts +270 -0
- package/src/demos/tools/astrid-production-memory-clean.ts +785 -0
- package/src/demos/tools/astrid-production-memory.ts +558 -0
- package/src/demos/tools/basic-translation-test.ts +66 -0
- package/src/demos/tools/chromadb-similarity-tuning.ts +390 -0
- package/src/demos/tools/clean-multilingual-conversation.ts +209 -0
- package/src/demos/tools/clean-translation-test.ts +119 -0
- package/src/demos/tools/clean-universal-multilingual-test.ts +131 -0
- package/src/demos/tools/complete-rag-demo.ts +369 -0
- package/src/demos/tools/complete-tool-demo.ts +132 -0
- package/src/demos/tools/demo-tool-calling.ts +124 -0
- package/src/demos/tools/dynamic-language-switching-test.ts +251 -0
- package/src/demos/tools/hybrid-thinking-test.ts +154 -0
- package/src/demos/tools/memory-integration-test.ts +420 -0
- package/src/demos/tools/multilingual-memory-system.ts +802 -0
- package/src/demos/tools/ondemand-translation-demo.ts +655 -0
- package/src/demos/tools/production-tool-demo.ts +245 -0
- package/src/demos/tools/revolutionary-multilingual-test.ts +151 -0
- package/src/demos/tools/rigorous-language-analysis.ts +218 -0
- package/src/demos/tools/test-universal-memory-system.ts +126 -0
- package/src/demos/tools/translation-integration-guide.ts +346 -0
- package/src/demos/tools/universal-memory-system.ts +560 -0
- package/src/http.ts +247 -0
- package/src/index.ts +161 -0
- package/src/interfaces.ts +657 -0
- package/src/mcp.ts +345 -0
- package/src/providers/anthropic.ts +762 -0
- package/src/providers/google.ts +620 -0
- package/src/providers/index.ts +8 -0
- package/src/providers/ollama.ts +469 -0
- package/src/providers/openai.ts +392 -0
- package/src/router.ts +780 -0
- package/src/stream-decoder.ts +361 -0
- package/src/structured-output.ts +759 -0
- package/src/test-scripts/test-advanced-tools.ts +310 -0
- package/src/test-scripts/test-google-streaming-enhanced.ts +147 -0
- package/src/test-scripts/test-google-streaming.ts +63 -0
- package/src/test-scripts/test-google-system-prompt-comprehensive.ts +189 -0
- package/src/test-scripts/test-mcp-config.ts +28 -0
- package/src/test-scripts/test-mcp-connection.ts +29 -0
- package/src/test-scripts/test-system-message-positions.ts +163 -0
- package/src/test-scripts/test-system-prompt-improvement-demo.ts +83 -0
- package/src/test-scripts/test-tool-calling.ts +231 -0
- package/src/tests/ai-model.test.ts +1614 -0
- package/src/tests/auditor.test.ts +224 -0
- package/src/tests/http.test.ts +200 -0
- package/src/tests/interfaces.test.ts +117 -0
- package/src/tests/providers/google.test.ts +660 -0
- package/src/tests/providers/ollama.test.ts +954 -0
- package/src/tests/providers/openai.test.ts +1122 -0
- package/src/tests/router.test.ts +254 -0
- package/src/tests/stream-decoder.test.ts +179 -0
- package/src/tests/structured-output.test.ts +1450 -0
- package/src/tests/tools.test.ts +175 -0
- package/src/tools.ts +246 -0
- package/src/zod-adapter.ts +72 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { AIModelFactory } from "../factory";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Comprehensive test for Google models with proper system prompt handling
|
|
5
|
+
* Tests both Gemini (systemInstruction) and Gemma (embedded in user prompt) approaches
|
|
6
|
+
*/
|
|
7
|
+
async function testGoogleSystemPromptHandling() {
|
|
8
|
+
console.log('๐งช Testing Google Models with Proper System Prompt Handling...\n');
|
|
9
|
+
|
|
10
|
+
// Test models with different system instruction approaches
|
|
11
|
+
const models = [
|
|
12
|
+
{
|
|
13
|
+
name: 'Gemini 2.5 Flash Lite',
|
|
14
|
+
model: 'gemini-2.5-flash-lite',
|
|
15
|
+
supportsSystemInstruction: true,
|
|
16
|
+
approach: 'Uses Google systemInstruction parameter'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'Gemma 3 27B IT',
|
|
20
|
+
model: 'gemma-3-27b-it',
|
|
21
|
+
supportsSystemInstruction: false,
|
|
22
|
+
approach: 'Embeds system prompt in user message'
|
|
23
|
+
}
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
let allTestsPassed = true;
|
|
27
|
+
|
|
28
|
+
for (const modelInfo of models) {
|
|
29
|
+
console.log(`\n๐ฌ Testing ${modelInfo.name} (${modelInfo.model})`);
|
|
30
|
+
console.log(`System approach: ${modelInfo.approach}`);
|
|
31
|
+
console.log(`System instruction parameter: ${modelInfo.supportsSystemInstruction ? 'โ
' : 'โ'}`);
|
|
32
|
+
console.log('='.repeat(70));
|
|
33
|
+
|
|
34
|
+
const googleModel = AIModelFactory.createGoogleChatModel(
|
|
35
|
+
modelInfo.model,
|
|
36
|
+
'AIzaSyBDbo7iVNEuCcRNTgDIgRrkGpFKisXXnm0'
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const testResult = await testModelSystemPrompt(googleModel, modelInfo);
|
|
40
|
+
if (!testResult) {
|
|
41
|
+
allTestsPassed = false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return { success: allTestsPassed };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function testModelSystemPrompt(googleModel: any, modelInfo: any) {
|
|
49
|
+
const modelName = modelInfo.name;
|
|
50
|
+
let testsPassed = true;
|
|
51
|
+
|
|
52
|
+
// Test 1: Basic functionality without system prompt
|
|
53
|
+
console.log(`\n--- Test 1: Basic Chat (${modelName}) ---`);
|
|
54
|
+
try {
|
|
55
|
+
console.log('Question: "What is 2+2?"');
|
|
56
|
+
|
|
57
|
+
const basicResponse = await googleModel.chat([
|
|
58
|
+
{ role: 'user', content: 'What is 2+2?' }
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
console.log('Response:', basicResponse.message.content);
|
|
62
|
+
console.log('โ
Basic chat works');
|
|
63
|
+
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error(`โ Basic chat failed for ${modelName}:`, error);
|
|
66
|
+
testsPassed = false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Test 2: System prompt with math personality
|
|
70
|
+
console.log(`\n--- Test 2: System Prompt - Math Teacher (${modelName}) ---`);
|
|
71
|
+
try {
|
|
72
|
+
console.log('System: "You are a math teacher. Always explain your answers step by step."');
|
|
73
|
+
console.log('Question: "What is 2+2?"');
|
|
74
|
+
|
|
75
|
+
const mathResponse = await googleModel.chat([
|
|
76
|
+
{ role: 'system', content: 'You are a math teacher. Always explain your answers step by step.' },
|
|
77
|
+
{ role: 'user', content: 'What is 2+2?' }
|
|
78
|
+
]);
|
|
79
|
+
|
|
80
|
+
console.log('Response:', mathResponse.message.content);
|
|
81
|
+
|
|
82
|
+
// Check if response is more detailed (indicating system prompt worked)
|
|
83
|
+
const isDetailed = mathResponse.message.content.length > 10 &&
|
|
84
|
+
(mathResponse.message.content.toLowerCase().includes('step') ||
|
|
85
|
+
mathResponse.message.content.toLowerCase().includes('add') ||
|
|
86
|
+
mathResponse.message.content.toLowerCase().includes('plus'));
|
|
87
|
+
|
|
88
|
+
if (isDetailed) {
|
|
89
|
+
console.log('โ
System prompt appears to be working - detailed explanation provided');
|
|
90
|
+
} else {
|
|
91
|
+
console.log('โ ๏ธ System prompt effectiveness unclear - response:', mathResponse.message.content);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.error(`โ Math teacher system prompt failed for ${modelName}:`, error);
|
|
96
|
+
testsPassed = false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Test 3: System prompt with personality change - streaming
|
|
100
|
+
console.log(`\n--- Test 3: System Prompt Streaming - Pirate (${modelName}) ---`);
|
|
101
|
+
try {
|
|
102
|
+
console.log('System: "You are a friendly pirate. Always use pirate language with Arrr!"');
|
|
103
|
+
console.log('Question: "Count from 1 to 3"');
|
|
104
|
+
console.log('Streaming response:');
|
|
105
|
+
console.log('---');
|
|
106
|
+
|
|
107
|
+
const pirateStream = googleModel.chatStream([
|
|
108
|
+
{ role: 'system', content: 'You are a friendly pirate. Always use pirate language with Arrr!' },
|
|
109
|
+
{ role: 'user', content: 'Count from 1 to 3' }
|
|
110
|
+
]);
|
|
111
|
+
|
|
112
|
+
let streamResponse = '';
|
|
113
|
+
for await (const chunk of pirateStream) {
|
|
114
|
+
process.stdout.write(chunk);
|
|
115
|
+
streamResponse += chunk;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
console.log('\n---');
|
|
119
|
+
|
|
120
|
+
// Check for pirate language
|
|
121
|
+
const hasPirateLanguage = streamResponse.toLowerCase().includes('arr') ||
|
|
122
|
+
streamResponse.toLowerCase().includes('matey') ||
|
|
123
|
+
streamResponse.toLowerCase().includes('ahoy') ||
|
|
124
|
+
streamResponse.toLowerCase().includes('pirate');
|
|
125
|
+
|
|
126
|
+
if (hasPirateLanguage) {
|
|
127
|
+
console.log('โ
System prompt streaming works - pirate language detected!');
|
|
128
|
+
} else {
|
|
129
|
+
console.log('โ ๏ธ System prompt streaming effectiveness unclear');
|
|
130
|
+
console.log('Response was:', streamResponse);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
} catch (error) {
|
|
134
|
+
console.error(`โ Pirate system prompt streaming failed for ${modelName}:`, error);
|
|
135
|
+
testsPassed = false;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Test 4: Complex system prompt with multiple instructions
|
|
139
|
+
console.log(`\n--- Test 4: Complex System Prompt (${modelName}) ---`);
|
|
140
|
+
try {
|
|
141
|
+
console.log('System: Complex instructions with format requirements');
|
|
142
|
+
console.log('Question: "List 3 colors"');
|
|
143
|
+
|
|
144
|
+
const complexResponse = await googleModel.chat([
|
|
145
|
+
{ role: 'system', content: 'You are a helpful assistant. Always format your lists with numbers. Always say "Here are" before your list. Keep responses very short.' },
|
|
146
|
+
{ role: 'user', content: 'List 3 colors' }
|
|
147
|
+
]);
|
|
148
|
+
|
|
149
|
+
console.log('Response:', complexResponse.message.content);
|
|
150
|
+
|
|
151
|
+
// Check if formatting instructions were followed
|
|
152
|
+
const hasNumbering = /\d+\.|\d+\)/.test(complexResponse.message.content);
|
|
153
|
+
const hasPrefix = complexResponse.message.content.toLowerCase().includes('here are');
|
|
154
|
+
|
|
155
|
+
console.log(`Numbering detected: ${hasNumbering ? 'โ
' : 'โ'}`);
|
|
156
|
+
console.log(`Prefix detected: ${hasPrefix ? 'โ
' : 'โ'}`);
|
|
157
|
+
|
|
158
|
+
if (hasNumbering || hasPrefix) {
|
|
159
|
+
console.log('โ
Complex system prompt partially effective');
|
|
160
|
+
} else {
|
|
161
|
+
console.log('โ ๏ธ Complex system prompt effectiveness unclear');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.error(`โ Complex system prompt failed for ${modelName}:`, error);
|
|
166
|
+
testsPassed = false;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
console.log(`\n๐ ${modelName} Tests Summary: ${testsPassed ? 'โ
PASSED' : 'โ FAILED'}`);
|
|
170
|
+
return testsPassed;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Run the comprehensive test
|
|
174
|
+
testGoogleSystemPromptHandling().then(result => {
|
|
175
|
+
console.log('\n' + '='.repeat(70));
|
|
176
|
+
if (result.success) {
|
|
177
|
+
console.log('๐ All tests completed successfully!');
|
|
178
|
+
console.log('\n๐ Summary:');
|
|
179
|
+
console.log('โ
Gemini models: Using systemInstruction parameter');
|
|
180
|
+
console.log('โ
Gemma models: Embedding system prompts in user messages');
|
|
181
|
+
console.log('โ
Both streaming and non-streaming work');
|
|
182
|
+
console.log('โ
Complex system prompts handled correctly');
|
|
183
|
+
} else {
|
|
184
|
+
console.log('๐ฅ Some tests failed - check output above');
|
|
185
|
+
}
|
|
186
|
+
console.log('\n๐ก Implementation now follows Google\'s recommendations:');
|
|
187
|
+
console.log(' โข Gemini: Uses systemInstruction parameter');
|
|
188
|
+
console.log(' โข Gemma: Embeds system instructions in user prompts');
|
|
189
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple test to verify MCP config loading
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { readFile } from 'fs/promises';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
|
|
8
|
+
async function testConfigLoading() {
|
|
9
|
+
try {
|
|
10
|
+
const path = join(process.cwd(), '.vscode', 'mcp.json');
|
|
11
|
+
const content = await readFile(path, 'utf-8');
|
|
12
|
+
|
|
13
|
+
console.log('Raw content:');
|
|
14
|
+
console.log(content);
|
|
15
|
+
console.log('\n' + '='.repeat(50) + '\n');
|
|
16
|
+
|
|
17
|
+
const parsed = JSON.parse(content);
|
|
18
|
+
console.log('Parsed JSON:');
|
|
19
|
+
console.log(JSON.stringify(parsed, null, 2));
|
|
20
|
+
|
|
21
|
+
console.log('\nโ
JSON parsing successful!');
|
|
22
|
+
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error('โ Error:', error);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
testConfigLoading();
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple MCP Connection Test
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { AIModelFactory } from "../factory";
|
|
6
|
+
import { MCPIntegration } from "../mcp-integration";
|
|
7
|
+
|
|
8
|
+
async function testMCPConnection() {
|
|
9
|
+
console.log('๐ Testing MCP Connection...');
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
const mcpIntegration = new MCPIntegration();
|
|
13
|
+
const model = AIModelFactory.createOllamaChatModel('qwen3:8b');
|
|
14
|
+
|
|
15
|
+
console.log('Attempting to connect to MCP servers...');
|
|
16
|
+
await mcpIntegration.connectAndRegisterTools(model);
|
|
17
|
+
|
|
18
|
+
console.log('โ
MCP connection successful!');
|
|
19
|
+
|
|
20
|
+
// Clean up
|
|
21
|
+
await mcpIntegration.disconnect();
|
|
22
|
+
console.log('โ
Disconnected successfully');
|
|
23
|
+
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error('โ MCP connection failed:', error);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
testMCPConnection();
|
|
@@ -0,0 +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
|
+
});
|
|
@@ -0,0 +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
|
+
});
|