UNPKG

claude-flow

Version:

Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration

607 lines (529 loc) 16.4 kB
/** * @claude-flow/memory - V3 Unified Memory System * * Provides a unified memory interface backed by AgentDB with HNSW indexing * for 150x-12,500x faster vector search compared to brute-force approaches. * * @module @claude-flow/memory * * @example * ```typescript * import { UnifiedMemoryService, query, QueryTemplates } from '@claude-flow/memory'; * * // Initialize the memory service * const memory = new UnifiedMemoryService({ * dimensions: 1536, * cacheEnabled: true, * embeddingGenerator: async (text) => embeddings.embed(text), * }); * * await memory.initialize(); * * // Store entries * await memory.store({ * key: 'auth-patterns', * content: 'OAuth 2.0 implementation patterns for secure authentication', * tags: ['auth', 'security', 'patterns'], * }); * * // Semantic search * const results = await memory.semanticSearch('user authentication best practices', 5); * * // Query with fluent builder * const entries = await memory.query( * query() * .semantic('security vulnerabilities') * .inNamespace('security') * .withTags(['critical']) * .threshold(0.8) * .limit(10) * .build() * ); * ``` */ // ===== Core Types ===== export type { // Memory Entry Types MemoryType, AccessLevel, ConsistencyLevel, DistanceMetric, MemoryEntry, MemoryEntryInput, MemoryEntryUpdate, // Query Types QueryType, MemoryQuery, SearchResult, SearchOptions, // HNSW Types HNSWConfig, HNSWStats, QuantizationConfig, // Backend Types IMemoryBackend, BackendStats, HealthCheckResult, ComponentHealth, // Cache Types CacheConfig, CacheStats, CachedEntry, // Migration Types MigrationSource, MigrationConfig, MigrationProgress, MigrationResult, MigrationError, // Event Types MemoryEventType, MemoryEvent, MemoryEventHandler, // SONA Types SONAMode, LearningPattern, // Utility Types EmbeddingGenerator, } from './types.js'; // Utility Functions and Constants (runtime values) export { generateMemoryId, createDefaultEntry, PERFORMANCE_TARGETS, } from './types.js'; // ===== Auto Memory Bridge (ADR-048) ===== export { AutoMemoryBridge, resolveAutoMemoryDir, findGitRoot } from './auto-memory-bridge.js'; export type { AutoMemoryBridgeConfig, MemoryInsight, InsightCategory, SyncDirection, SyncMode, PruneStrategy, SyncResult, ImportResult, } from './auto-memory-bridge.js'; // ===== Learning Bridge ===== export { LearningBridge } from './learning-bridge.js'; export type { LearningBridgeConfig, LearningStats, ConsolidateResult, PatternMatch, } from './learning-bridge.js'; // ===== RVF Learning Persistence (ADR-057 Phase 6) ===== export { RvfLearningStore } from './rvf-learning-store.js'; export type { RvfLearningStoreConfig, PatternRecord, LoraRecord, EwcRecord, TrajectoryRecord, } from './rvf-learning-store.js'; export { PersistentSonaCoordinator } from './persistent-sona.js'; export type { PersistentSonaConfig } from './persistent-sona.js'; // ===== RVF Migration (Bidirectional) ===== export { RvfMigrator } from './rvf-migration.js'; export type { RvfMigrationOptions, RvfMigrationResult } from './rvf-migration.js'; // ===== Knowledge Graph ===== export { MemoryGraph } from './memory-graph.js'; export type { MemoryGraphConfig, GraphNode, GraphEdge, GraphStats, RankedResult, EdgeType, } from './memory-graph.js'; // ===== Agent-Scoped Memory ===== export { resolveAgentMemoryDir, createAgentBridge, transferKnowledge, listAgentScopes, } from './agent-memory-scope.js'; export type { AgentMemoryScope, AgentScopedConfig, TransferOptions, TransferResult, } from './agent-memory-scope.js'; // ===== Controller Registry (ADR-053) ===== export { ControllerRegistry, INIT_LEVELS } from './controller-registry.js'; export type { AgentDBControllerName, CLIControllerName, ControllerName, InitLevel, ControllerHealth, RegistryHealthReport, RuntimeConfig, } from './controller-registry.js'; // ===== Core Components ===== export { AgentDBAdapter } from './agentdb-adapter.js'; export type { AgentDBAdapterConfig } from './agentdb-adapter.js'; export { AgentDBBackend } from './agentdb-backend.js'; export type { AgentDBBackendConfig } from './agentdb-backend.js'; export { SQLiteBackend } from './sqlite-backend.js'; export type { SQLiteBackendConfig } from './sqlite-backend.js'; export { SqlJsBackend } from './sqljs-backend.js'; export type { SqlJsBackendConfig } from './sqljs-backend.js'; export { HybridBackend } from './hybrid-backend.js'; export type { HybridBackendConfig, StructuredQuery, SemanticQuery, HybridQuery, } from './hybrid-backend.js'; export { RvfBackend } from './rvf-backend.js'; export type { RvfBackendConfig } from './rvf-backend.js'; export { HnswLite, cosineSimilarity } from './hnsw-lite.js'; export type { HnswSearchResult } from './hnsw-lite.js'; export { HNSWIndex } from './hnsw-index.js'; export { CacheManager, TieredCacheManager } from './cache-manager.js'; export { QueryBuilder, query, QueryTemplates } from './query-builder.js'; export type { SortDirection, SortField } from './query-builder.js'; export { MemoryMigrator, createMigrator, migrateMultipleSources } from './migration.js'; export { createDatabase, getPlatformInfo, getAvailableProviders } from './database-provider.js'; export type { DatabaseProvider, DatabaseOptions } from './database-provider.js'; // ===== Smart Retrieval (ADR-090) ===== export { smartSearch, defaultQueryExpansions } from './smart-retrieval.js'; export type { SearchCandidate, RawSearchRequest, RawSearchResponse, SearchFn, SmartSearchOptions, SmartSearchStats, SmartSearchResult, } from './smart-retrieval.js'; // ===== Unified Memory Service ===== import { EventEmitter } from 'node:events'; import { IMemoryBackend, MemoryEntry, MemoryEntryInput, MemoryEntryUpdate, MemoryQuery, SearchResult, SearchOptions, BackendStats, HealthCheckResult, EmbeddingGenerator, MigrationSource, MigrationConfig, MigrationResult, } from './types.js'; import { AgentDBAdapter, AgentDBAdapterConfig } from './agentdb-adapter.js'; import { MemoryMigrator } from './migration.js'; /** * Configuration for UnifiedMemoryService */ export interface UnifiedMemoryServiceConfig extends Partial<AgentDBAdapterConfig> { /** Enable automatic embedding generation */ autoEmbed?: boolean; /** Default embedding dimensions */ dimensions?: number; /** Embedding generator function */ embeddingGenerator?: EmbeddingGenerator; } /** * Unified Memory Service * * High-level interface for the V3 memory system that provides: * - Simple API for common operations * - Automatic embedding generation * - Cross-agent memory sharing * - SONA integration for learning * - Event-driven notifications * - Performance monitoring */ export class UnifiedMemoryService extends EventEmitter implements IMemoryBackend { private adapter: AgentDBAdapter; private config: UnifiedMemoryServiceConfig; private initialized: boolean = false; constructor(config: UnifiedMemoryServiceConfig = {}) { super(); this.config = { dimensions: 1536, cacheEnabled: true, autoEmbed: true, ...config, }; this.adapter = new AgentDBAdapter({ dimensions: this.config.dimensions, cacheEnabled: this.config.cacheEnabled, cacheSize: this.config.cacheSize, cacheTtl: this.config.cacheTtl, hnswM: this.config.hnswM, hnswEfConstruction: this.config.hnswEfConstruction, defaultNamespace: this.config.defaultNamespace, embeddingGenerator: this.config.embeddingGenerator, persistenceEnabled: this.config.persistenceEnabled, persistencePath: this.config.persistencePath, maxEntries: this.config.maxEntries, }); // Forward adapter events this.adapter.on('entry:stored', (data) => this.emit('entry:stored', data)); this.adapter.on('entry:updated', (data) => this.emit('entry:updated', data)); this.adapter.on('entry:deleted', (data) => this.emit('entry:deleted', data)); this.adapter.on('cache:hit', (data) => this.emit('cache:hit', data)); this.adapter.on('cache:miss', (data) => this.emit('cache:miss', data)); this.adapter.on('index:added', (data) => this.emit('index:added', data)); } // ===== Lifecycle ===== async initialize(): Promise<void> { if (this.initialized) return; await this.adapter.initialize(); this.initialized = true; this.emit('initialized'); } async shutdown(): Promise<void> { if (!this.initialized) return; await this.adapter.shutdown(); this.initialized = false; this.emit('shutdown'); } // ===== IMemoryBackend Implementation ===== async store(entry: MemoryEntry): Promise<void> { return this.adapter.store(entry); } async get(id: string): Promise<MemoryEntry | null> { return this.adapter.get(id); } async getByKey(namespace: string, key: string): Promise<MemoryEntry | null> { return this.adapter.getByKey(namespace, key); } async update(id: string, update: MemoryEntryUpdate): Promise<MemoryEntry | null> { return this.adapter.update(id, update); } async delete(id: string): Promise<boolean> { return this.adapter.delete(id); } async query(query: MemoryQuery): Promise<MemoryEntry[]> { return this.adapter.query(query); } async search(embedding: Float32Array, options: SearchOptions): Promise<SearchResult[]> { return this.adapter.search(embedding, options); } async bulkInsert(entries: MemoryEntry[]): Promise<void> { return this.adapter.bulkInsert(entries); } async bulkDelete(ids: string[]): Promise<number> { return this.adapter.bulkDelete(ids); } async count(namespace?: string): Promise<number> { return this.adapter.count(namespace); } async listNamespaces(): Promise<string[]> { return this.adapter.listNamespaces(); } async clearNamespace(namespace: string): Promise<number> { return this.adapter.clearNamespace(namespace); } async getStats(): Promise<BackendStats> { return this.adapter.getStats(); } async healthCheck(): Promise<HealthCheckResult> { return this.adapter.healthCheck(); } // ===== Convenience Methods ===== /** * Store an entry from simple input */ async storeEntry(input: MemoryEntryInput): Promise<MemoryEntry> { return this.adapter.storeEntry(input); } /** * Semantic search by content string */ async semanticSearch( content: string, k: number = 10, threshold?: number ): Promise<SearchResult[]> { return this.adapter.semanticSearch(content, k, threshold); } /** * Find similar entries to a given entry */ async findSimilar(id: string, k: number = 5): Promise<SearchResult[]> { const entry = await this.get(id); if (!entry || !entry.embedding) { return []; } const results = await this.search(entry.embedding, { k: k + 1 }); // Filter out the source entry return results.filter((r) => r.entry.id !== id).slice(0, k); } /** * Get or create an entry */ async getOrCreate( namespace: string, key: string, creator: () => MemoryEntryInput | Promise<MemoryEntryInput> ): Promise<MemoryEntry> { const existing = await this.getByKey(namespace, key); if (existing) return existing; const input = await creator(); return this.storeEntry({ ...input, namespace, key }); } /** * Append content to an existing entry */ async appendContent(id: string, content: string): Promise<MemoryEntry | null> { const entry = await this.get(id); if (!entry) return null; return this.update(id, { content: entry.content + '\n' + content, }); } /** * Add tags to an existing entry */ async addTags(id: string, tags: string[]): Promise<MemoryEntry | null> { const entry = await this.get(id); if (!entry) return null; const newTags = [...new Set([...entry.tags, ...tags])]; return this.update(id, { tags: newTags }); } /** * Remove tags from an existing entry */ async removeTags(id: string, tags: string[]): Promise<MemoryEntry | null> { const entry = await this.get(id); if (!entry) return null; const newTags = entry.tags.filter((t) => !tags.includes(t)); return this.update(id, { tags: newTags }); } // ===== Migration ===== /** * Migrate from a legacy memory source */ async migrateFrom( source: MigrationSource, sourcePath: string, options: Partial<MigrationConfig> = {} ): Promise<MigrationResult> { const migrator = new MemoryMigrator( this.adapter, { source, sourcePath, ...options }, this.config.embeddingGenerator ); // Forward migration events migrator.on('migration:started', (data) => this.emit('migration:started', data)); migrator.on('migration:progress', (data) => this.emit('migration:progress', data)); migrator.on('migration:completed', (data) => this.emit('migration:completed', data)); migrator.on('migration:failed', (data) => this.emit('migration:failed', data)); migrator.on('migration:error', (data) => this.emit('migration:error', data)); migrator.on('migration:warning', (data) => this.emit('migration:warning', data)); return migrator.migrate(); } // ===== Cross-Agent Memory Sharing ===== /** * Share an entry with another agent */ async shareWith(id: string, agentId: string): Promise<MemoryEntry | null> { const entry = await this.get(id); if (!entry) return null; const sharedWith = (entry.metadata.sharedWith as string[]) || []; if (!sharedWith.includes(agentId)) { sharedWith.push(agentId); } return this.update(id, { metadata: { ...entry.metadata, sharedWith }, }); } /** * Get entries shared with a specific agent */ async getSharedWith(agentId: string): Promise<MemoryEntry[]> { const all = await this.query({ type: 'hybrid', limit: 10000 }); return all.filter((entry) => { const sharedWith = (entry.metadata.sharedWith as string[]) || []; return sharedWith.includes(agentId); }); } // ===== Utility ===== /** * Get the underlying adapter for advanced operations */ getAdapter(): AgentDBAdapter { return this.adapter; } /** * Check if the service is initialized */ isInitialized(): boolean { return this.initialized; } } // ===== Factory Functions ===== /** * Create a simple in-memory service (for testing) */ export function createInMemoryService(): UnifiedMemoryService { return new UnifiedMemoryService({ persistenceEnabled: false, cacheEnabled: true, }); } /** * Create a persistent memory service */ export function createPersistentService(path: string): UnifiedMemoryService { return new UnifiedMemoryService({ persistenceEnabled: true, persistencePath: path, cacheEnabled: true, }); } /** * Create a memory service with embedding support */ export function createEmbeddingService( embeddingGenerator: EmbeddingGenerator, dimensions: number = 1536 ): UnifiedMemoryService { return new UnifiedMemoryService({ embeddingGenerator, dimensions, autoEmbed: true, cacheEnabled: true, }); } /** * Create a hybrid memory service (SQLite + AgentDB) * This is the DEFAULT recommended configuration per ADR-009 * * @example * ```typescript * const memory = createHybridService('./data/memory.db', embeddingFn); * await memory.initialize(); * * // Structured queries go to SQLite * const user = await memory.getByKey('users', 'john@example.com'); * * // Semantic queries go to AgentDB * const similar = await memory.semanticSearch('authentication patterns', 10); * ``` */ export function createHybridService( databasePath: string, embeddingGenerator: EmbeddingGenerator, dimensions: number = 1536 ): UnifiedMemoryService { return new UnifiedMemoryService({ embeddingGenerator, dimensions, autoEmbed: true, cacheEnabled: true, // Note: This would require extending UnifiedMemoryService to support HybridBackend // For now, this creates an AgentDB service with persistence persistenceEnabled: true, persistencePath: databasePath, }); } // Default export export default UnifiedMemoryService;