UNPKG

il2cpp-dump-analyzer-mcp

Version:

Agentic RAG system for analyzing IL2CPP dump.cs files from Unity games

246 lines 10.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EnhancedSupabaseVectorStore = void 0; const documents_1 = require("@langchain/core/documents"); const connection_manager_1 = require("./connection-manager"); const retry_manager_1 = require("./retry-manager"); const performance_monitor_1 = require("./performance-monitor"); const crypto_1 = __importDefault(require("crypto")); /** * Enhanced Supabase vector store with performance optimizations, * connection pooling, retry logic, and advanced search capabilities */ class EnhancedSupabaseVectorStore { constructor(embeddings, tableName = 'il2cpp_documents') { this.embeddings = embeddings; this.tableName = tableName; this.isInitialized = false; // Initialize connection manager this.connectionManager = connection_manager_1.SupabaseConnectionManager.getInstance(); // Initialize retry manager for database operations this.retryManager = retry_manager_1.RetryManager.forDatabase({ maxAttempts: 3, initialDelayMs: 500, maxDelayMs: 5000 }); // Initialize circuit breaker this.circuitBreaker = new retry_manager_1.CircuitBreaker(5, 60000); // Initialize performance monitor this.performanceMonitor = new performance_monitor_1.DatabasePerformanceMonitor(); // Get embedding dimensions this.dimensions = embeddings.getDimension?.() || 384; console.log(`Enhanced Supabase vector store initialized with ${this.dimensions} dimensions`); } /** * Initialize the vector store */ async initialize() { if (this.isInitialized) return; await this.retryManager.execute(async () => { const client = this.connectionManager.getClient(); // Verify table exists and is accessible const { error } = await client .from(this.tableName) .select('id') .limit(1); if (error && error.code === '42P01') { throw new Error(`Table ${this.tableName} does not exist. Please run the setup SQL commands.`); } this.isInitialized = true; }, 'vector_store_initialization'); } /** * Add documents to the vector store with enhanced error handling */ async addDocuments(documents) { await this.initialize(); if (documents.length === 0) return; return this.circuitBreaker.execute(async () => { return this.retryManager.execute(async () => { const client = this.connectionManager.getClient(); // Generate embeddings for all documents const embeddings = await this.embeddings.embedDocuments(documents.map(doc => doc.pageContent)); // Process in batches to avoid memory issues const batchSize = 50; const totalBatches = Math.ceil(documents.length / batchSize); for (let i = 0; i < documents.length; i += batchSize) { const batch = documents.slice(i, i + batchSize); const batchEmbeddings = embeddings.slice(i, i + batchSize); const batchNumber = Math.floor(i / batchSize) + 1; // Prepare batch data with document hashes for deduplication const batchData = batch.map((doc, idx) => ({ content: doc.pageContent, metadata: doc.metadata, embedding: batchEmbeddings[idx], document_hash: this.generateDocumentHash(doc) })); // Insert with conflict resolution const { error } = await client .from(this.tableName) .upsert(batchData, { onConflict: 'document_hash', ignoreDuplicates: true }); if (error) { console.error(`Batch ${batchNumber}/${totalBatches} failed:`, error); throw error; } console.log(`Batch ${batchNumber}/${totalBatches}: Added ${batch.length} documents`); } // Clear related cache entries this.performanceMonitor.clearCache('search_*'); this.connectionManager.releaseClient(); }, 'add_documents_batch'); }); } /** * Enhanced similarity search with caching and performance monitoring */ async similaritySearch(query, options = {}) { await this.initialize(); const { k = 5, threshold = 0.0, filters = {}, hybridSearch = false, textWeight = 0.3, vectorWeight = 0.7, useCache = true, cacheTtlMs = 300000 // 5 minutes } = options; // Generate cache key const cacheKey = this.generateCacheKey('search', query, options); // Try cache first if enabled if (useCache) { const cached = this.performanceMonitor.getCached(cacheKey); if (cached) { return cached.map((result) => ({ ...result, cached: true })); } } return this.circuitBreaker.execute(async () => { return this.retryManager.execute(async () => { const client = this.connectionManager.getClient(); // Generate query embedding const queryEmbedding = await this.embeddings.embedQuery(query); let results; if (hybridSearch) { // Use hybrid search function const { data, error } = await client.rpc('hybrid_search', { query_text: query, query_embedding: queryEmbedding, match_threshold: threshold, match_count: k, text_weight: textWeight, vector_weight: vectorWeight }); if (error) throw error; results = data || []; } else if (Object.keys(filters).length > 0) { // Use filtered search function const { data, error } = await client.rpc('match_documents_filtered', { query_embedding: queryEmbedding, match_threshold: threshold, match_count: k, filter_metadata: filters }); if (error) throw error; results = data || []; } else { // Use standard search function const { data, error } = await client.rpc('match_documents', { query_embedding: queryEmbedding, match_threshold: threshold, match_count: k }); if (error) throw error; results = data || []; } // Convert to enhanced search results const enhancedResults = results.map(row => ({ document: new documents_1.Document({ pageContent: row.content, metadata: row.metadata }), similarity: row.similarity || row.vector_score, textScore: row.text_score, combinedScore: row.combined_score, cached: false })); // Cache results if enabled if (useCache) { this.performanceMonitor.cache(cacheKey, enhancedResults, cacheTtlMs); } this.connectionManager.releaseClient(); return enhancedResults; }, 'similarity_search_query'); }); } /** * Add code chunks with metadata enhancement */ async addCodeChunks(chunks) { const documents = chunks.map(chunk => new documents_1.Document({ pageContent: chunk.text, metadata: { ...chunk.metadata, chunk_type: 'il2cpp_code', added_at: new Date().toISOString() } })); await this.addDocuments(documents); } /** * Get database statistics and health information */ async getHealthStatus() { const connectionHealth = this.connectionManager.getHealthStatus(); const performanceStats = this.performanceMonitor.getStats(); const cacheStats = this.performanceMonitor.getCacheStats(); const circuitBreakerStats = this.circuitBreaker.getStats(); return { isHealthy: connectionHealth.isHealthy && this.circuitBreaker.getState() !== 'OPEN', connectionStats: connectionHealth, performanceStats, cacheStats, circuitBreakerStats }; } /** * Generate document hash for deduplication */ generateDocumentHash(document) { const content = document.pageContent + JSON.stringify(document.metadata); return crypto_1.default.createHash('sha256').update(content).digest('hex'); } /** * Generate cache key for search operations */ generateCacheKey(operation, query, options) { const optionsHash = crypto_1.default.createHash('md5') .update(JSON.stringify(options)) .digest('hex'); return `${operation}_${crypto_1.default.createHash('md5').update(query).digest('hex')}_${optionsHash}`; } /** * Clear all caches */ clearCache() { this.performanceMonitor.clearCache(); } /** * Export performance metrics */ exportMetrics() { return this.performanceMonitor.exportMetrics(); } /** * Cleanup resources */ async cleanup() { await this.connectionManager.cleanup(); } } exports.EnhancedSupabaseVectorStore = EnhancedSupabaseVectorStore; //# sourceMappingURL=enhanced-vector-store.js.map