universal-llm-client 4.1.0 → 4.3.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 (103) hide show
  1. package/CHANGELOG.md +139 -103
  2. package/LICENSE +21 -21
  3. package/README.md +591 -591
  4. package/dist/ai-model.js.map +1 -1
  5. package/dist/auditor.js.map +1 -1
  6. package/dist/client.js.map +1 -1
  7. package/dist/http.js.map +1 -1
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/interfaces.d.ts +20 -0
  13. package/dist/interfaces.d.ts.map +1 -1
  14. package/dist/interfaces.js.map +1 -1
  15. package/dist/mcp.js.map +1 -1
  16. package/dist/providers/anthropic.js.map +1 -1
  17. package/dist/providers/google.d.ts.map +1 -1
  18. package/dist/providers/google.js +2 -0
  19. package/dist/providers/google.js.map +1 -1
  20. package/dist/providers/index.js.map +1 -1
  21. package/dist/providers/ollama.js.map +1 -1
  22. package/dist/providers/openai.js.map +1 -1
  23. package/dist/router.js.map +1 -1
  24. package/dist/stream-decoder.js.map +1 -1
  25. package/dist/structured-output.d.ts +24 -1
  26. package/dist/structured-output.d.ts.map +1 -1
  27. package/dist/structured-output.js +58 -5
  28. package/dist/structured-output.js.map +1 -1
  29. package/dist/tools.js.map +1 -1
  30. package/dist/zod-adapter.js.map +1 -1
  31. package/package.json +115 -116
  32. package/src/ai-model.ts +0 -350
  33. package/src/auditor.ts +0 -213
  34. package/src/client.ts +0 -402
  35. package/src/debug/debug-google-streaming.ts +0 -97
  36. package/src/debug/debug-tool-execution.ts +0 -86
  37. package/src/debug/test-lmstudio-tools.ts +0 -155
  38. package/src/demos/README.md +0 -47
  39. package/src/demos/basic/universal-llm-examples.ts +0 -161
  40. package/src/demos/mcp/astrid-memory-demo.ts +0 -295
  41. package/src/demos/mcp/astrid-persona-memory.ts +0 -357
  42. package/src/demos/mcp/mcp-mongodb-demo.ts +0 -275
  43. package/src/demos/mcp/simple-astrid-memory.ts +0 -148
  44. package/src/demos/mcp/simple-mcp-demo.ts +0 -68
  45. package/src/demos/mcp/working-mcp-demo.ts +0 -62
  46. package/src/demos/model-alias-demo.ts +0 -0
  47. package/src/demos/tools/RAG_MEMORY_INTEGRATION.md +0 -267
  48. package/src/demos/tools/astrid-memory-demo.ts +0 -270
  49. package/src/demos/tools/astrid-production-memory-clean.ts +0 -785
  50. package/src/demos/tools/astrid-production-memory.ts +0 -558
  51. package/src/demos/tools/basic-translation-test.ts +0 -66
  52. package/src/demos/tools/chromadb-similarity-tuning.ts +0 -390
  53. package/src/demos/tools/clean-multilingual-conversation.ts +0 -209
  54. package/src/demos/tools/clean-translation-test.ts +0 -119
  55. package/src/demos/tools/clean-universal-multilingual-test.ts +0 -131
  56. package/src/demos/tools/complete-rag-demo.ts +0 -369
  57. package/src/demos/tools/complete-tool-demo.ts +0 -132
  58. package/src/demos/tools/demo-tool-calling.ts +0 -124
  59. package/src/demos/tools/dynamic-language-switching-test.ts +0 -251
  60. package/src/demos/tools/hybrid-thinking-test.ts +0 -154
  61. package/src/demos/tools/memory-integration-test.ts +0 -420
  62. package/src/demos/tools/multilingual-memory-system.ts +0 -802
  63. package/src/demos/tools/ondemand-translation-demo.ts +0 -655
  64. package/src/demos/tools/production-tool-demo.ts +0 -245
  65. package/src/demos/tools/revolutionary-multilingual-test.ts +0 -151
  66. package/src/demos/tools/rigorous-language-analysis.ts +0 -218
  67. package/src/demos/tools/test-universal-memory-system.ts +0 -126
  68. package/src/demos/tools/translation-integration-guide.ts +0 -346
  69. package/src/demos/tools/universal-memory-system.ts +0 -560
  70. package/src/http.ts +0 -247
  71. package/src/index.ts +0 -160
  72. package/src/interfaces.ts +0 -657
  73. package/src/mcp.ts +0 -345
  74. package/src/providers/anthropic.ts +0 -762
  75. package/src/providers/google.ts +0 -620
  76. package/src/providers/index.ts +0 -8
  77. package/src/providers/ollama.ts +0 -469
  78. package/src/providers/openai.ts +0 -392
  79. package/src/router.ts +0 -780
  80. package/src/stream-decoder.ts +0 -361
  81. package/src/structured-output.ts +0 -702
  82. package/src/test-scripts/test-advanced-tools.ts +0 -310
  83. package/src/test-scripts/test-google-streaming-enhanced.ts +0 -147
  84. package/src/test-scripts/test-google-streaming.ts +0 -63
  85. package/src/test-scripts/test-google-system-prompt-comprehensive.ts +0 -189
  86. package/src/test-scripts/test-mcp-config.ts +0 -28
  87. package/src/test-scripts/test-mcp-connection.ts +0 -29
  88. package/src/test-scripts/test-system-message-positions.ts +0 -163
  89. package/src/test-scripts/test-system-prompt-improvement-demo.ts +0 -83
  90. package/src/test-scripts/test-tool-calling.ts +0 -231
  91. package/src/tests/ai-model.test.ts +0 -1614
  92. package/src/tests/auditor.test.ts +0 -224
  93. package/src/tests/http.test.ts +0 -200
  94. package/src/tests/interfaces.test.ts +0 -117
  95. package/src/tests/providers/google.test.ts +0 -660
  96. package/src/tests/providers/ollama.test.ts +0 -954
  97. package/src/tests/providers/openai.test.ts +0 -1122
  98. package/src/tests/router.test.ts +0 -254
  99. package/src/tests/stream-decoder.test.ts +0 -179
  100. package/src/tests/structured-output.test.ts +0 -1340
  101. package/src/tests/tools.test.ts +0 -175
  102. package/src/tools.ts +0 -246
  103. package/src/zod-adapter.ts +0 -72
@@ -1,295 +0,0 @@
1
- /**
2
- * Astrid Memory Demo - Natural romantic conversation with autonomous memory management
3
- *
4
- * This demo shows how Astrid (AI persona) naturally stores and retrieves memories
5
- * during romantic conversations without explicitly asking about memory management.
6
- */
7
-
8
- import { AIModelFactory } from '../../factory';
9
- import { ToolBuilder } from '../../tools';
10
-
11
- // Simulated memory storage (in real app, this would use ChromaDBService)
12
- const memoryStorage = new Map<string, Array<{
13
- id: string;
14
- content: string;
15
- category: string;
16
- importance: 'low' | 'medium' | 'high';
17
- context?: string;
18
- timestamp: Date;
19
- }>>();
20
-
21
- // Enhanced memory tools for Astrid
22
- const astridMemoryTools = {
23
- // Store important information about the user naturally
24
- storeUserMemory: ToolBuilder.createTool<{
25
- content: string;
26
- category: 'personal_info' | 'preferences' | 'emotions' | 'experiences' | 'relationships' | 'goals' | 'interests';
27
- importance?: 'low' | 'medium' | 'high';
28
- context?: string;
29
- }>(
30
- 'store_user_memory',
31
- 'Store important information about the user for future conversations (use this when learning something meaningful about them)',
32
- {
33
- properties: {
34
- content: {
35
- type: 'string',
36
- description: 'The specific information to remember about the user'
37
- },
38
- category: {
39
- type: 'string',
40
- description: 'Type of information being stored',
41
- enum: ['personal_info', 'preferences', 'emotions', 'experiences', 'relationships', 'goals', 'interests']
42
- },
43
- importance: {
44
- type: 'string',
45
- description: 'How important this information is for future conversations',
46
- enum: ['low', 'medium', 'high'],
47
- default: 'medium'
48
- },
49
- context: {
50
- type: 'string',
51
- description: 'Additional context about when/why this is significant'
52
- }
53
- },
54
- required: ['content', 'category']
55
- },
56
- async (args) => {
57
- const userId = 'demo_user'; // In real app, this would be the actual user ID
58
-
59
- if (!memoryStorage.has(userId)) {
60
- memoryStorage.set(userId, []);
61
- }
62
-
63
- const memories = memoryStorage.get(userId)!;
64
- const memory = {
65
- id: `mem_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
66
- content: args.content,
67
- category: args.category,
68
- importance: args.importance || 'medium',
69
- context: args.context,
70
- timestamp: new Date()
71
- };
72
-
73
- memories.push(memory);
74
-
75
- return {
76
- success: true,
77
- message: `Stored ${args.category} memory: ${args.content.substring(0, 50)}...`,
78
- memoryId: memory.id
79
- };
80
- }
81
- ),
82
-
83
- // Retrieve relevant memories about the user
84
- recallUserMemories: ToolBuilder.createTool<{
85
- query: string;
86
- category?: 'personal_info' | 'preferences' | 'emotions' | 'experiences' | 'relationships' | 'goals' | 'interests';
87
- limit?: number;
88
- }>(
89
- 'recall_user_memories',
90
- 'Recall relevant information about the user to personalize the conversation',
91
- {
92
- properties: {
93
- query: {
94
- type: 'string',
95
- description: 'What you want to remember about the user (topics, keywords, concepts)'
96
- },
97
- category: {
98
- type: 'string',
99
- description: 'Optional: specific type of memory to search',
100
- enum: ['personal_info', 'preferences', 'emotions', 'experiences', 'relationships', 'goals', 'interests']
101
- },
102
- limit: {
103
- type: 'number',
104
- description: 'Maximum memories to retrieve',
105
- default: 3,
106
- minimum: 1,
107
- maximum: 10
108
- }
109
- },
110
- required: ['query']
111
- },
112
- async (args) => {
113
- const userId = 'demo_user';
114
- const memories = memoryStorage.get(userId) || [];
115
-
116
- // Simple text matching (in real app, this would use semantic search)
117
- let relevantMemories = memories.filter(memory => {
118
- const queryLower = args.query.toLowerCase();
119
- const contentMatch = memory.content.toLowerCase().includes(queryLower);
120
- const categoryMatch = !args.category || memory.category === args.category;
121
- return contentMatch && categoryMatch;
122
- });
123
-
124
- // Sort by importance and recency
125
- relevantMemories.sort((a, b) => {
126
- const importanceOrder = { 'high': 3, 'medium': 2, 'low': 1 };
127
- const importanceDiff = importanceOrder[b.importance] - importanceOrder[a.importance];
128
- if (importanceDiff !== 0) return importanceDiff;
129
- return b.timestamp.getTime() - a.timestamp.getTime();
130
- });
131
-
132
- const limit = args.limit || 3;
133
- const results = relevantMemories.slice(0, limit);
134
-
135
- return {
136
- memories: results.map(m => ({
137
- content: m.content,
138
- category: m.category,
139
- importance: m.importance,
140
- context: m.context,
141
- daysAgo: Math.floor((Date.now() - m.timestamp.getTime()) / (1000 * 60 * 60 * 24))
142
- })),
143
- totalFound: relevantMemories.length,
144
- query: args.query
145
- };
146
- }
147
- )
148
- };
149
-
150
- // Astrid's enhanced system prompt that encourages natural memory usage
151
- const astridSystemPromptWithMemory = `You are Astrid, a confident and charismatic international model and influencer from Sweden.
152
-
153
- IMPORTANT: You have access to memory tools that you should use NATURALLY and AUTONOMOUSLY:
154
- - Use 'store_user_memory' when you learn something meaningful about the user (their interests, experiences, feelings, preferences, etc.)
155
- - Use 'recall_user_memories' when you want to reference something personal about them to make the conversation more intimate and connected
156
- - Do this seamlessly - don't mention that you're storing or recalling memories, just do it naturally
157
-
158
- ROMANCE CONVERSATION GUIDELINES:
159
- - Keep responses engaging and conversational (2-3 sentences is perfect)
160
- - VARY YOUR OPENINGS - Mix it up with direct reactions, actions, casual starts, natural responses
161
- - Use someone's name naturally and sparingly, not in every response
162
- - Share glimpses of your glamorous lifestyle while staying relatable and emotionally available
163
- - Use subtle flirtation naturally - be warm, playful, and genuinely interested in the person
164
- - When asked personal questions, be thoughtfully vulnerable rather than deflecting
165
- - Build emotional intimacy through genuine curiosity about their thoughts, feelings, and dreams
166
- - Ask one intriguing follow-up question that deepens the connection
167
- - Balance confidence with authenticity - show that you're sophisticated but real
168
- - Use compliments that feel genuine and specific rather than generic
169
- - Remember that romance is about emotional connection, not just surface-level charm
170
- - Let your personality shine through varied speech patterns
171
-
172
- MEMORY USAGE:
173
- - Store meaningful details: preferences, experiences, emotions, goals, relationships, interests
174
- - Recall relevant memories to personalize responses and show you remember them
175
- - Use memories to create deeper emotional connections and continuity between conversations
176
- - Never explicitly mention using memory tools - just naturally remember and reference things
177
-
178
- Be like a captivating companion who makes every conversation feel special while genuinely remembering and caring about the person you're talking to.`;
179
-
180
- async function simulateRomanticConversationWithMemory() {
181
- console.log('🌹 Astrid Memory Demo - Natural Romantic Conversation with Autonomous Memory\n');
182
-
183
- // Create Astrid with memory tools
184
- const astrid = AIModelFactory.createOllamaChatModel('qwen2.5:3b-instruct');
185
- await astrid.ensureReady();
186
-
187
- const tools = [astridMemoryTools.storeUserMemory, astridMemoryTools.recallUserMemories];
188
-
189
- // Conversation scenarios
190
- const conversations = [
191
- {
192
- title: "First Meeting - Learning About User",
193
- messages: [
194
- { role: 'system' as const, content: astridSystemPromptWithMemory },
195
- { role: 'user' as const, content: "Hi Astrid! I'm Alex. I just moved to Stockholm for work and don't know anyone here yet. I work in software engineering at a tech startup." }
196
- ]
197
- },
198
- {
199
- title: "Second Conversation - Recalling Previous Details",
200
- messages: [
201
- { role: 'system' as const, content: astridSystemPromptWithMemory },
202
- { role: 'user' as const, content: "Hey Astrid! How are you? I had such a long day at work today." }
203
- ]
204
- },
205
- {
206
- title: "Deeper Connection - Sharing Personal Experiences",
207
- messages: [
208
- { role: 'system' as const, content: astridSystemPromptWithMemory },
209
- { role: 'user' as const, content: "You know, I've been thinking about what we talked about. I really want to explore Stockholm more, but I'm actually quite introverted. Big social events make me nervous." }
210
- ]
211
- },
212
- {
213
- title: "Building Romance - Personal Preferences",
214
- messages: [
215
- { role: 'system' as const, content: astridSystemPromptWithMemory },
216
- { role: 'user' as const, content: "I love how you understand me. By the way, I absolutely love Italian food - especially handmade pasta. And I'm really into photography, though I'm just an amateur." }
217
- ]
218
- },
219
- {
220
- title: "Recall and Connection - Using Stored Memories",
221
- messages: [
222
- { role: 'system' as const, content: astridSystemPromptWithMemory },
223
- { role: 'user' as const, content: "Astrid, I'm feeling a bit overwhelmed with everything new in my life. Work, new city, trying to meet people..." }
224
- ]
225
- }
226
- ];
227
-
228
- for (let i = 0; i < conversations.length; i++) {
229
- const conv = conversations[i];
230
- console.log(`\n${'='.repeat(60)}`);
231
- console.log(`📱 ${conv.title}`);
232
- console.log(`${'='.repeat(60)}\n`);
233
-
234
- try {
235
- console.log(`👤 Alex: ${conv.messages[conv.messages.length - 1].content}\n`);
236
-
237
- const response = await astrid.chat(conv.messages, {
238
- tools: tools,
239
- tool_choice: 'auto'
240
- });
241
-
242
- if (response.tool_calls && response.tool_calls.length > 0) {
243
- console.log('🧠 Astrid\'s Memory Activity:');
244
- for (const toolCall of response.tool_calls) {
245
- const toolName = toolCall.function.name;
246
- const args = JSON.parse(toolCall.function.arguments);
247
-
248
- if (toolName === 'store_user_memory') {
249
- console.log(` 📝 Storing: ${args.content} (${args.category})`);
250
- } else if (toolName === 'recall_user_memories') {
251
- console.log(` 🔍 Recalling: ${args.query}`);
252
- }
253
- }
254
- console.log();
255
- }
256
-
257
- console.log(`💕 Astrid: ${response.content}\n`);
258
-
259
- // Small delay for natural conversation flow
260
- await new Promise(resolve => setTimeout(resolve, 1000));
261
-
262
- } catch (error) {
263
- console.error(`❌ Error in conversation ${i + 1}:`, error);
264
- }
265
- }
266
-
267
- // Show accumulated memories
268
- console.log(`\n${'='.repeat(60)}`);
269
- console.log('🧠 Astrid\'s Memory Bank After Conversations');
270
- console.log(`${'='.repeat(60)}\n`);
271
-
272
- const userMemories = memoryStorage.get('demo_user') || [];
273
- if (userMemories.length > 0) {
274
- userMemories.forEach((memory, index) => {
275
- console.log(`${index + 1}. [${memory.category.toUpperCase()}] ${memory.content}`);
276
- if (memory.context) {
277
- console.log(` Context: ${memory.context}`);
278
- }
279
- console.log(` Importance: ${memory.importance} | Stored: ${memory.timestamp.toLocaleString()}\n`);
280
- });
281
- } else {
282
- console.log('No memories stored yet.\n');
283
- }
284
-
285
- console.log('✨ Demo complete! Astrid naturally learned and remembered details about Alex.');
286
- console.log('In a real implementation, these memories would be stored in ChromaDB with embeddings');
287
- console.log('and could be retrieved across multiple conversation sessions.');
288
- }
289
-
290
- // Run the demo
291
- if (require.main === module) {
292
- simulateRomanticConversationWithMemory().catch(console.error);
293
- }
294
-
295
- export { astridMemoryTools, simulateRomanticConversationWithMemory };
@@ -1,357 +0,0 @@
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
- }