| // ============================================================ | |
| // 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; | |
| } | |
| */ | |