import * as crypto from 'crypto';
export class ReasoningCache {
cache = new Map();
patternCache = new Map();
metrics;
precomputedPatterns = [];
maxCacheSize = 10000;
defaultTTL = 3600000; warmupEnabled = true;
constructor(options = {}) {
this.maxCacheSize = options.maxSize || 10000;
this.defaultTTL = options.defaultTTL || 3600000;
this.warmupEnabled = options.enableWarmup ?? true;
this.metrics = {
hits: 0,
misses: 0,
totalQueries: 0,
avgComputeTime: 0,
cacheSize: 0,
hitRatio: 0,
overhead: 0
};
if (this.warmupEnabled) {
this.initializeCommonPatterns();
this.warmupCache();
}
}
get(query, context = {}, depth = 5) {
const key = this.generateCacheKey(query, context, depth);
const startTime = performance.now();
this.metrics.totalQueries++;
const entry = this.cache.get(key);
if (entry && this.isValidEntry(entry)) {
entry.hitCount++;
this.metrics.hits++;
this.updateMetrics(performance.now() - startTime, true);
return entry;
}
const patternMatch = this.findPatternMatch(query);
if (patternMatch) {
this.metrics.hits++;
this.updateMetrics(performance.now() - startTime, true);
return this.adaptPatternResult(patternMatch, query, context);
}
this.metrics.misses++;
this.updateMetrics(performance.now() - startTime, false);
return null;
}
set(query, context, depth, result, computeTime) {
const key = this.generateCacheKey(query, context, depth);
const patterns = this.extractPatterns(query);
const confidence = result.confidence || 0.5;
const ttl = this.calculateTTL(confidence, patterns.length, computeTime);
const entry = {
result,
timestamp: Date.now(),
hitCount: 0,
computeTime,
patterns,
confidence,
ttl
};
if (this.cache.size >= this.maxCacheSize) {
this.evictLeastUseful();
}
this.cache.set(key, entry);
this.metrics.cacheSize = this.cache.size;
this.updatePatternFrequency(patterns);
}
initializeCommonPatterns() {
this.precomputedPatterns = [
{
pattern: 'api_security',
variations: [
'api security vulnerabilities',
'rest api security issues',
'api authentication problems',
'api rate limiting issues'
],
baseResult: null,
priority: 10,
frequency: 0
},
{
pattern: 'jwt_vulnerabilities',
variations: [
'jwt security issues',
'jwt token vulnerabilities',
'jwt signature validation',
'jwt cache problems'
],
baseResult: null,
priority: 9,
frequency: 0
},
{
pattern: 'distributed_systems',
variations: [
'microservices issues',
'distributed system problems',
'service mesh complications',
'distributed consensus'
],
baseResult: null,
priority: 8,
frequency: 0
},
{
pattern: 'cache_issues',
variations: [
'cache invalidation problems',
'redis cache issues',
'cache collision attacks',
'cdn cache poisoning'
],
baseResult: null,
priority: 7,
frequency: 0
},
{
pattern: 'edge_cases',
variations: [
'hidden complexities',
'edge case analysis',
'unexpected behaviors',
'corner cases'
],
baseResult: null,
priority: 6,
frequency: 0
}
];
}
warmupCache() {
setTimeout(async () => {
for (const pattern of this.precomputedPatterns) {
if (pattern.priority >= 8) { for (const variation of pattern.variations.slice(0, 2)) { const mockResult = this.generateMockResult(pattern.pattern, variation);
const key = this.generateCacheKey(variation, {}, 5);
const entry = {
result: mockResult,
timestamp: Date.now(),
hitCount: 0,
computeTime: 50, patterns: [pattern.pattern],
confidence: 0.8,
ttl: this.defaultTTL * 2 };
this.cache.set(key, entry);
}
}
}
this.metrics.cacheSize = this.cache.size;
}, 100); }
generateCacheKey(query, context, depth) {
const normalized = query.toLowerCase().trim().replace(/\s+/g, ' ');
const contextStr = JSON.stringify(context);
const content = `${normalized}|${contextStr}|${depth}`;
return crypto.createHash('sha256').update(content).digest('hex').substring(0, 16);
}
isValidEntry(entry) {
const age = Date.now() - entry.timestamp;
return age < entry.ttl;
}
findPatternMatch(query) {
const queryPatterns = this.extractPatterns(query);
for (const [key, entry] of this.cache.entries()) {
if (this.isValidEntry(entry)) {
const overlap = this.calculatePatternOverlap(queryPatterns, entry.patterns);
if (overlap > 0.7) { return entry;
}
}
}
return null;
}
extractPatterns(query) {
const patterns = [];
const lowerQuery = query.toLowerCase();
if (lowerQuery.includes('api') || lowerQuery.includes('rest'))
patterns.push('api_security');
if (lowerQuery.includes('jwt') || lowerQuery.includes('token'))
patterns.push('jwt_vulnerabilities');
if (lowerQuery.includes('distributed') || lowerQuery.includes('microservice'))
patterns.push('distributed_systems');
if (lowerQuery.includes('cache') || lowerQuery.includes('redis'))
patterns.push('cache_issues');
if (lowerQuery.includes('edge') || lowerQuery.includes('hidden'))
patterns.push('edge_cases');
if (lowerQuery.includes('security') || lowerQuery.includes('vulnerab'))
patterns.push('security_analysis');
if (lowerQuery.includes('performance') || lowerQuery.includes('optimiz'))
patterns.push('performance_issues');
return patterns.length > 0 ? patterns : ['general_reasoning'];
}
calculatePatternOverlap(patterns1, patterns2) {
if (patterns1.length === 0 || patterns2.length === 0)
return 0;
const intersection = patterns1.filter(p => patterns2.includes(p));
const union = [...new Set([...patterns1, ...patterns2])];
return intersection.length / union.length; }
adaptPatternResult(entry, query, context) {
const adaptedResult = {
...entry.result,
query: query, adapted: true,
originalConfidence: entry.result.confidence,
confidence: entry.result.confidence * 0.95, reasoning: [
...entry.result.reasoning,
{
type: 'pattern_adaptation',
description: 'Result adapted from cached pattern',
confidence: 0.9
}
]
};
return {
...entry,
result: adaptedResult,
hitCount: entry.hitCount + 1
};
}
calculateTTL(confidence, patternCount, computeTime) {
const confidenceFactor = confidence; const complexityFactor = Math.min(patternCount / 5, 1); const computeFactor = Math.min(computeTime / 1000, 1); const multiplier = (confidenceFactor + complexityFactor + computeFactor) / 3;
return Math.floor(this.defaultTTL * (0.5 + multiplier * 1.5)); }
evictLeastUseful() {
let leastUseful = null;
let minScore = Infinity;
for (const [key, entry] of this.cache.entries()) {
const age = Date.now() - entry.timestamp;
const ageScore = age / entry.ttl; const hitScore = 1 / (entry.hitCount + 1); const confidenceScore = 1 - entry.confidence; const totalScore = ageScore + hitScore + confidenceScore;
if (totalScore < minScore) {
minScore = totalScore;
leastUseful = key;
}
}
if (leastUseful) {
this.cache.delete(leastUseful);
}
}
updatePatternFrequency(patterns) {
for (const pattern of patterns) {
const existing = this.precomputedPatterns.find(p => p.pattern === pattern);
if (existing) {
existing.frequency++;
}
}
}
generateMockResult(pattern, query) {
return {
query,
answer: `Pre-computed analysis for ${pattern} patterns.`,
confidence: 0.8,
reasoning: [
{
type: 'pre_computed',
description: `Pre-computed result for ${pattern}`,
confidence: 0.8
}
],
insights: [`Cached insight for ${pattern}`],
patterns: [pattern],
cached: true,
precomputed: true
};
}
updateMetrics(queryTime, hit) {
this.metrics.hitRatio = this.metrics.hits / this.metrics.totalQueries;
this.metrics.avgComputeTime = (this.metrics.avgComputeTime + queryTime) / 2;
this.metrics.overhead = queryTime; }
getMetrics() {
return {
...this.metrics,
cacheSize: this.cache.size
};
}
clear() {
this.cache.clear();
this.patternCache.clear();
this.metrics = {
hits: 0,
misses: 0,
totalQueries: 0,
avgComputeTime: 0,
cacheSize: 0,
hitRatio: 0,
overhead: 0
};
}
getStatus() {
return {
size: this.cache.size,
maxSize: this.maxCacheSize,
metrics: this.getMetrics(),
patterns: this.precomputedPatterns.map(p => ({
pattern: p.pattern,
frequency: p.frequency,
priority: p.priority
}))
};
}
}