File size: 9,667 Bytes
cca0d89 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | // ============================================================
// INTEGRATION GUIDE
// How to plug these improvements into your existing codebase
// ============================================================
/**
* This file shows the EXACT changes to make in each file of your
* existing React Native app. Each section maps to a specific file
* in your codebase.
*/
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// FILE: features/memory/infrastructure/memoryVectorStore.ts
// CHANGE: Replace direct INSERT with dedup-aware store
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
BEFORE (line ~28):
export async function storeMemory(text: string, embedding: number[]) {
await db.run(
'INSERT INTO memories (text, embedding) VALUES (?, vec_f32(?))',
[text, JSON.stringify(embedding)]
);
}
AFTER:
import { ImprovedMemoryService } from '../../../memory-improvements/src';
const memoryService = new ImprovedMemoryService(db, embedFn, config);
export async function storeMemory(text: string, embedding: number[]) {
return memoryService.storeUserMessage(text, embedding);
}
*/
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// FILE: features/memory/application/useSemanticMemory.ts
// CHANGE: Replace fixed top-5/0.45 with dynamic retrieval
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
BEFORE (line ~6):
export function useSemanticMemory() {
const searchMemories = async (embedding: number[]) => {
const results = await db.getAll(
`SELECT text FROM memories
WHERE vec_distance_cosine(embedding, vec_f32(?)) <= ?
ORDER BY vec_distance_cosine(embedding, vec_f32(?)) ASC
LIMIT 5`,
[JSON.stringify(embedding), 0.55, JSON.stringify(embedding)]
);
return results
.filter(r => (1 - r.distance) >= 0.45)
.map(r => r.text);
};
return { searchMemories };
}
AFTER:
import { ImprovedMemoryService } from '../../../memory-improvements/src';
export function useSemanticMemory(memoryService: ImprovedMemoryService) {
const searchMemories = async (userMessage: string, embedding: number[]) => {
const { context, memoryIds } = await memoryService.retrieve(userMessage, embedding);
return context;
};
return { searchMemories };
}
*/
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// FILE: features/memory/application/memoryService.ts
// CHANGE: Replace scoreMessage with smart filtering
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
BEFORE (line ~20):
export function scoreMessage(text: string): boolean {
if (text.length < 10) return false;
if (isSmallTalk(text)) return false;
return true;
}
AFTER:
import { shouldStoreUserMessage } from '../../../memory-improvements/src/smartFilter';
export function scoreMessage(text: string): { store: boolean; textToStore: string } {
return shouldStoreUserMessage(text);
}
*/
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// FILE: features/chat/application/ChatGenerationContext.tsx
// CHANGE: Add assistant memory storage after reply generation
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
BEFORE (line ~179):
await saveMessage(conversationId, 'assistant', responseBuffer);
AFTER:
await saveMessage(conversationId, 'assistant', responseBuffer);
await memoryService.storeAssistantReply(responseBuffer); // NEW
*/
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// FILE: features/chat/application/ChatGenerationContext.tsx
// CHANGE: Pass user message text to retrieval (not just embedding)
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
BEFORE (line ~139):
const sharedEmbedding = embed(userText);
const memories = await searchMemories(sharedEmbedding);
AFTER:
const sharedEmbedding = await embed(userText);
const { context: memories } = await memoryService.retrieve(userText, sharedEmbedding);
*/
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// FILE: features/chat/domain/constants.ts
// CHANGE: Use structured memory format in system prompt
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
BEFORE (line ~26):
export function buildSystemPrompt(characterName: string, memories: string[]): string {
const memorySection = memories.length > 0
? `\n\nPast context:\n${memories.map(m => `- ${m}`).join('\n')}`
: '';
return `Your name is ${characterName}. You are a casual AI companion texting on Messenger.${memorySection}`;
}
AFTER:
export function buildSystemPrompt(characterName: string, formattedMemories: string): string {
const memorySection = formattedMemories ? `\n\n${formattedMemories}` : '';
return `Your name is ${characterName}. You are a casual AI companion texting on Messenger.${memorySection}`;
}
// Output format:
// About the user:
// - Allergic to peanuts
// - Likes spicy noodles
//
// Recent events:
// - Went to the dentist yesterday
//
// Instructions:
// - Always suggest peanut-free options
*/
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// FILE: features/memory/MemoryProvider.tsx (NEW FILE)
// CHANGE: Initialize the improved memory service
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
import React, { createContext, useContext, useState } from 'react';
import { ImprovedMemoryService, DEFAULT_MEMORY_CONFIG } from '../memory-improvements/src';
const MemoryContext = createContext<ImprovedMemoryService | null>(null);
export function MemoryProvider({ children, db, embedFn }: {
children: React.ReactNode;
db: any;
embedFn: (text: string) => Promise<number[]>;
}) {
const [service] = useState(() => new ImprovedMemoryService(db, embedFn, {
...DEFAULT_MEMORY_CONFIG,
}));
return (
<MemoryContext.Provider value={service}>
{children}
</MemoryContext.Provider>
);
}
export function useMemoryService(): ImprovedMemoryService {
const service = useContext(MemoryContext);
if (!service) throw new Error('useMemoryService must be used within MemoryProvider');
return service;
}
*/
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// DATABASE MIGRATION (run once on app update)
// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/*
async function initDatabase() {
const db = await open({ name: 'chat.db' });
const { user_version } = await db.get('PRAGMA user_version');
if (user_version < 2) {
await db.transaction(async (tx) => {
await tx.run(`
CREATE TABLE IF NOT EXISTS memories_v2 (
id TEXT PRIMARY KEY,
text TEXT NOT NULL,
embedding BLOB NOT NULL,
type TEXT NOT NULL DEFAULT 'semantic',
source TEXT NOT NULL DEFAULT 'user',
created_at INTEGER NOT NULL,
last_accessed_at INTEGER NOT NULL,
access_count INTEGER NOT NULL DEFAULT 0,
importance REAL NOT NULL DEFAULT 0.5,
conversation_id TEXT,
metadata TEXT
)
`);
const existing = await tx.getAll('SELECT * FROM memories');
for (const row of existing) {
await tx.run(
`INSERT INTO memories_v2 VALUES (?, ?, ?, 'semantic', 'user', ?, ?, 0, 0.5, NULL, NULL)`,
[`mem_${row.id}`, row.text, row.embedding, Date.now(), Date.now()]
);
}
await tx.run('PRAGMA user_version = 2');
});
}
return db;
}
*/
|