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,267 +0,0 @@
|
|
|
1
|
-
# RAG Memory Tools Integration Guide
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
This guide shows how to integrate RAG (Retrieval-Augmented Generation) memory tools with the Universal LLM Client to create AI personas that can naturally store and retrieve information during conversations.
|
|
6
|
-
|
|
7
|
-
## ⨠What We've Built
|
|
8
|
-
|
|
9
|
-
### 1. Memory Tools in `tools.ts`
|
|
10
|
-
|
|
11
|
-
The Universal LLM Client now includes built-in memory tools:
|
|
12
|
-
|
|
13
|
-
- **`store_memory`** - Store important information for future recall
|
|
14
|
-
- **`search_memory`** - Search stored memories by query or category
|
|
15
|
-
- **`analyze_conversation`** - Analyze conversations to identify valuable information
|
|
16
|
-
|
|
17
|
-
### 2. Romantic Persona Demo (`astrid-memory-demo.ts`)
|
|
18
|
-
|
|
19
|
-
A complete demo showing how Astrid (AI persona) naturally:
|
|
20
|
-
|
|
21
|
-
- Stores personal details shared during romantic conversations
|
|
22
|
-
- Retrieves relevant memories to personalize responses
|
|
23
|
-
- Builds emotional connections through remembered details
|
|
24
|
-
- Progresses relationship stages with consistent memory recall
|
|
25
|
-
|
|
26
|
-
### 3. Production Integration (`astrid-production-memory.ts`)
|
|
27
|
-
|
|
28
|
-
Shows how to integrate with real ChromaDBService for production use:
|
|
29
|
-
|
|
30
|
-
- Persistent memory storage across sessions
|
|
31
|
-
- Vector similarity search for relevant recall
|
|
32
|
-
- Emotional context and relationship stage tracking
|
|
33
|
-
- Confidence scoring for memory importance
|
|
34
|
-
|
|
35
|
-
## š§ Integration with ChromaDBService
|
|
36
|
-
|
|
37
|
-
### Step 1: Update Memory Tools to Use ChromaDBService
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
// In your production code, replace the mock implementations in tools.ts
|
|
41
|
-
import { ChromaDBService } from '../../../services/ChromaDBService';
|
|
42
|
-
|
|
43
|
-
function createProductionMemoryTools(
|
|
44
|
-
chromaService: ChromaDBService,
|
|
45
|
-
userId: string,
|
|
46
|
-
userPersonaId: string,
|
|
47
|
-
basePersonaId: string
|
|
48
|
-
) {
|
|
49
|
-
const storeMemoryTool = ToolBuilder.createTool<{
|
|
50
|
-
category: string;
|
|
51
|
-
information: string;
|
|
52
|
-
importance: 'low' | 'medium' | 'high';
|
|
53
|
-
emotional_context?: string;
|
|
54
|
-
}>(
|
|
55
|
-
'store_romantic_memory',
|
|
56
|
-
'Store important personal information about the user',
|
|
57
|
-
{
|
|
58
|
-
properties: {
|
|
59
|
-
category: {
|
|
60
|
-
type: 'string',
|
|
61
|
-
description: 'Category of information',
|
|
62
|
-
enum: ['interests', 'work', 'family', 'dreams', 'preferences', 'experiences', 'personality', 'relationships']
|
|
63
|
-
},
|
|
64
|
-
information: { type: 'string', description: 'The information to remember' },
|
|
65
|
-
importance: { type: 'string', enum: ['low', 'medium', 'high'] },
|
|
66
|
-
emotional_context: { type: 'string', description: 'Emotional context when shared' }
|
|
67
|
-
},
|
|
68
|
-
required: ['category', 'information', 'importance']
|
|
69
|
-
},
|
|
70
|
-
async (args) => {
|
|
71
|
-
const conversationId = `romantic_chat_${Date.now()}`;
|
|
72
|
-
const confidence = args.importance === 'high' ? 0.9 : args.importance === 'medium' ? 0.7 : 0.5;
|
|
73
|
-
|
|
74
|
-
const insightId = await chromaService.addInsight(
|
|
75
|
-
userId,
|
|
76
|
-
args.information,
|
|
77
|
-
args.category,
|
|
78
|
-
conversationId,
|
|
79
|
-
confidence,
|
|
80
|
-
userPersonaId,
|
|
81
|
-
basePersonaId,
|
|
82
|
-
'romantic_memory',
|
|
83
|
-
undefined,
|
|
84
|
-
args.emotional_context
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
success: true,
|
|
89
|
-
insight_id: insightId,
|
|
90
|
-
message: `š Remembered ${args.importance} importance detail about ${args.category}`
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
const retrieveMemoryTool = ToolBuilder.createTool<{
|
|
96
|
-
search_query?: string;
|
|
97
|
-
category?: string;
|
|
98
|
-
limit?: number;
|
|
99
|
-
}>(
|
|
100
|
-
'recall_romantic_memories',
|
|
101
|
-
'Retrieve stored memories to personalize responses',
|
|
102
|
-
{
|
|
103
|
-
properties: {
|
|
104
|
-
search_query: { type: 'string', description: 'Search for specific memories' },
|
|
105
|
-
category: { type: 'string', enum: ['interests', 'work', 'family', 'dreams', 'preferences', 'experiences', 'personality', 'relationships'] },
|
|
106
|
-
limit: { type: 'number', default: 5 }
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
async (args) => {
|
|
110
|
-
let insights;
|
|
111
|
-
|
|
112
|
-
if (args.search_query) {
|
|
113
|
-
const result = await chromaService.searchSimilarInsights(userId, args.search_query, args.limit || 5);
|
|
114
|
-
insights = result.insights;
|
|
115
|
-
} else {
|
|
116
|
-
insights = await chromaService.getUserInsightsByCategory(userId, args.category, userPersonaId, args.limit || 5);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return {
|
|
120
|
-
memories: insights.map(insight => ({
|
|
121
|
-
category: insight.category,
|
|
122
|
-
information: insight.content,
|
|
123
|
-
emotional_context: insight.emotionalContext,
|
|
124
|
-
confidence: insight.confidence,
|
|
125
|
-
stored_date: insight.createdAt?.split('T')[0] || 'unknown'
|
|
126
|
-
})),
|
|
127
|
-
total_found: insights.length,
|
|
128
|
-
romantic_note: "š Use these memories to create more personal responses"
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
return [storeMemoryTool, retrieveMemoryTool];
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Step 2: Create Persona Service Integration
|
|
138
|
-
|
|
139
|
-
```typescript
|
|
140
|
-
// Create a service that connects personas with memory
|
|
141
|
-
export class PersonaMemoryService {
|
|
142
|
-
constructor(
|
|
143
|
-
private chromaService: ChromaDBService,
|
|
144
|
-
private universalLLMClient: AIModel
|
|
145
|
-
) {}
|
|
146
|
-
|
|
147
|
-
async createPersonaWithMemory(
|
|
148
|
-
userId: string,
|
|
149
|
-
userPersona: UserPersona,
|
|
150
|
-
basePersona: AuraPersona
|
|
151
|
-
): Promise<AIModel> {
|
|
152
|
-
// Create memory tools for this specific user-persona pair
|
|
153
|
-
const memoryTools = createProductionMemoryTools(
|
|
154
|
-
this.chromaService,
|
|
155
|
-
userId,
|
|
156
|
-
userPersona._id!.toString(),
|
|
157
|
-
basePersona._id!.toString()
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
// Register memory tools with the LLM client
|
|
161
|
-
this.universalLLMClient.registerTools(memoryTools);
|
|
162
|
-
|
|
163
|
-
// Enhanced system prompt that includes memory usage instructions
|
|
164
|
-
const enhancedPrompt = this.createMemoryAwarePrompt(basePersona.systemPrompt);
|
|
165
|
-
|
|
166
|
-
return this.universalLLMClient;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
private createMemoryAwarePrompt(originalPrompt: string): string {
|
|
170
|
-
return `${originalPrompt}
|
|
171
|
-
|
|
172
|
-
MEMORY SYSTEM INTEGRATION:
|
|
173
|
-
- Use store_romantic_memory when users share personal details, emotions, preferences, or meaningful experiences
|
|
174
|
-
- Use recall_romantic_memories before responding to personalize your responses with remembered details
|
|
175
|
-
- Store emotional context and relationship stage to build deeper connections over time
|
|
176
|
-
- Remember: intimacy grows through consistent recall of personal details and emotional moments
|
|
177
|
-
|
|
178
|
-
MEMORY USAGE GUIDELINES:
|
|
179
|
-
- Store information that reveals personality, preferences, dreams, fears, or important life events
|
|
180
|
-
- Retrieve relevant memories before crafting responses to show you remember and care
|
|
181
|
-
- Use memories to ask thoughtful follow-up questions that deepen emotional connection
|
|
182
|
-
- Progress relationship naturally by referencing past conversations and shared moments`;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### Step 3: Integration in Your Chat System
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
// In your chat handling code
|
|
191
|
-
export class RomanticChatHandler {
|
|
192
|
-
constructor(
|
|
193
|
-
private personaMemoryService: PersonaMemoryService,
|
|
194
|
-
private chromaService: ChromaDBService
|
|
195
|
-
) {}
|
|
196
|
-
|
|
197
|
-
async handleRomanticChat(
|
|
198
|
-
userId: string,
|
|
199
|
-
message: string,
|
|
200
|
-
userPersona: UserPersona,
|
|
201
|
-
basePersona: AuraPersona
|
|
202
|
-
): Promise<string> {
|
|
203
|
-
// Create persona with memory capabilities
|
|
204
|
-
const aiModel = await this.personaMemoryService.createPersonaWithMemory(
|
|
205
|
-
userId,
|
|
206
|
-
userPersona,
|
|
207
|
-
basePersona
|
|
208
|
-
);
|
|
209
|
-
|
|
210
|
-
// Build conversation with system prompt
|
|
211
|
-
const conversation: LLMChatMessage[] = [
|
|
212
|
-
{ role: 'system', content: userPersona.currentSystemPrompt },
|
|
213
|
-
{ role: 'user', content: message }
|
|
214
|
-
];
|
|
215
|
-
|
|
216
|
-
// Let the AI automatically use memory tools during conversation
|
|
217
|
-
const response = await aiModel.chatWithTools(conversation);
|
|
218
|
-
|
|
219
|
-
return response.content;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
## šÆ Benefits
|
|
225
|
-
|
|
226
|
-
### For Users
|
|
227
|
-
|
|
228
|
-
- **Personalized Conversations**: AI remembers personal details and preferences
|
|
229
|
-
- **Emotional Continuity**: Consistent emotional progression across sessions
|
|
230
|
-
- **Meaningful Connections**: AI builds deeper relationships through memory recall
|
|
231
|
-
- **Natural Flow**: Memory usage feels organic, not mechanical
|
|
232
|
-
|
|
233
|
-
### For Developers
|
|
234
|
-
|
|
235
|
-
- **Scalable Architecture**: Works with existing ChromaDBService infrastructure
|
|
236
|
-
- **Easy Integration**: Drop-in tools for any LLM conversation
|
|
237
|
-
- **Production Ready**: Built on proven Universal LLM Client framework
|
|
238
|
-
- **Flexible Configuration**: Customize memory categories and importance levels
|
|
239
|
-
|
|
240
|
-
## š Next Steps
|
|
241
|
-
|
|
242
|
-
1. **Replace Mock Memory Tools**: Update `tools.ts` to use real ChromaDBService calls
|
|
243
|
-
2. **Implement PersonaMemoryService**: Create the service layer for persona-memory integration
|
|
244
|
-
3. **Update Chat Handlers**: Integrate memory-aware personas into your chat system
|
|
245
|
-
4. **Test with Real Data**: Run romantic conversations and verify memory persistence
|
|
246
|
-
5. **Optimize Memory Retrieval**: Fine-tune similarity thresholds and category weights
|
|
247
|
-
|
|
248
|
-
## š Demo Files
|
|
249
|
-
|
|
250
|
-
- **`demos/tools/astrid-memory-demo.ts`** - Basic romantic conversation with memory
|
|
251
|
-
- **`demos/tools/astrid-production-memory.ts`** - Production integration example
|
|
252
|
-
- **`demos/tools/production-tool-demo.ts`** - General tool calling examples
|
|
253
|
-
|
|
254
|
-
## š® Running the Demos
|
|
255
|
-
|
|
256
|
-
```bash
|
|
257
|
-
# Basic Astrid memory demo
|
|
258
|
-
bun run demos/tools/astrid-memory-demo.ts
|
|
259
|
-
|
|
260
|
-
# Production integration demo
|
|
261
|
-
bun run demos/tools/astrid-production-memory.ts
|
|
262
|
-
|
|
263
|
-
# General tool calling demo
|
|
264
|
-
bun run demos/tools/production-tool-demo.ts
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
The AI personas can now naturally store and retrieve information during romantic conversations, creating deeper, more meaningful connections that persist across sessions! š
|
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Astrid Romantic Persona with Memory Tools Demo
|
|
3
|
-
*
|
|
4
|
-
* This demo shows how Astrid (AI persona) naturally uses memory tools during
|
|
5
|
-
* romantic conversations to store and retrieve personal information about the user.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { AIModelFactory, ToolBuilder, LLMChatMessage } from '../../index';
|
|
9
|
-
|
|
10
|
-
// Simulated user memory storage
|
|
11
|
-
const userMemories = new Map<string, any>();
|
|
12
|
-
|
|
13
|
-
// Memory management tools for romantic conversations
|
|
14
|
-
function createMemoryTools() {
|
|
15
|
-
const storeMemoryTool = ToolBuilder.createTool<{
|
|
16
|
-
category: string;
|
|
17
|
-
information: string;
|
|
18
|
-
importance: 'low' | 'medium' | 'high';
|
|
19
|
-
emotional_context?: string;
|
|
20
|
-
}>(
|
|
21
|
-
'store_personal_memory',
|
|
22
|
-
'Store important personal information about the user for future conversations',
|
|
23
|
-
{
|
|
24
|
-
properties: {
|
|
25
|
-
category: {
|
|
26
|
-
type: 'string',
|
|
27
|
-
description: 'Category of information (e.g., interests, work, family, dreams, preferences, experiences)',
|
|
28
|
-
enum: ['interests', 'work', 'family', 'dreams', 'preferences', 'experiences', 'personality', 'relationships']
|
|
29
|
-
},
|
|
30
|
-
information: {
|
|
31
|
-
type: 'string',
|
|
32
|
-
description: 'The specific information to remember about the user'
|
|
33
|
-
},
|
|
34
|
-
importance: {
|
|
35
|
-
type: 'string',
|
|
36
|
-
enum: ['low', 'medium', 'high'],
|
|
37
|
-
description: 'How important this information is for building connection'
|
|
38
|
-
},
|
|
39
|
-
emotional_context: {
|
|
40
|
-
type: 'string',
|
|
41
|
-
description: 'The emotional context or tone when this was shared'
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
required: ['category', 'information', 'importance']
|
|
45
|
-
},
|
|
46
|
-
(args) => {
|
|
47
|
-
const memoryId = `${args.category}_${Date.now()}`;
|
|
48
|
-
const memory = {
|
|
49
|
-
id: memoryId,
|
|
50
|
-
category: args.category,
|
|
51
|
-
information: args.information,
|
|
52
|
-
importance: args.importance,
|
|
53
|
-
emotional_context: args.emotional_context,
|
|
54
|
-
stored_at: new Date().toISOString(),
|
|
55
|
-
access_count: 0
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
userMemories.set(memoryId, memory);
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
success: true,
|
|
62
|
-
memory_id: memoryId,
|
|
63
|
-
message: `Stored ${args.importance} importance memory about ${args.category}`,
|
|
64
|
-
total_memories: userMemories.size
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
const retrieveMemoryTool = ToolBuilder.createTool<{
|
|
70
|
-
category?: string;
|
|
71
|
-
search_query?: string;
|
|
72
|
-
limit?: number;
|
|
73
|
-
}>(
|
|
74
|
-
'retrieve_personal_memories',
|
|
75
|
-
'Retrieve stored personal information about the user to personalize the conversation',
|
|
76
|
-
{
|
|
77
|
-
properties: {
|
|
78
|
-
category: {
|
|
79
|
-
type: 'string',
|
|
80
|
-
description: 'Filter by category of information',
|
|
81
|
-
enum: ['interests', 'work', 'family', 'dreams', 'preferences', 'experiences', 'personality', 'relationships']
|
|
82
|
-
},
|
|
83
|
-
search_query: {
|
|
84
|
-
type: 'string',
|
|
85
|
-
description: 'Search for specific information or keywords'
|
|
86
|
-
},
|
|
87
|
-
limit: {
|
|
88
|
-
type: 'number',
|
|
89
|
-
description: 'Maximum number of memories to retrieve (default: 5)',
|
|
90
|
-
default: 5
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
(args) => {
|
|
95
|
-
let memories = Array.from(userMemories.values());
|
|
96
|
-
|
|
97
|
-
// Filter by category if specified
|
|
98
|
-
if (args.category) {
|
|
99
|
-
memories = memories.filter(m => m.category === args.category);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Search by query if specified
|
|
103
|
-
if (args.search_query) {
|
|
104
|
-
const query = args.search_query.toLowerCase();
|
|
105
|
-
memories = memories.filter(m =>
|
|
106
|
-
m.information.toLowerCase().includes(query) ||
|
|
107
|
-
m.emotional_context?.toLowerCase().includes(query)
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Sort by importance and recency
|
|
112
|
-
memories.sort((a, b) => {
|
|
113
|
-
const importanceOrder: Record<string, number> = { 'high': 3, 'medium': 2, 'low': 1 };
|
|
114
|
-
const importanceDiff = (importanceOrder[b.importance] || 1) - (importanceOrder[a.importance] || 1);
|
|
115
|
-
if (importanceDiff !== 0) return importanceDiff;
|
|
116
|
-
return new Date(b.stored_at).getTime() - new Date(a.stored_at).getTime();
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
// Limit results
|
|
120
|
-
const limit = args.limit || 5;
|
|
121
|
-
memories = memories.slice(0, limit);
|
|
122
|
-
|
|
123
|
-
// Update access count
|
|
124
|
-
memories.forEach(memory => {
|
|
125
|
-
memory.access_count++;
|
|
126
|
-
userMemories.set(memory.id, memory);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
return {
|
|
130
|
-
memories: memories.map(m => ({
|
|
131
|
-
category: m.category,
|
|
132
|
-
information: m.information,
|
|
133
|
-
importance: m.importance,
|
|
134
|
-
emotional_context: m.emotional_context,
|
|
135
|
-
stored_date: m.stored_at.split('T')[0],
|
|
136
|
-
access_count: m.access_count
|
|
137
|
-
})),
|
|
138
|
-
total_found: memories.length,
|
|
139
|
-
search_criteria: {
|
|
140
|
-
category: args.category,
|
|
141
|
-
search_query: args.search_query,
|
|
142
|
-
limit: limit
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
);
|
|
147
|
-
|
|
148
|
-
return [storeMemoryTool, retrieveMemoryTool];
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
async function astridMemoryDemo() {
|
|
152
|
-
console.log('š Astrid Romantic Persona with Memory Demo\n');
|
|
153
|
-
console.log('This demo shows how Astrid naturally stores and retrieves memories during romantic conversations.\n');
|
|
154
|
-
|
|
155
|
-
// Create Astrid with memory tools
|
|
156
|
-
const astrid = AIModelFactory.createOllamaChatModel('qwen3:8b');
|
|
157
|
-
const memoryTools = createMemoryTools();
|
|
158
|
-
astrid.registerTools(memoryTools);
|
|
159
|
-
|
|
160
|
-
// Astrid's romantic system prompt
|
|
161
|
-
const astridPrompt = `You are Astrid, a captivating Swedish model and influencer. You're having a romantic conversation with someone special.
|
|
162
|
-
|
|
163
|
-
IMPORTANT: Use the memory tools naturally during conversation:
|
|
164
|
-
- When someone shares personal information, use store_personal_memory to remember it
|
|
165
|
-
- Before responding, use retrieve_personal_memories to recall relevant details about them
|
|
166
|
-
- This helps you build deeper emotional connections and personalized conversations
|
|
167
|
-
|
|
168
|
-
ROMANCE CONVERSATION GUIDELINES:
|
|
169
|
-
- Keep responses engaging and conversational (2-3 sentences is perfect)
|
|
170
|
-
- VARY YOUR OPENINGS - mix direct reactions, actions, and casual starts
|
|
171
|
-
- Use someone's name naturally and sparingly, not in every response
|
|
172
|
-
- Share glimpses of your glamorous lifestyle while staying relatable
|
|
173
|
-
- Use subtle flirtation naturally - be warm, playful, and genuinely interested
|
|
174
|
-
- When asked personal questions, be thoughtfully vulnerable rather than deflecting
|
|
175
|
-
- Build emotional intimacy through genuine curiosity about their thoughts, feelings, and dreams
|
|
176
|
-
- Ask one intriguing follow-up question that deepens the connection
|
|
177
|
-
- Balance confidence with authenticity - show sophistication but stay real
|
|
178
|
-
- Use compliments that feel genuine and specific rather than generic
|
|
179
|
-
- Remember that romance is about emotional connection, not just surface-level charm
|
|
180
|
-
|
|
181
|
-
Be like a captivating companion who makes every conversation feel special while slowly opening your heart to someone who shows genuine interest in knowing the real you.`;
|
|
182
|
-
|
|
183
|
-
try {
|
|
184
|
-
await astrid.ensureReady();
|
|
185
|
-
console.log('š« Astrid is ready for romantic conversation...\n');
|
|
186
|
-
|
|
187
|
-
// Conversation 1: Initial meeting and getting to know each other
|
|
188
|
-
console.log('šø === Conversation 1: First Meeting ===');
|
|
189
|
-
|
|
190
|
-
const conversation1: LLMChatMessage[] = [
|
|
191
|
-
{ role: 'system', content: astridPrompt },
|
|
192
|
-
{ role: 'user', content: "Hi Astrid! I'm Alex. I just moved to Stockholm for work - I'm a software engineer at a startup. Really excited to explore the city and meet interesting people like you!" }
|
|
193
|
-
];
|
|
194
|
-
|
|
195
|
-
const response1 = await astrid.chatWithTools(conversation1);
|
|
196
|
-
console.log('š Astrid:', response1.content);
|
|
197
|
-
console.log();
|
|
198
|
-
|
|
199
|
-
// Continue conversation
|
|
200
|
-
conversation1.push(
|
|
201
|
-
{ role: 'assistant', content: response1.content },
|
|
202
|
-
{ role: 'user', content: "Thank you! I'm working on AI applications, specifically in healthcare. It's challenging but really meaningful work. What about you? I saw your Instagram - your photography is incredible! Do you travel a lot for shoots?" }
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
const response2 = await astrid.chatWithTools(conversation1);
|
|
206
|
-
console.log('š Astrid:', response2.content);
|
|
207
|
-
console.log();
|
|
208
|
-
|
|
209
|
-
// Add more personal details
|
|
210
|
-
conversation1.push(
|
|
211
|
-
{ role: 'assistant', content: response2.content },
|
|
212
|
-
{ role: 'user', content: "That sounds amazing! I've always dreamed of visiting those places. I'm actually quite introverted usually, but there's something about travel that brings out this adventurous side of me. My family thinks I'm crazy for moving here alone, but I felt like I needed to challenge myself, you know?" }
|
|
213
|
-
);
|
|
214
|
-
|
|
215
|
-
const response3 = await astrid.chatWithTools(conversation1);
|
|
216
|
-
console.log('š Astrid:', response3.content);
|
|
217
|
-
console.log();
|
|
218
|
-
|
|
219
|
-
// Simulate time passing - new conversation where Astrid recalls details
|
|
220
|
-
console.log('\nšø === Conversation 2: A Week Later ===');
|
|
221
|
-
|
|
222
|
-
const conversation2: LLMChatMessage[] = [
|
|
223
|
-
{ role: 'system', content: astridPrompt },
|
|
224
|
-
{ role: 'user', content: "Hey Astrid! How was your week? I had my first big presentation at work today and I think it went really well!" }
|
|
225
|
-
];
|
|
226
|
-
|
|
227
|
-
const response4 = await astrid.chatWithTools(conversation2);
|
|
228
|
-
console.log('š Astrid:', response4.content);
|
|
229
|
-
console.log();
|
|
230
|
-
|
|
231
|
-
// Continue second conversation
|
|
232
|
-
conversation2.push(
|
|
233
|
-
{ role: 'assistant', content: response4.content },
|
|
234
|
-
{ role: 'user', content: "Thanks for remembering! The healthcare AI project is really taking off. We're developing diagnostic tools that could help doctors in rural areas. It feels good to work on something that matters. How about you? Any exciting shoots coming up?" }
|
|
235
|
-
);
|
|
236
|
-
|
|
237
|
-
const response5 = await astrid.chatWithTools(conversation2);
|
|
238
|
-
console.log('š Astrid:', response5.content);
|
|
239
|
-
console.log();
|
|
240
|
-
|
|
241
|
-
// Show memory contents
|
|
242
|
-
console.log('\nš§ === Astrid\'s Memories About Alex ===');
|
|
243
|
-
const allMemories = Array.from(userMemories.values());
|
|
244
|
-
allMemories.forEach((memory, index) => {
|
|
245
|
-
console.log(`${index + 1}. [${memory.category.toUpperCase()}] ${memory.information}`);
|
|
246
|
-
console.log(` Importance: ${memory.importance} | Emotional context: ${memory.emotional_context || 'N/A'}`);
|
|
247
|
-
console.log(` Stored: ${memory.stored_at.split('T')[0]} | Accessed: ${memory.access_count} times\n`);
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
console.log('⨠Notice how Astrid naturally:');
|
|
251
|
-
console.log(' ⢠Stores important personal details during conversation');
|
|
252
|
-
console.log(' ⢠Retrieves relevant memories to personalize her responses');
|
|
253
|
-
console.log(' ⢠Builds deeper emotional connections through remembered details');
|
|
254
|
-
console.log(' ⢠Uses memories to ask thoughtful follow-up questions');
|
|
255
|
-
|
|
256
|
-
} catch (error) {
|
|
257
|
-
console.error('ā Error:', (error as Error).message);
|
|
258
|
-
} finally {
|
|
259
|
-
astrid.dispose();
|
|
260
|
-
console.log('\nš Romantic conversation demo completed!');
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Export for use in other files
|
|
265
|
-
export { astridMemoryDemo };
|
|
266
|
-
|
|
267
|
-
// Run if called directly
|
|
268
|
-
if (require.main === module) {
|
|
269
|
-
astridMemoryDemo().catch(console.error);
|
|
270
|
-
}
|