memory-improvements / src /integrationGuide.ts
loudiman's picture
Add integrationGuide documentation
cca0d89 verified
// ============================================================
// 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;
}
*/