il2cpp-dump-analyzer-mcp
Version:
Agentic RAG system for analyzing IL2CPP dump.cs files from Unity games
246 lines • 10.5 kB
JavaScript
"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