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.
Files changed (127) hide show
  1. package/dist/ai-model.d.ts +20 -22
  2. package/dist/ai-model.d.ts.map +1 -1
  3. package/dist/ai-model.js +26 -23
  4. package/dist/ai-model.js.map +1 -1
  5. package/dist/client.d.ts +5 -5
  6. package/dist/client.d.ts.map +1 -1
  7. package/dist/client.js +17 -9
  8. package/dist/client.js.map +1 -1
  9. package/dist/http.d.ts +2 -0
  10. package/dist/http.d.ts.map +1 -1
  11. package/dist/http.js +1 -0
  12. package/dist/http.js.map +1 -1
  13. package/dist/index.d.ts +3 -3
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +4 -4
  16. package/dist/index.js.map +1 -1
  17. package/dist/interfaces.d.ts +49 -11
  18. package/dist/interfaces.d.ts.map +1 -1
  19. package/dist/interfaces.js +14 -0
  20. package/dist/interfaces.js.map +1 -1
  21. package/dist/providers/anthropic.d.ts +56 -0
  22. package/dist/providers/anthropic.d.ts.map +1 -0
  23. package/dist/providers/anthropic.js +524 -0
  24. package/dist/providers/anthropic.js.map +1 -0
  25. package/dist/providers/google.d.ts +5 -0
  26. package/dist/providers/google.d.ts.map +1 -1
  27. package/dist/providers/google.js +64 -8
  28. package/dist/providers/google.js.map +1 -1
  29. package/dist/providers/index.d.ts +1 -0
  30. package/dist/providers/index.d.ts.map +1 -1
  31. package/dist/providers/index.js +1 -0
  32. package/dist/providers/index.js.map +1 -1
  33. package/dist/providers/ollama.d.ts.map +1 -1
  34. package/dist/providers/ollama.js +38 -11
  35. package/dist/providers/ollama.js.map +1 -1
  36. package/dist/providers/openai.d.ts.map +1 -1
  37. package/dist/providers/openai.js +9 -7
  38. package/dist/providers/openai.js.map +1 -1
  39. package/dist/router.d.ts +13 -33
  40. package/dist/router.d.ts.map +1 -1
  41. package/dist/router.js +33 -57
  42. package/dist/router.js.map +1 -1
  43. package/dist/stream-decoder.d.ts +29 -2
  44. package/dist/stream-decoder.d.ts.map +1 -1
  45. package/dist/stream-decoder.js +39 -11
  46. package/dist/stream-decoder.js.map +1 -1
  47. package/dist/structured-output.d.ts +107 -181
  48. package/dist/structured-output.d.ts.map +1 -1
  49. package/dist/structured-output.js +137 -192
  50. package/dist/structured-output.js.map +1 -1
  51. package/dist/zod-adapter.d.ts +44 -0
  52. package/dist/zod-adapter.d.ts.map +1 -0
  53. package/dist/zod-adapter.js +61 -0
  54. package/dist/zod-adapter.js.map +1 -0
  55. package/package.json +9 -1
  56. package/src/ai-model.ts +350 -0
  57. package/src/auditor.ts +213 -0
  58. package/src/client.ts +402 -0
  59. package/src/debug/debug-google-streaming.ts +97 -0
  60. package/src/debug/debug-tool-execution.ts +86 -0
  61. package/src/debug/test-lmstudio-tools.ts +155 -0
  62. package/src/demos/README.md +47 -0
  63. package/src/demos/basic/universal-llm-examples.ts +161 -0
  64. package/src/demos/mcp/astrid-memory-demo.ts +295 -0
  65. package/src/demos/mcp/astrid-persona-memory.ts +357 -0
  66. package/src/demos/mcp/mcp-mongodb-demo.ts +275 -0
  67. package/src/demos/mcp/simple-astrid-memory.ts +148 -0
  68. package/src/demos/mcp/simple-mcp-demo.ts +68 -0
  69. package/src/demos/mcp/working-mcp-demo.ts +62 -0
  70. package/src/demos/model-alias-demo.ts +0 -0
  71. package/src/demos/tools/RAG_MEMORY_INTEGRATION.md +267 -0
  72. package/src/demos/tools/astrid-memory-demo.ts +270 -0
  73. package/src/demos/tools/astrid-production-memory-clean.ts +785 -0
  74. package/src/demos/tools/astrid-production-memory.ts +558 -0
  75. package/src/demos/tools/basic-translation-test.ts +66 -0
  76. package/src/demos/tools/chromadb-similarity-tuning.ts +390 -0
  77. package/src/demos/tools/clean-multilingual-conversation.ts +209 -0
  78. package/src/demos/tools/clean-translation-test.ts +119 -0
  79. package/src/demos/tools/clean-universal-multilingual-test.ts +131 -0
  80. package/src/demos/tools/complete-rag-demo.ts +369 -0
  81. package/src/demos/tools/complete-tool-demo.ts +132 -0
  82. package/src/demos/tools/demo-tool-calling.ts +124 -0
  83. package/src/demos/tools/dynamic-language-switching-test.ts +251 -0
  84. package/src/demos/tools/hybrid-thinking-test.ts +154 -0
  85. package/src/demos/tools/memory-integration-test.ts +420 -0
  86. package/src/demos/tools/multilingual-memory-system.ts +802 -0
  87. package/src/demos/tools/ondemand-translation-demo.ts +655 -0
  88. package/src/demos/tools/production-tool-demo.ts +245 -0
  89. package/src/demos/tools/revolutionary-multilingual-test.ts +151 -0
  90. package/src/demos/tools/rigorous-language-analysis.ts +218 -0
  91. package/src/demos/tools/test-universal-memory-system.ts +126 -0
  92. package/src/demos/tools/translation-integration-guide.ts +346 -0
  93. package/src/demos/tools/universal-memory-system.ts +560 -0
  94. package/src/http.ts +247 -0
  95. package/src/index.ts +161 -0
  96. package/src/interfaces.ts +657 -0
  97. package/src/mcp.ts +345 -0
  98. package/src/providers/anthropic.ts +762 -0
  99. package/src/providers/google.ts +620 -0
  100. package/src/providers/index.ts +8 -0
  101. package/src/providers/ollama.ts +469 -0
  102. package/src/providers/openai.ts +392 -0
  103. package/src/router.ts +780 -0
  104. package/src/stream-decoder.ts +361 -0
  105. package/src/structured-output.ts +759 -0
  106. package/src/test-scripts/test-advanced-tools.ts +310 -0
  107. package/src/test-scripts/test-google-streaming-enhanced.ts +147 -0
  108. package/src/test-scripts/test-google-streaming.ts +63 -0
  109. package/src/test-scripts/test-google-system-prompt-comprehensive.ts +189 -0
  110. package/src/test-scripts/test-mcp-config.ts +28 -0
  111. package/src/test-scripts/test-mcp-connection.ts +29 -0
  112. package/src/test-scripts/test-system-message-positions.ts +163 -0
  113. package/src/test-scripts/test-system-prompt-improvement-demo.ts +83 -0
  114. package/src/test-scripts/test-tool-calling.ts +231 -0
  115. package/src/tests/ai-model.test.ts +1614 -0
  116. package/src/tests/auditor.test.ts +224 -0
  117. package/src/tests/http.test.ts +200 -0
  118. package/src/tests/interfaces.test.ts +117 -0
  119. package/src/tests/providers/google.test.ts +660 -0
  120. package/src/tests/providers/ollama.test.ts +954 -0
  121. package/src/tests/providers/openai.test.ts +1122 -0
  122. package/src/tests/router.test.ts +254 -0
  123. package/src/tests/stream-decoder.test.ts +179 -0
  124. package/src/tests/structured-output.test.ts +1450 -0
  125. package/src/tests/tools.test.ts +175 -0
  126. package/src/tools.ts +246 -0
  127. package/src/zod-adapter.ts +72 -0
@@ -0,0 +1,357 @@
1
+ /**
2
+ * Astrid Persona Memory Integration - Real ChromaDB Integration
3
+ *
4
+ * This shows how to integrate memory tools with the actual AuraPersona system
5
+ * and ChromaDBService for production use.
6
+ */
7
+
8
+ import { AIModelFactory } from '../../factory';
9
+ import { ToolBuilder } from '../../tools';
10
+ import { Gender } from '../../../../../src/models/AuraPersona.js';
11
+
12
+ // Type definitions for the persona system
13
+ interface PersonaTraits {
14
+ age?: number;
15
+ gender?: string;
16
+ profession?: string;
17
+ interests?: string[];
18
+ personality?: string[];
19
+ location?: string;
20
+ relationshipStatus?: string;
21
+ }
22
+
23
+ interface AuraPersona {
24
+ _id?: string;
25
+ name: string;
26
+ bio?: string;
27
+ systemPrompt: string;
28
+ purpose: string;
29
+ traits?: PersonaTraits;
30
+ }
31
+
32
+ interface UserPersona {
33
+ _id?: string;
34
+ userId: string;
35
+ basePersonaId: string;
36
+ currentSystemPrompt: string;
37
+ evolutionVersion: number;
38
+ messagesSinceLastEvolution: number;
39
+ isActive: boolean;
40
+ }
41
+
42
+ // Astrid persona definition (matching the real persona structure)
43
+ const astridPersona: AuraPersona = {
44
+ name: 'Astrid',
45
+ purpose: 'ROMANCE',
46
+ bio: 'A captivating international model and digital influencer who combines Swedish elegance with global sophistication.',
47
+ systemPrompt: `You are Astrid, a confident and charismatic international model and influencer.
48
+
49
+ AUTONOMOUS MEMORY USAGE:
50
+ - Use memory tools naturally during conversation - don't announce you're doing it
51
+ - Store meaningful details about the user: preferences, experiences, emotions, goals, relationships
52
+ - Recall relevant memories to personalize responses and show genuine interest
53
+ - Build continuity and deeper emotional connections through remembered details
54
+
55
+ ROMANCE CONVERSATION GUIDELINES:
56
+ - Keep responses engaging and conversational (2-3 sentences is perfect for meaningful exchange)
57
+ - VARY YOUR OPENINGS - Don't always start responses the same way! Mix it up with:
58
+ * Direct reactions: "That's so sweet!", "I love that!", "Honestly...", "You know what?"
59
+ * Actions: "*smiles warmly*", "*looks into your eyes*", "*bites my lip playfully*"
60
+ * Casual starts: "So...", "Actually...", "Listen...", "Wait...", "Mmm..."
61
+ * Natural responses: "Yes!", "Oh my god!", "Seriously?", "I can't believe..."
62
+ - Use someone's name naturally and sparingly, not in every response
63
+ - Share glimpses of your glamorous lifestyle while staying relatable and emotionally available
64
+ - Use subtle flirtation naturally - be warm, playful, and genuinely interested in the person
65
+ - When asked personal questions, be thoughtfully vulnerable rather than deflecting
66
+ - Build emotional intimacy through genuine curiosity about their thoughts, feelings, and dreams
67
+ - Ask one intriguing follow-up question that deepens the connection
68
+ - Balance confidence with authenticity - show that you're sophisticated but real
69
+ - Use compliments that feel genuine and specific rather than generic
70
+ - Remember that romance is about emotional connection, not just surface-level charm
71
+
72
+ Be like a captivating companion who makes every conversation special while naturally remembering everything important about the person you're talking to.`,
73
+ traits: {
74
+ age: 27,
75
+ gender: Gender.FEMALE,
76
+ profession: 'International model and digital influencer',
77
+ interests: ['fashion photography', 'luxury travel', 'fitness and wellness', 'fine dining', 'art galleries'],
78
+ personality: ['confident', 'charismatic', 'sophisticated', 'playful'],
79
+ location: 'Stockholm, Sweden (travels globally)',
80
+ relationshipStatus: 'single'
81
+ }
82
+ };
83
+
84
+ // Memory tools that would integrate with ChromaDBService
85
+ const createPersonaMemoryTools = (userId: string, userPersonaId: string) => {
86
+
87
+ // Tool to store user insights naturally during conversation
88
+ const storePersonaMemory = ToolBuilder.createTool<{
89
+ content: string;
90
+ category: 'personal_info' | 'preferences' | 'emotions' | 'experiences' | 'relationships' | 'goals' | 'interests' | 'events';
91
+ importance?: 'low' | 'medium' | 'high';
92
+ emotionalContext?: string;
93
+ relationshipStage?: string;
94
+ }>(
95
+ 'store_persona_memory',
96
+ 'Store important information about the user for building deeper connection (use automatically when learning meaningful details)',
97
+ {
98
+ properties: {
99
+ content: {
100
+ type: 'string',
101
+ description: 'Important information about the user to remember'
102
+ },
103
+ category: {
104
+ type: 'string',
105
+ description: 'Type of information',
106
+ enum: ['personal_info', 'preferences', 'emotions', 'experiences', 'relationships', 'goals', 'interests', 'events']
107
+ },
108
+ importance: {
109
+ type: 'string',
110
+ description: 'How significant this is for the relationship',
111
+ enum: ['low', 'medium', 'high'],
112
+ default: 'medium'
113
+ },
114
+ emotionalContext: {
115
+ type: 'string',
116
+ description: 'Emotional state or context when this was shared'
117
+ },
118
+ relationshipStage: {
119
+ type: 'string',
120
+ description: 'Stage of relationship when this was learned'
121
+ }
122
+ },
123
+ required: ['content', 'category']
124
+ },
125
+ async (args) => {
126
+ // In real implementation, this would call ChromaDBService.addInsight()
127
+ console.log(`šŸ’¾ [Memory] Storing: ${args.content} (${args.category})`);
128
+
129
+ // Simulate ChromaDBService.addInsight() call
130
+ const insightId = `insight_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
131
+
132
+ // This would be the actual call:
133
+ // await chromaDBService.addInsight(
134
+ // userId,
135
+ // args.content,
136
+ // args.category,
137
+ // conversationId, // current conversation ID
138
+ // args.importance === 'high' ? 0.9 : args.importance === 'medium' ? 0.7 : 0.5,
139
+ // userPersonaId,
140
+ // astridPersona._id || 'astrid_base_persona',
141
+ // 'persona_insight',
142
+ // messageIndex, // current message index
143
+ // args.emotionalContext,
144
+ // args.relationshipStage
145
+ // );
146
+
147
+ return {
148
+ success: true,
149
+ insightId,
150
+ message: `Remembered: ${args.content.substring(0, 50)}...`
151
+ };
152
+ }
153
+ );
154
+
155
+ // Tool to recall relevant memories for personalizing responses
156
+ const recallPersonaMemories = ToolBuilder.createTool<{
157
+ query: string;
158
+ category?: string;
159
+ limit?: number;
160
+ minSimilarity?: number;
161
+ }>(
162
+ 'recall_persona_memories',
163
+ 'Recall relevant information about the user to personalize the conversation (use to reference past conversations)',
164
+ {
165
+ properties: {
166
+ query: {
167
+ type: 'string',
168
+ description: 'What to search for in memory about the user'
169
+ },
170
+ category: {
171
+ type: 'string',
172
+ description: 'Optional: specific type of memory',
173
+ enum: ['personal_info', 'preferences', 'emotions', 'experiences', 'relationships', 'goals', 'interests', 'events']
174
+ },
175
+ limit: {
176
+ type: 'number',
177
+ description: 'Maximum memories to retrieve',
178
+ default: 3,
179
+ minimum: 1,
180
+ maximum: 10
181
+ },
182
+ minSimilarity: {
183
+ type: 'number',
184
+ description: 'Minimum similarity threshold',
185
+ default: 0.3,
186
+ minimum: 0.1,
187
+ maximum: 1.0
188
+ }
189
+ },
190
+ required: ['query']
191
+ },
192
+ async (args) => {
193
+ console.log(`šŸ” [Memory] Recalling: ${args.query}`);
194
+
195
+ // In real implementation, this would call ChromaDBService.searchSimilarInsights()
196
+ // const results = await chromaDBService.searchSimilarInsights(
197
+ // userId,
198
+ // args.query,
199
+ // args.limit || 3,
200
+ // args.minSimilarity || 0.3
201
+ // );
202
+
203
+ // Simulate memory retrieval
204
+ const mockMemories = [
205
+ {
206
+ content: "Works as a software engineer at a tech startup in Stockholm",
207
+ category: "personal_info",
208
+ importance: "high",
209
+ similarity: 0.85,
210
+ daysAgo: 2
211
+ },
212
+ {
213
+ content: "Just moved to Stockholm and doesn't know anyone yet",
214
+ category: "experiences",
215
+ importance: "medium",
216
+ similarity: 0.78,
217
+ daysAgo: 2
218
+ },
219
+ {
220
+ content: "Is introverted and gets nervous at big social events",
221
+ category: "personal_info",
222
+ importance: "high",
223
+ similarity: 0.72,
224
+ daysAgo: 1
225
+ }
226
+ ];
227
+
228
+ return {
229
+ memories: mockMemories.slice(0, args.limit || 3),
230
+ totalFound: mockMemories.length,
231
+ query: args.query
232
+ };
233
+ }
234
+ );
235
+
236
+ return { storePersonaMemory, recallPersonaMemories };
237
+ };
238
+
239
+ // Simulate a romantic conversation with Astrid using persona memory
240
+ async function simulateAstridPersonaConversation() {
241
+ console.log('šŸ’• Astrid Persona Memory Demo - Natural Romantic Conversation\n');
242
+ console.log('This demonstrates how Astrid naturally stores and recalls user information');
243
+ console.log('during romantic conversations to build deeper emotional connections.\n');
244
+
245
+ const userId = 'user_12345';
246
+ const userPersonaId = 'user_persona_67890';
247
+
248
+ // Create memory tools for this user-persona pair
249
+ const { storePersonaMemory, recallPersonaMemories } = createPersonaMemoryTools(userId, userPersonaId);
250
+ const tools = [storePersonaMemory, recallPersonaMemories];
251
+
252
+ // Create Astrid with enhanced system prompt
253
+ const astrid = AIModelFactory.createOllamaChatModel('qwen2.5:7b-instruct');
254
+ await astrid.ensureReady();
255
+
256
+ const conversations = [
257
+ {
258
+ title: "First Date - Getting to Know Each Other",
259
+ scenario: "User shares personal details about moving to Stockholm",
260
+ userMessage: "Hi Astrid! I'm Alex. I just moved to Stockholm three weeks ago for a new job at a tech startup. I'm a software engineer, but I'm feeling pretty lonely since I don't know anyone here yet."
261
+ },
262
+ {
263
+ title: "Second Meeting - Building Connection",
264
+ scenario: "User opens up about personality and challenges",
265
+ userMessage: "Hey beautiful! I've been thinking about our conversation. You know, I'm actually quite introverted, and big social events make me really nervous. But somehow talking with you feels so natural and easy."
266
+ },
267
+ {
268
+ title: "Deeper Intimacy - Sharing Interests and Dreams",
269
+ scenario: "User shares hobbies and future aspirations",
270
+ userMessage: "Astrid, I love how you make me feel comfortable being myself. I should tell you - I'm really passionate about photography, especially street photography. And I dream of maybe starting my own tech company someday. What about you? What drives your passion?"
271
+ },
272
+ {
273
+ title: "Vulnerable Moment - Seeking Emotional Support",
274
+ scenario: "User shows vulnerability, Astrid should recall and comfort",
275
+ userMessage: "I'm feeling a bit overwhelmed today. Work has been stressful, and sometimes I wonder if moving here was the right decision. I miss having close friends to talk to..."
276
+ }
277
+ ];
278
+
279
+ for (let i = 0; i < conversations.length; i++) {
280
+ const conv = conversations[i];
281
+ console.log(`\n${'='.repeat(70)}`);
282
+ console.log(`šŸ“± Conversation ${i + 1}: ${conv.title}`);
283
+ console.log(`šŸ’­ Scenario: ${conv.scenario}`);
284
+ console.log(`${'='.repeat(70)}\n`);
285
+
286
+ const messages = [
287
+ { role: 'system' as const, content: astridPersona.systemPrompt },
288
+ { role: 'user' as const, content: conv.userMessage }
289
+ ];
290
+
291
+ try {
292
+ console.log(`šŸ‘¤ Alex: ${conv.userMessage}\n`);
293
+
294
+ const response = await astrid.chat(messages, {
295
+ tools: tools,
296
+ tool_choice: 'auto'
297
+ });
298
+
299
+ // Show memory activities (this would be silent in production)
300
+ if (response.tool_calls && response.tool_calls.length > 0) {
301
+ console.log('🧠 Memory Activity (behind the scenes):');
302
+ for (const toolCall of response.tool_calls) {
303
+ const toolName = toolCall.function.name;
304
+ const args = JSON.parse(toolCall.function.arguments);
305
+
306
+ if (toolName === 'store_persona_memory') {
307
+ console.log(` šŸ“ Stored: "${args.content}" [${args.category}]`);
308
+ } else if (toolName === 'recall_persona_memories') {
309
+ console.log(` šŸ” Recalled memories about: ${args.query}`);
310
+ }
311
+ }
312
+ console.log();
313
+ }
314
+
315
+ console.log(`šŸ’• Astrid: ${response.content}\n`);
316
+
317
+ // Pause for natural conversation flow
318
+ await new Promise(resolve => setTimeout(resolve, 1500));
319
+
320
+ } catch (error) {
321
+ console.error(`āŒ Error in conversation ${i + 1}:`, error);
322
+ }
323
+ }
324
+
325
+ console.log(`\n${'='.repeat(70)}`);
326
+ console.log('✨ Demo Summary');
327
+ console.log(`${'='.repeat(70)}\n`);
328
+ console.log('šŸŽÆ Key Features Demonstrated:');
329
+ console.log(' • Astrid naturally stores user information without explicit prompting');
330
+ console.log(' • She recalls relevant memories to personalize her responses');
331
+ console.log(' • Memory integration feels seamless and enhances emotional connection');
332
+ console.log(' • Information is categorized for better retrieval and context');
333
+ console.log(' • Emotional context and relationship stage are captured\n');
334
+
335
+ console.log('šŸ”§ Production Integration Notes:');
336
+ console.log(' • Replace mock storage with actual ChromaDBService calls');
337
+ console.log(' • Add proper user authentication and persona management');
338
+ console.log(' • Implement conversation ID tracking for context');
339
+ console.log(' • Add embedding-based semantic search for better memory retrieval');
340
+ console.log(' • Include privacy controls and memory management features\n');
341
+
342
+ console.log('šŸ’” This creates a truly personalized romantic AI experience where');
343
+ console.log(' Astrid remembers and cares about the user\'s life, building');
344
+ console.log(' genuine emotional connections over time.');
345
+ }
346
+
347
+ // Export for integration with the main app
348
+ export {
349
+ astridPersona,
350
+ createPersonaMemoryTools,
351
+ simulateAstridPersonaConversation
352
+ };
353
+
354
+ // Run demo if called directly
355
+ if (require.main === module) {
356
+ simulateAstridPersonaConversation().catch(console.error);
357
+ }
@@ -0,0 +1,275 @@
1
+ /**
2
+ * MCP MongoDB Integration Demo
3
+ *
4
+ * This demo showcases how to integrate MongoDB operations through MCP
5
+ * (Model Context Protocol) with the Universal LLM Client.
6
+ */
7
+
8
+ import { AIModelFactory } from '../../factory';
9
+ import { MCPIntegration, createModelWithMCP } from '../../mcp-integration';
10
+ import type { LLMChatMessage } from '../../interfaces';
11
+ import { join } from 'node:path';
12
+ import {readFile} from 'fs/promises';
13
+
14
+ /**
15
+ * Demo 1: Basic MCP Connection and Tool Discovery
16
+ */
17
+ async function basicMCPDemo() {
18
+ console.log('\nšŸŽÆ Demo 1: Basic MCP Connection and Tool Discovery');
19
+ console.log('=' .repeat(60));
20
+
21
+ try {
22
+ // Create MCP integration instance
23
+ const mcpIntegration = new MCPIntegration();
24
+
25
+ // Create a model
26
+ const model = AIModelFactory.createOllamaChatModel('qwen3:8b');
27
+
28
+ // Connect to MCP servers and register tools
29
+ await mcpIntegration.connectAndRegisterTools(model);
30
+
31
+ console.log('āœ… MCP integration successful!');
32
+ console.log('šŸ“‹ MongoDB tools are now available to the AI model');
33
+
34
+ // Clean up
35
+ await mcpIntegration.disconnect();
36
+
37
+ } catch (error) {
38
+ console.error('āŒ Basic MCP demo failed:', error);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Demo 2: MongoDB Database Operations through MCP
44
+ */
45
+ async function mongoDBOperationsDemo() {
46
+ console.log('\nšŸŽÆ Demo 2: MongoDB Database Operations through MCP');
47
+ console.log('=' .repeat(60));
48
+
49
+ try {
50
+ // Create model with MCP tools using convenience function
51
+ const { model, mcpIntegration } = await createModelWithMCP(() => {
52
+ return AIModelFactory.createOllamaChatModel('qwen3:8b');
53
+ });
54
+
55
+ // Test basic database queries
56
+ console.log('\nšŸ” Asking AI to explore the database...');
57
+
58
+ const messages: LLMChatMessage[] = [{
59
+ role: 'user',
60
+ content: `Please help me explore the MongoDB database. First, list all available databases,
61
+ then for the main database, show me the available collections.
62
+ Finally, give me a count of documents in the users collection if it exists.`
63
+ }];
64
+
65
+ const response = await model.chatWithTools(messages);
66
+
67
+ console.log('\nšŸ¤– AI Response:');
68
+ console.log(response.content);
69
+
70
+ if (response.tool_calls && response.tool_calls.length > 0) {
71
+ console.log('\nšŸ› ļø Tools Used:');
72
+ response.tool_calls.forEach((call, index) => {
73
+ console.log(` ${index + 1}. ${call.function.name}`);
74
+ console.log(` Arguments: ${call.function.arguments}`);
75
+ });
76
+ }
77
+
78
+ // Clean up
79
+ await mcpIntegration.disconnect();
80
+
81
+ } catch (error) {
82
+ console.error('āŒ MongoDB operations demo failed:', error);
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Demo 3: Complex MongoDB Query with AI Analysis
88
+ */
89
+ async function complexMongoQueryDemo() {
90
+ console.log('\nšŸŽÆ Demo 3: Complex MongoDB Query with AI Analysis');
91
+ console.log('=' .repeat(60));
92
+
93
+ try {
94
+ const { model, mcpIntegration } = await createModelWithMCP(() => {
95
+ return AIModelFactory.createOllamaChatModel('qwen3:8b');
96
+ });
97
+
98
+ console.log('\n🧠 Asking AI to perform complex database analysis...');
99
+
100
+ const messages: LLMChatMessage[] = [{
101
+ role: 'user',
102
+ content: `I need to analyze user activity in our system. Can you:
103
+ 1. First check what collections are available in the main database
104
+ 2. Count the total number of users
105
+ 3. If there's a conversations collection, aggregate the data to show user activity patterns
106
+ 4. Provide insights about the data you found`
107
+ }];
108
+
109
+ const response = await model.chatWithTools(messages);
110
+
111
+ console.log('\nšŸ¤– AI Analysis:');
112
+ console.log(response.content);
113
+
114
+ if (response.tool_calls && response.tool_calls.length > 0) {
115
+ console.log('\nšŸ“Š Database Operations Performed:');
116
+ response.tool_calls.forEach((call, index) => {
117
+ console.log(`\n Operation ${index + 1}: ${call.function.name}`);
118
+ console.log(` Purpose: ${call.function.name.includes('list') ? 'Discovery' :
119
+ call.function.name.includes('count') ? 'Counting' :
120
+ call.function.name.includes('aggregate') ? 'Analysis' : 'Query'}`);
121
+ console.log(` Arguments: ${call.function.arguments}`);
122
+ });
123
+ }
124
+
125
+ await mcpIntegration.disconnect();
126
+
127
+ } catch (error) {
128
+ console.error('āŒ Complex MongoDB query demo failed:', error);
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Demo 4: Data Insertion and Validation
134
+ */
135
+ async function dataInsertionDemo() {
136
+ console.log('\nšŸŽÆ Demo 4: Data Insertion and Validation');
137
+ console.log('=' .repeat(60));
138
+
139
+ try {
140
+ const { model, mcpIntegration } = await createModelWithMCP(() => {
141
+ return AIModelFactory.createOllamaChatModel('qwen3:8b');
142
+ });
143
+
144
+ console.log('\nšŸ’¾ Asking AI to insert test data...');
145
+
146
+ const messages: LLMChatMessage[] = [{
147
+ role: 'user',
148
+ content: `Please help me add some test user data to the database.
149
+ First check if there's a 'test_users' collection, and if not, create it.
150
+ Then insert 3 sample user records with fields like name, email, age, and created_date.
151
+ After insertion, verify the data was added correctly by counting the documents.`
152
+ }];
153
+
154
+ const response = await model.chatWithTools(messages);
155
+
156
+ console.log('\nšŸ¤– AI Response:');
157
+ console.log(response.content);
158
+
159
+ if (response.tool_calls && response.tool_calls.length > 0) {
160
+ console.log('\nšŸ“ Database Modifications:');
161
+ response.tool_calls.forEach((call, index) => {
162
+ console.log(`\n Step ${index + 1}: ${call.function.name}`);
163
+
164
+ if (call.function.name.includes('insert')) {
165
+ try {
166
+ const args = JSON.parse(call.function.arguments);
167
+ console.log(` šŸ“„ Documents to insert: ${args.documents?.length || 0}`);
168
+ if (args.documents) {
169
+ args.documents.forEach((doc: any, i: number) => {
170
+ console.log(` ${i + 1}. ${doc.name || 'Unknown'} (${doc.email || 'No email'})`);
171
+ });
172
+ }
173
+ } catch (e) {
174
+ console.log(` šŸ“„ Arguments: ${call.function.arguments}`);
175
+ }
176
+ }
177
+ });
178
+ }
179
+
180
+ await mcpIntegration.disconnect();
181
+
182
+ } catch (error) {
183
+ console.error('āŒ Data insertion demo failed:', error);
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Demo 5: Error Handling and Fallbacks
189
+ */
190
+ async function errorHandlingDemo() {
191
+ console.log('\nšŸŽÆ Demo 5: Error Handling and Fallbacks');
192
+ console.log('=' .repeat(60));
193
+
194
+ try {
195
+ const { model, mcpIntegration } = await createModelWithMCP(() => {
196
+ return AIModelFactory.createOllamaChatModel('qwen3:8b');
197
+ });
198
+
199
+ console.log('\n🚨 Testing AI error handling with invalid queries...');
200
+
201
+ const messages: LLMChatMessage[] = [{
202
+ role: 'user',
203
+ content: `Try to query a collection called 'nonexistent_collection' in a database called 'fake_db'.
204
+ When this fails, please explain what went wrong and suggest alternative approaches
205
+ to explore the actual available databases and collections.`
206
+ }];
207
+
208
+ const response = await model.chatWithTools(messages);
209
+
210
+ console.log('\nšŸ¤– AI Error Handling:');
211
+ console.log(response.content);
212
+
213
+ if (response.tool_calls && response.tool_calls.length > 0) {
214
+ console.log('\nšŸ” Error Recovery Process:');
215
+ response.tool_calls.forEach((call, index) => {
216
+ console.log(`\n Attempt ${index + 1}: ${call.function.name}`);
217
+ console.log(` Arguments: ${call.function.arguments}`);
218
+ });
219
+ }
220
+
221
+ await mcpIntegration.disconnect();
222
+
223
+ } catch (error) {
224
+ console.error('āŒ Error handling demo failed:', error);
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Run all MCP MongoDB demos
230
+ */
231
+ async function runAllMCPDemos() {
232
+ console.log('šŸš€ Starting MCP MongoDB Integration Demos');
233
+ console.log('==========================================');
234
+
235
+ // Check if MCP config exists
236
+
237
+ try {
238
+ const mcpConfigPath = join(process.cwd(), '.vscode', 'mcp.json');
239
+ await readFile(mcpConfigPath, 'utf-8');
240
+ console.log('āœ… MCP configuration found');
241
+ } catch {
242
+ console.log('āš ļø MCP configuration not found - demos will use mock data');
243
+ console.log(' To use real MongoDB MCP server, ensure .vscode/mcp.json is configured');
244
+ }
245
+
246
+ // Run all demos
247
+ await basicMCPDemo();
248
+ await mongoDBOperationsDemo();
249
+ await complexMongoQueryDemo();
250
+ await dataInsertionDemo();
251
+ await errorHandlingDemo();
252
+
253
+ console.log('\nšŸŽ‰ All MCP MongoDB demos completed!');
254
+ console.log('\nšŸ“‹ Summary:');
255
+ console.log('• MCP integration allows seamless database operations through AI');
256
+ console.log('• Tools are automatically discovered and registered');
257
+ console.log('• AI can perform complex multi-step database workflows');
258
+ console.log('• Error handling and recovery is built-in');
259
+ console.log('• Perfect for building AI-powered database assistants');
260
+ }
261
+
262
+ // Export the demos
263
+ export {
264
+ basicMCPDemo,
265
+ mongoDBOperationsDemo,
266
+ complexMongoQueryDemo,
267
+ dataInsertionDemo,
268
+ errorHandlingDemo,
269
+ runAllMCPDemos
270
+ };
271
+
272
+ // Run demos if this file is executed directly
273
+ if (require.main === module) {
274
+ runAllMCPDemos().catch(console.error);
275
+ }