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.
- package/CHANGELOG.md +139 -103
- package/LICENSE +21 -21
- package/README.md +591 -591
- package/dist/ai-model.js.map +1 -1
- package/dist/auditor.js.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +20 -0
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/mcp.js.map +1 -1
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +2 -0
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai.js.map +1 -1
- package/dist/router.js.map +1 -1
- package/dist/stream-decoder.js.map +1 -1
- package/dist/structured-output.d.ts +24 -1
- package/dist/structured-output.d.ts.map +1 -1
- package/dist/structured-output.js +58 -5
- package/dist/structured-output.js.map +1 -1
- package/dist/tools.js.map +1 -1
- package/dist/zod-adapter.js.map +1 -1
- package/package.json +115 -116
- package/src/ai-model.ts +0 -350
- package/src/auditor.ts +0 -213
- package/src/client.ts +0 -402
- package/src/debug/debug-google-streaming.ts +0 -97
- package/src/debug/debug-tool-execution.ts +0 -86
- package/src/debug/test-lmstudio-tools.ts +0 -155
- package/src/demos/README.md +0 -47
- package/src/demos/basic/universal-llm-examples.ts +0 -161
- package/src/demos/mcp/astrid-memory-demo.ts +0 -295
- package/src/demos/mcp/astrid-persona-memory.ts +0 -357
- package/src/demos/mcp/mcp-mongodb-demo.ts +0 -275
- package/src/demos/mcp/simple-astrid-memory.ts +0 -148
- package/src/demos/mcp/simple-mcp-demo.ts +0 -68
- package/src/demos/mcp/working-mcp-demo.ts +0 -62
- package/src/demos/model-alias-demo.ts +0 -0
- package/src/demos/tools/RAG_MEMORY_INTEGRATION.md +0 -267
- package/src/demos/tools/astrid-memory-demo.ts +0 -270
- package/src/demos/tools/astrid-production-memory-clean.ts +0 -785
- package/src/demos/tools/astrid-production-memory.ts +0 -558
- package/src/demos/tools/basic-translation-test.ts +0 -66
- package/src/demos/tools/chromadb-similarity-tuning.ts +0 -390
- package/src/demos/tools/clean-multilingual-conversation.ts +0 -209
- package/src/demos/tools/clean-translation-test.ts +0 -119
- package/src/demos/tools/clean-universal-multilingual-test.ts +0 -131
- package/src/demos/tools/complete-rag-demo.ts +0 -369
- package/src/demos/tools/complete-tool-demo.ts +0 -132
- package/src/demos/tools/demo-tool-calling.ts +0 -124
- package/src/demos/tools/dynamic-language-switching-test.ts +0 -251
- package/src/demos/tools/hybrid-thinking-test.ts +0 -154
- package/src/demos/tools/memory-integration-test.ts +0 -420
- package/src/demos/tools/multilingual-memory-system.ts +0 -802
- package/src/demos/tools/ondemand-translation-demo.ts +0 -655
- package/src/demos/tools/production-tool-demo.ts +0 -245
- package/src/demos/tools/revolutionary-multilingual-test.ts +0 -151
- package/src/demos/tools/rigorous-language-analysis.ts +0 -218
- package/src/demos/tools/test-universal-memory-system.ts +0 -126
- package/src/demos/tools/translation-integration-guide.ts +0 -346
- package/src/demos/tools/universal-memory-system.ts +0 -560
- package/src/http.ts +0 -247
- package/src/index.ts +0 -160
- package/src/interfaces.ts +0 -657
- package/src/mcp.ts +0 -345
- package/src/providers/anthropic.ts +0 -762
- package/src/providers/google.ts +0 -620
- package/src/providers/index.ts +0 -8
- package/src/providers/ollama.ts +0 -469
- package/src/providers/openai.ts +0 -392
- package/src/router.ts +0 -780
- package/src/stream-decoder.ts +0 -361
- package/src/structured-output.ts +0 -702
- package/src/test-scripts/test-advanced-tools.ts +0 -310
- package/src/test-scripts/test-google-streaming-enhanced.ts +0 -147
- package/src/test-scripts/test-google-streaming.ts +0 -63
- package/src/test-scripts/test-google-system-prompt-comprehensive.ts +0 -189
- package/src/test-scripts/test-mcp-config.ts +0 -28
- package/src/test-scripts/test-mcp-connection.ts +0 -29
- package/src/test-scripts/test-system-message-positions.ts +0 -163
- package/src/test-scripts/test-system-prompt-improvement-demo.ts +0 -83
- package/src/test-scripts/test-tool-calling.ts +0 -231
- package/src/tests/ai-model.test.ts +0 -1614
- package/src/tests/auditor.test.ts +0 -224
- package/src/tests/http.test.ts +0 -200
- package/src/tests/interfaces.test.ts +0 -117
- package/src/tests/providers/google.test.ts +0 -660
- package/src/tests/providers/ollama.test.ts +0 -954
- package/src/tests/providers/openai.test.ts +0 -1122
- package/src/tests/router.test.ts +0 -254
- package/src/tests/stream-decoder.test.ts +0 -179
- package/src/tests/structured-output.test.ts +0 -1340
- package/src/tests/tools.test.ts +0 -175
- package/src/tools.ts +0 -246
- 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
|
-
}
|