vector-chunk
Version:
🚀 Next-Gen Content Intelligence - The most powerful, lightweight, and intelligent vector search package for modern applications. Zero dependencies, AI-powered search, real-time processing, content analysis, tone detection, style matching, DNA fingerprint
301 lines (300 loc) • 12.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AdaptiveOptimizer = void 0;
class AdaptiveOptimizer {
constructor(optimizationConfig = {}, adaptiveConfig = {}) {
this.performanceHistory = [];
this.optimizationCount = 0;
this.lastOptimization = Date.now();
this.config = {
enableAutoOptimization: true,
learningRate: 0.1,
performanceThreshold: 0.8,
optimizationInterval: 60000,
maxOptimizationAttempts: 10,
...optimizationConfig
};
this.adaptiveConfig = {
enableLearning: true,
performanceTracking: true,
autoTuning: true,
optimizationStrategy: 'balanced',
...adaptiveConfig
};
}
recordMetrics(metrics) {
if (!this.adaptiveConfig.performanceTracking)
return;
const performanceMetric = {
...metrics,
timestamp: new Date()
};
this.performanceHistory.push(performanceMetric);
if (this.performanceHistory.length > 100) {
this.performanceHistory = this.performanceHistory.slice(-100);
}
if (this.shouldAutoOptimize()) {
this.autoOptimize();
}
}
optimizeChunkSize(currentConfig) {
if (!this.config.enableAutoOptimization || this.performanceHistory.length < 5) {
return currentConfig;
}
const optimalSize = this.calculateOptimalChunkSize();
const optimalOverlap = this.calculateOptimalOverlap(optimalSize);
const optimizedConfig = {
...currentConfig,
chunkSize: optimalSize,
overlap: optimalOverlap
};
return optimizedConfig;
}
optimizeSearchConfig(currentConfig) {
if (!this.config.enableAutoOptimization || this.performanceHistory.length < 5) {
return currentConfig;
}
const optimalThreshold = this.calculateOptimalThreshold();
const optimalMaxResults = this.calculateOptimalMaxResults();
const optimizedConfig = {
...currentConfig,
threshold: optimalThreshold,
maxResults: optimalMaxResults
};
return optimizedConfig;
}
getOptimizationRecommendations() {
if (this.performanceHistory.length < 3) {
return {
chunkSize: { current: 512, recommended: 512, confidence: 0 },
overlap: { current: 50, recommended: 50, confidence: 0 },
threshold: { current: 0.0, recommended: 0.0, confidence: 0 },
maxResults: { current: 10, recommended: 10, confidence: 0 },
overallImprovement: 0
};
}
const optimalChunkSize = this.calculateOptimalChunkSize();
const optimalOverlap = this.calculateOptimalOverlap(optimalChunkSize);
const optimalThreshold = this.calculateOptimalThreshold();
const optimalMaxResults = this.calculateOptimalMaxResults();
const currentChunkSize = this.performanceHistory[this.performanceHistory.length - 1]?.chunkSize || 512;
const currentOverlap = 50;
const currentThreshold = 0.0;
const currentMaxResults = 10;
const chunkSizeConfidence = this.calculateConfidence('chunkSize');
const overlapConfidence = 0.5;
const thresholdConfidence = 0.5;
const maxResultsConfidence = 0.5;
const overallImprovement = this.calculateOverallImprovement();
return {
chunkSize: {
current: currentChunkSize,
recommended: optimalChunkSize,
confidence: chunkSizeConfidence
},
overlap: {
current: currentOverlap,
recommended: optimalOverlap,
confidence: overlapConfidence
},
threshold: {
current: currentThreshold,
recommended: optimalThreshold,
confidence: thresholdConfidence
},
maxResults: {
current: currentMaxResults,
recommended: optimalMaxResults,
confidence: maxResultsConfidence
},
overallImprovement
};
}
getPerformanceAnalytics() {
if (this.performanceHistory.length === 0) {
return {
averageSearchTime: 0,
averageAccuracy: 0,
performanceTrend: 'stable',
optimizationHistory: []
};
}
const recentMetrics = this.performanceHistory.slice(-20);
const averageSearchTime = recentMetrics.reduce((sum, m) => sum + m.searchTime, 0) / recentMetrics.length;
const averageAccuracy = recentMetrics.reduce((sum, m) => sum + m.accuracy, 0) / recentMetrics.length;
const performanceTrend = this.calculatePerformanceTrend();
const optimizationHistory = this.getOptimizationHistory();
return {
averageSearchTime,
averageAccuracy,
performanceTrend,
optimizationHistory
};
}
resetOptimization() {
this.performanceHistory = [];
this.optimizationCount = 0;
this.lastOptimization = Date.now();
}
updateConfig(newConfig) {
this.config = { ...this.config, ...newConfig };
}
updateAdaptiveConfig(newConfig) {
this.adaptiveConfig = { ...this.adaptiveConfig, ...newConfig };
}
shouldAutoOptimize() {
if (!this.config.enableAutoOptimization)
return false;
if (this.optimizationCount >= this.config.maxOptimizationAttempts)
return false;
const timeSinceLastOptimization = Date.now() - this.lastOptimization;
if (timeSinceLastOptimization < this.config.optimizationInterval)
return false;
if (this.performanceHistory.length < 5)
return false;
const recentPerformance = this.performanceHistory.slice(-5);
const averageAccuracy = recentPerformance.reduce((sum, m) => sum + m.accuracy, 0) / recentPerformance.length;
return averageAccuracy < this.config.performanceThreshold;
}
autoOptimize() {
this.optimizationCount++;
this.lastOptimization = Date.now();
}
calculateOptimalChunkSize() {
if (this.performanceHistory.length < 3)
return 512;
const sizePerformanceMap = new Map();
this.performanceHistory.forEach(metric => {
const size = metric.chunkSize;
if (!sizePerformanceMap.has(size)) {
sizePerformanceMap.set(size, []);
}
sizePerformanceMap.get(size).push(metric.accuracy);
});
let bestSize = 512;
let bestPerformance = 0;
for (const [size, performances] of sizePerformanceMap) {
const avgPerformance = performances.reduce((sum, p) => sum + p, 0) / performances.length;
if (avgPerformance > bestPerformance) {
bestPerformance = avgPerformance;
bestSize = size;
}
}
const currentSize = this.performanceHistory[this.performanceHistory.length - 1]?.chunkSize || 512;
const learningRate = this.config.learningRate;
const optimalSize = Math.round(currentSize + (bestSize - currentSize) * learningRate);
return Math.max(100, Math.min(2048, optimalSize));
}
calculateOptimalOverlap(chunkSize) {
const baseOverlap = Math.round(chunkSize * 0.15);
if (this.performanceHistory.length < 3)
return baseOverlap;
const recentMetrics = this.performanceHistory.slice(-10);
const avgAccuracy = recentMetrics.reduce((sum, m) => sum + m.accuracy, 0) / recentMetrics.length;
if (avgAccuracy < 0.6) {
return Math.round(chunkSize * 0.2);
}
if (avgAccuracy > 0.9) {
return Math.round(chunkSize * 0.1);
}
return baseOverlap;
}
calculateOptimalThreshold() {
if (this.performanceHistory.length < 3)
return 0.0;
const recentMetrics = this.performanceHistory.slice(-20);
const avgAccuracy = recentMetrics.reduce((sum, m) => sum + m.accuracy, 0) / recentMetrics.length;
if (avgAccuracy < 0.5) {
return Math.max(0.0, avgAccuracy - 0.2);
}
else if (avgAccuracy > 0.8) {
return Math.min(0.5, avgAccuracy - 0.3);
}
else {
return Math.max(0.0, avgAccuracy - 0.25);
}
}
calculateOptimalMaxResults() {
if (this.performanceHistory.length < 3)
return 10;
const recentMetrics = this.performanceHistory.slice(-20);
const avgSearchTime = recentMetrics.reduce((sum, m) => sum + m.searchTime, 0) / recentMetrics.length;
if (avgSearchTime < 50) {
return Math.min(50, 15 + Math.floor((100 - avgSearchTime) / 10));
}
else if (avgSearchTime > 200) {
return Math.max(5, 10 - Math.floor((avgSearchTime - 100) / 20));
}
else {
return 10;
}
}
calculateConfidence(metric) {
if (this.performanceHistory.length < 3)
return 0;
const values = this.performanceHistory.map(m => m[metric]);
const mean = values.reduce((sum, v) => sum + v, 0) / values.length;
const variance = values.reduce((sum, v) => sum + Math.pow(v - mean, 2), 0) / values.length;
const standardDeviation = Math.sqrt(variance);
const confidence = Math.max(0, Math.min(1, 1 - (standardDeviation / mean)));
return isNaN(confidence) ? 0 : confidence;
}
calculateOverallImprovement() {
if (this.performanceHistory.length < 10)
return 0;
const firstHalf = this.performanceHistory.slice(0, Math.floor(this.performanceHistory.length / 2));
const secondHalf = this.performanceHistory.slice(Math.floor(this.performanceHistory.length / 2));
const firstHalfAvg = firstHalf.reduce((sum, m) => sum + m.accuracy, 0) / firstHalf.length;
const secondHalfAvg = secondHalf.reduce((sum, m) => sum + m.accuracy, 0) / secondHalf.length;
return secondHalfAvg - firstHalfAvg;
}
calculatePerformanceTrend() {
if (this.performanceHistory.length < 10)
return 'stable';
const improvement = this.calculateOverallImprovement();
const threshold = 0.05;
if (improvement > threshold)
return 'improving';
if (improvement < -threshold)
return 'declining';
return 'stable';
}
getOptimizationHistory() {
return [{
timestamp: new Date(),
improvement: this.calculateOverallImprovement(),
changes: {
chunkSize: { from: 512, to: this.calculateOptimalChunkSize() },
threshold: { from: 0.0, to: this.calculateOptimalThreshold() }
}
}];
}
getOptimizationStats() {
const performanceImprovement = this.calculateOverallImprovement();
const confidenceLevel = this.calculateConfidence('accuracy');
const recommendations = [];
if (this.performanceHistory.length < 5) {
recommendations.push('Need more performance data for optimization');
}
else if (performanceImprovement < 0) {
recommendations.push('Performance declining - consider optimization');
}
else if (performanceImprovement > 0.1) {
recommendations.push('Performance improving - current settings are optimal');
}
else {
recommendations.push('Performance stable - minor optimizations possible');
}
if (this.optimizationCount >= this.config.maxOptimizationAttempts) {
recommendations.push('Maximum optimization attempts reached');
}
return {
totalOptimizations: this.optimizationCount,
lastOptimization: new Date(this.lastOptimization),
performanceImprovement,
confidenceLevel,
recommendations
};
}
}
exports.AdaptiveOptimizer = AdaptiveOptimizer;