@sparkleideas/plugins 3.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +401 -0
- package/__tests__/collection-manager.test.ts +332 -0
- package/__tests__/dependency-graph.test.ts +434 -0
- package/__tests__/enhanced-plugin-registry.test.ts +488 -0
- package/__tests__/plugin-registry.test.ts +368 -0
- package/__tests__/ruvector-bridge.test.ts +2429 -0
- package/__tests__/ruvector-integration.test.ts +1602 -0
- package/__tests__/ruvector-migrations.test.ts +1099 -0
- package/__tests__/ruvector-quantization.test.ts +846 -0
- package/__tests__/ruvector-streaming.test.ts +1088 -0
- package/__tests__/sdk.test.ts +325 -0
- package/__tests__/security.test.ts +348 -0
- package/__tests__/utils/ruvector-test-utils.ts +860 -0
- package/examples/plugin-creator/index.ts +636 -0
- package/examples/plugin-creator/plugin-creator.test.ts +312 -0
- package/examples/ruvector/README.md +288 -0
- package/examples/ruvector/attention-patterns.ts +394 -0
- package/examples/ruvector/basic-usage.ts +288 -0
- package/examples/ruvector/docker-compose.yml +75 -0
- package/examples/ruvector/gnn-analysis.ts +501 -0
- package/examples/ruvector/hyperbolic-hierarchies.ts +557 -0
- package/examples/ruvector/init-db.sql +119 -0
- package/examples/ruvector/quantization.ts +680 -0
- package/examples/ruvector/self-learning.ts +447 -0
- package/examples/ruvector/semantic-search.ts +576 -0
- package/examples/ruvector/streaming-large-data.ts +507 -0
- package/examples/ruvector/transactions.ts +594 -0
- package/examples/ruvector-plugins/hook-pattern-library.ts +486 -0
- package/examples/ruvector-plugins/index.ts +79 -0
- package/examples/ruvector-plugins/intent-router.ts +354 -0
- package/examples/ruvector-plugins/mcp-tool-optimizer.ts +424 -0
- package/examples/ruvector-plugins/reasoning-bank.ts +657 -0
- package/examples/ruvector-plugins/ruvector-plugins.test.ts +518 -0
- package/examples/ruvector-plugins/semantic-code-search.ts +498 -0
- package/examples/ruvector-plugins/shared/index.ts +20 -0
- package/examples/ruvector-plugins/shared/vector-utils.ts +257 -0
- package/examples/ruvector-plugins/sona-learning.ts +445 -0
- package/package.json +97 -0
- package/src/collections/collection-manager.ts +661 -0
- package/src/collections/index.ts +56 -0
- package/src/collections/official/index.ts +1040 -0
- package/src/core/base-plugin.ts +416 -0
- package/src/core/plugin-interface.ts +215 -0
- package/src/hooks/index.ts +685 -0
- package/src/index.ts +378 -0
- package/src/integrations/agentic-flow.ts +743 -0
- package/src/integrations/index.ts +88 -0
- package/src/integrations/ruvector/ARCHITECTURE.md +1245 -0
- package/src/integrations/ruvector/attention-advanced.ts +1040 -0
- package/src/integrations/ruvector/attention-executor.ts +782 -0
- package/src/integrations/ruvector/attention-mechanisms.ts +757 -0
- package/src/integrations/ruvector/attention.ts +1063 -0
- package/src/integrations/ruvector/gnn.ts +3050 -0
- package/src/integrations/ruvector/hyperbolic.ts +1948 -0
- package/src/integrations/ruvector/index.ts +394 -0
- package/src/integrations/ruvector/migrations/001_create_extension.sql +135 -0
- package/src/integrations/ruvector/migrations/002_create_vector_tables.sql +259 -0
- package/src/integrations/ruvector/migrations/003_create_indices.sql +328 -0
- package/src/integrations/ruvector/migrations/004_create_functions.sql +598 -0
- package/src/integrations/ruvector/migrations/005_create_attention_functions.sql +654 -0
- package/src/integrations/ruvector/migrations/006_create_gnn_functions.sql +728 -0
- package/src/integrations/ruvector/migrations/007_create_hyperbolic_functions.sql +762 -0
- package/src/integrations/ruvector/migrations/index.ts +35 -0
- package/src/integrations/ruvector/migrations/migrations.ts +647 -0
- package/src/integrations/ruvector/quantization.ts +2036 -0
- package/src/integrations/ruvector/ruvector-bridge.ts +2000 -0
- package/src/integrations/ruvector/self-learning.ts +2376 -0
- package/src/integrations/ruvector/streaming.ts +1737 -0
- package/src/integrations/ruvector/types.ts +1945 -0
- package/src/providers/index.ts +643 -0
- package/src/registry/dependency-graph.ts +568 -0
- package/src/registry/enhanced-plugin-registry.ts +994 -0
- package/src/registry/plugin-registry.ts +604 -0
- package/src/sdk/index.ts +563 -0
- package/src/security/index.ts +594 -0
- package/src/types/index.ts +446 -0
- package/src/workers/index.ts +700 -0
- package/tmp.json +0 -0
- package/tsconfig.json +25 -0
- package/vitest.config.ts +23 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RuVector PostgreSQL Bridge - Self-Learning Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates:
|
|
5
|
+
* - Enabling the self-optimization learning loop
|
|
6
|
+
* - Monitoring query patterns and performance
|
|
7
|
+
* - Auto-tuning HNSW index parameters
|
|
8
|
+
* - Pattern recognition and anomaly detection
|
|
9
|
+
*
|
|
10
|
+
* Run with: npx ts-node examples/ruvector/self-learning.ts
|
|
11
|
+
*
|
|
12
|
+
* @module @sparkleideas/plugins/examples/ruvector/self-learning
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
createRuVectorBridge,
|
|
17
|
+
type RuVectorBridge,
|
|
18
|
+
} from '../../src/integrations/ruvector/index.js';
|
|
19
|
+
|
|
20
|
+
import {
|
|
21
|
+
createSelfLearningSystem,
|
|
22
|
+
LearningLoop,
|
|
23
|
+
QueryOptimizer,
|
|
24
|
+
IndexTuner,
|
|
25
|
+
PatternRecognizer,
|
|
26
|
+
DEFAULT_LEARNING_CONFIG,
|
|
27
|
+
HIGH_ACCURACY_LEARNING_CONFIG,
|
|
28
|
+
type LearningConfig,
|
|
29
|
+
type QueryHistory,
|
|
30
|
+
type Pattern,
|
|
31
|
+
type WorkloadAnalysis,
|
|
32
|
+
} from '../../src/integrations/ruvector/self-learning.js';
|
|
33
|
+
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// Configuration
|
|
36
|
+
// ============================================================================
|
|
37
|
+
|
|
38
|
+
const config = {
|
|
39
|
+
connection: {
|
|
40
|
+
host: process.env.POSTGRES_HOST || 'localhost',
|
|
41
|
+
port: parseInt(process.env.POSTGRES_PORT || '5432', 10),
|
|
42
|
+
database: process.env.POSTGRES_DB || 'vectors',
|
|
43
|
+
user: process.env.POSTGRES_USER || 'postgres',
|
|
44
|
+
password: process.env.POSTGRES_PASSWORD || 'postgres',
|
|
45
|
+
},
|
|
46
|
+
dimensions: 384,
|
|
47
|
+
learningEnabled: true,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// Simulated Query Workload
|
|
52
|
+
// ============================================================================
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Simulated queries representing a realistic workload.
|
|
56
|
+
*/
|
|
57
|
+
const workloadQueries = [
|
|
58
|
+
// Vector similarity searches (frequent)
|
|
59
|
+
"SELECT id, embedding <-> $1 as distance FROM documents ORDER BY distance LIMIT 10",
|
|
60
|
+
"SELECT id, embedding <=> $1 as distance FROM documents WHERE category = 'tech' ORDER BY distance LIMIT 5",
|
|
61
|
+
"SELECT id, metadata FROM documents WHERE embedding <-> $1 < 0.5 LIMIT 20",
|
|
62
|
+
|
|
63
|
+
// Analytical queries
|
|
64
|
+
"SELECT category, COUNT(*) FROM documents GROUP BY category",
|
|
65
|
+
"SELECT DATE(created_at), COUNT(*) FROM documents GROUP BY DATE(created_at)",
|
|
66
|
+
|
|
67
|
+
// CRUD operations
|
|
68
|
+
"INSERT INTO documents (id, embedding, metadata) VALUES ($1, $2, $3)",
|
|
69
|
+
"UPDATE documents SET metadata = $1 WHERE id = $2",
|
|
70
|
+
"DELETE FROM documents WHERE created_at < $1",
|
|
71
|
+
|
|
72
|
+
// Complex joins
|
|
73
|
+
"SELECT d.id, d.metadata, c.name FROM documents d JOIN categories c ON d.category_id = c.id WHERE d.embedding <-> $1 < 0.3",
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Generate realistic query history.
|
|
78
|
+
*/
|
|
79
|
+
function generateQueryHistory(queries: string[], count: number): QueryHistory[] {
|
|
80
|
+
const history: QueryHistory[] = [];
|
|
81
|
+
const now = Date.now();
|
|
82
|
+
|
|
83
|
+
for (let i = 0; i < count; i++) {
|
|
84
|
+
const query = queries[Math.floor(Math.random() * queries.length)];
|
|
85
|
+
const isVectorSearch = query.includes('<->') || query.includes('<=>');
|
|
86
|
+
|
|
87
|
+
// Simulate realistic durations
|
|
88
|
+
let baseDuration = isVectorSearch ? 50 : 10;
|
|
89
|
+
if (query.includes('GROUP BY')) baseDuration = 100;
|
|
90
|
+
if (query.includes('JOIN')) baseDuration = 150;
|
|
91
|
+
|
|
92
|
+
// Add some variance
|
|
93
|
+
const duration = baseDuration * (0.5 + Math.random());
|
|
94
|
+
|
|
95
|
+
// Simulate periodic pattern (business hours)
|
|
96
|
+
const hour = Math.floor((i / count) * 24);
|
|
97
|
+
const isPeakHour = hour >= 9 && hour <= 17;
|
|
98
|
+
const timestamp = new Date(now - (count - i) * 60000 + (isPeakHour ? 0 : Math.random() * 300000));
|
|
99
|
+
|
|
100
|
+
history.push({
|
|
101
|
+
fingerprint: `qf_${Math.abs(hashCode(query)).toString(16)}`,
|
|
102
|
+
sql: query,
|
|
103
|
+
timestamp,
|
|
104
|
+
durationMs: duration,
|
|
105
|
+
rowCount: Math.floor(Math.random() * 100) + 1,
|
|
106
|
+
success: Math.random() > 0.02, // 2% error rate
|
|
107
|
+
sessionId: `session_${i % 10}`,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return history;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Simple hash function for query fingerprinting.
|
|
116
|
+
*/
|
|
117
|
+
function hashCode(str: string): number {
|
|
118
|
+
let hash = 0;
|
|
119
|
+
for (let i = 0; i < str.length; i++) {
|
|
120
|
+
const char = str.charCodeAt(i);
|
|
121
|
+
hash = ((hash << 5) - hash) + char;
|
|
122
|
+
hash = hash & hash;
|
|
123
|
+
}
|
|
124
|
+
return hash;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Print workload analysis summary.
|
|
129
|
+
*/
|
|
130
|
+
function printWorkloadAnalysis(analysis: WorkloadAnalysis): void {
|
|
131
|
+
console.log('\n Workload Analysis Summary');
|
|
132
|
+
console.log(' ' + '-'.repeat(50));
|
|
133
|
+
console.log(` Total queries analyzed: ${analysis.totalQueries}`);
|
|
134
|
+
console.log(` Analysis duration: ${analysis.durationMs.toFixed(2)}ms`);
|
|
135
|
+
|
|
136
|
+
console.log('\n Query type distribution:');
|
|
137
|
+
analysis.queryDistribution.forEach((count, type) => {
|
|
138
|
+
const pct = ((count / analysis.totalQueries) * 100).toFixed(1);
|
|
139
|
+
console.log(` ${type}: ${count} (${pct}%)`);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
console.log('\n Workload characteristics:');
|
|
143
|
+
console.log(` Read/Write ratio: ${analysis.characteristics.readWriteRatio.toFixed(2)}`);
|
|
144
|
+
console.log(` Vector search %: ${analysis.characteristics.vectorSearchPercentage.toFixed(1)}%`);
|
|
145
|
+
console.log(` Avg complexity: ${analysis.characteristics.avgComplexity.toFixed(3)}`);
|
|
146
|
+
console.log(` Type: ${analysis.characteristics.isOLTP ? 'OLTP' : analysis.characteristics.isOLAP ? 'OLAP' : 'Hybrid'}`);
|
|
147
|
+
|
|
148
|
+
console.log('\n Top query patterns:');
|
|
149
|
+
analysis.topPatterns.slice(0, 5).forEach((pattern, i) => {
|
|
150
|
+
console.log(` ${i + 1}. Frequency: ${pattern.frequency}, Avg: ${pattern.avgDurationMs.toFixed(2)}ms`);
|
|
151
|
+
console.log(` ${pattern.example.slice(0, 60)}...`);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
console.log('\n Hot tables:');
|
|
155
|
+
analysis.hotTables.slice(0, 3).forEach(table => {
|
|
156
|
+
console.log(` ${table.tableName}: reads=${table.reads}, writes=${table.writes}, vector=${table.vectorSearches}`);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
console.log('\n Recommendations:');
|
|
160
|
+
analysis.recommendations.forEach(rec => {
|
|
161
|
+
console.log(` [P${rec.priority}] ${rec.description}`);
|
|
162
|
+
console.log(` Impact: ${rec.estimatedImpact}`);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ============================================================================
|
|
167
|
+
// Main Example
|
|
168
|
+
// ============================================================================
|
|
169
|
+
|
|
170
|
+
async function main(): Promise<void> {
|
|
171
|
+
console.log('RuVector PostgreSQL Bridge - Self-Learning Example');
|
|
172
|
+
console.log('====================================================\n');
|
|
173
|
+
|
|
174
|
+
const bridge: RuVectorBridge = createRuVectorBridge({
|
|
175
|
+
connectionString: `postgresql://${config.connection.user}:${config.connection.password}@${config.connection.host}:${config.connection.port}/${config.connection.database}`,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Create self-learning system with custom configuration
|
|
179
|
+
const learningConfig: Partial<LearningConfig> = {
|
|
180
|
+
enableMicroLearning: true,
|
|
181
|
+
microLearningThresholdMs: 0.1,
|
|
182
|
+
enableBackgroundLearning: true,
|
|
183
|
+
backgroundLearningIntervalMs: 5000, // 5 seconds for demo
|
|
184
|
+
enableEWC: true,
|
|
185
|
+
ewcLambda: 0.5,
|
|
186
|
+
maxPatterns: 1000,
|
|
187
|
+
patternExpiryMs: 3600000, // 1 hour
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const { learningLoop, queryOptimizer, indexTuner, patternRecognizer } =
|
|
191
|
+
createSelfLearningSystem(learningConfig);
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
await bridge.connect();
|
|
195
|
+
console.log('Connected to PostgreSQL');
|
|
196
|
+
|
|
197
|
+
// ========================================================================
|
|
198
|
+
// 1. Enable Learning Loop
|
|
199
|
+
// ========================================================================
|
|
200
|
+
console.log('\n1. Starting Self-Learning Loop');
|
|
201
|
+
console.log(' ' + '-'.repeat(50));
|
|
202
|
+
|
|
203
|
+
learningLoop.start();
|
|
204
|
+
console.log(' Learning loop started');
|
|
205
|
+
console.log(` Configuration:`);
|
|
206
|
+
console.log(` - Micro-learning: ${learningConfig.enableMicroLearning ? 'enabled' : 'disabled'}`);
|
|
207
|
+
console.log(` - Background learning interval: ${learningConfig.backgroundLearningIntervalMs}ms`);
|
|
208
|
+
console.log(` - EWC protection: ${learningConfig.enableEWC ? 'enabled' : 'disabled'}`);
|
|
209
|
+
console.log(` - Max patterns: ${learningConfig.maxPatterns}`);
|
|
210
|
+
|
|
211
|
+
// ========================================================================
|
|
212
|
+
// 2. Simulate Query Workload
|
|
213
|
+
// ========================================================================
|
|
214
|
+
console.log('\n2. Simulating Query Workload');
|
|
215
|
+
console.log(' ' + '-'.repeat(50));
|
|
216
|
+
|
|
217
|
+
const queryHistory = generateQueryHistory(workloadQueries, 500);
|
|
218
|
+
console.log(` Generated ${queryHistory.length} simulated queries`);
|
|
219
|
+
|
|
220
|
+
// Feed queries to the learning system
|
|
221
|
+
console.log(' Processing queries through micro-learning...');
|
|
222
|
+
const startProcess = performance.now();
|
|
223
|
+
|
|
224
|
+
for (const history of queryHistory) {
|
|
225
|
+
// Micro-learning: process each query
|
|
226
|
+
learningLoop.microLearn(history.sql, history.durationMs, history.rowCount);
|
|
227
|
+
|
|
228
|
+
// Record in index tuner
|
|
229
|
+
indexTuner.recordQuery(history);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const processTime = performance.now() - startProcess;
|
|
233
|
+
console.log(` Processed ${queryHistory.length} queries in ${processTime.toFixed(2)}ms`);
|
|
234
|
+
console.log(` Throughput: ${(queryHistory.length / (processTime / 1000)).toFixed(0)} queries/second`);
|
|
235
|
+
|
|
236
|
+
// ========================================================================
|
|
237
|
+
// 3. Analyze Workload Patterns
|
|
238
|
+
// ========================================================================
|
|
239
|
+
console.log('\n3. Analyzing Workload Patterns');
|
|
240
|
+
console.log(' ' + '-'.repeat(50));
|
|
241
|
+
|
|
242
|
+
const workloadAnalysis = indexTuner.analyzeWorkload();
|
|
243
|
+
printWorkloadAnalysis(workloadAnalysis);
|
|
244
|
+
|
|
245
|
+
// ========================================================================
|
|
246
|
+
// 4. Query Optimization Suggestions
|
|
247
|
+
// ========================================================================
|
|
248
|
+
console.log('\n4. Query Optimization Suggestions');
|
|
249
|
+
console.log(' ' + '-'.repeat(50));
|
|
250
|
+
|
|
251
|
+
// Analyze a slow query
|
|
252
|
+
const slowQuery = "SELECT * FROM documents WHERE embedding <-> $1 < 0.5";
|
|
253
|
+
console.log(`\n Analyzing: "${slowQuery}"`);
|
|
254
|
+
|
|
255
|
+
const analysis = queryOptimizer.analyzeQuery(slowQuery);
|
|
256
|
+
console.log(`\n Analysis results:`);
|
|
257
|
+
console.log(` Query type: ${analysis.queryType}`);
|
|
258
|
+
console.log(` Complexity: ${(analysis.complexity * 100).toFixed(1)}%`);
|
|
259
|
+
console.log(` Parse time: ${analysis.parseTimeMs.toFixed(3)}ms`);
|
|
260
|
+
|
|
261
|
+
console.log('\n Vector operations:');
|
|
262
|
+
analysis.vectorOperations.forEach(op => {
|
|
263
|
+
console.log(` - ${op.type} on ${op.table}.${op.column} (metric: ${op.metric})`);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
console.log('\n Bottlenecks:');
|
|
267
|
+
analysis.bottlenecks.forEach(b => {
|
|
268
|
+
console.log(` - [${b.type}] ${b.description} (severity: ${b.severity})`);
|
|
269
|
+
console.log(` Suggestion: ${b.suggestion}`);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
const optimizations = queryOptimizer.suggestOptimizations(analysis);
|
|
273
|
+
console.log('\n Suggested optimizations:');
|
|
274
|
+
optimizations.forEach(opt => {
|
|
275
|
+
console.log(` - [${opt.type}] ${opt.description}`);
|
|
276
|
+
console.log(` Expected improvement: ${opt.expectedImprovement}%`);
|
|
277
|
+
console.log(` Confidence: ${(opt.confidence * 100).toFixed(0)}%, Risk: ${opt.risk}`);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// ========================================================================
|
|
281
|
+
// 5. Auto-Tune HNSW Parameters
|
|
282
|
+
// ========================================================================
|
|
283
|
+
console.log('\n5. Auto-Tuning HNSW Index Parameters');
|
|
284
|
+
console.log(' ' + '-'.repeat(50));
|
|
285
|
+
|
|
286
|
+
const hnswParams = indexTuner.tuneHNSW('documents');
|
|
287
|
+
console.log(' Recommended HNSW parameters for "documents" table:');
|
|
288
|
+
console.log(` M: ${hnswParams.m}`);
|
|
289
|
+
console.log(` ef_construction: ${hnswParams.efConstruction}`);
|
|
290
|
+
console.log(` ef_search: ${hnswParams.efSearch}`);
|
|
291
|
+
console.log(` Optimized for: ${hnswParams.optimizedFor}`);
|
|
292
|
+
console.log(` Confidence: ${(hnswParams.confidence * 100).toFixed(1)}%`);
|
|
293
|
+
console.log(` Estimated recall: ${(hnswParams.estimatedRecall * 100).toFixed(1)}%`);
|
|
294
|
+
console.log(` Estimated QPS: ${hnswParams.estimatedQps}`);
|
|
295
|
+
|
|
296
|
+
// Get index suggestions
|
|
297
|
+
const indexSuggestions = indexTuner.suggestIndexes();
|
|
298
|
+
console.log('\n Index suggestions:');
|
|
299
|
+
indexSuggestions.slice(0, 3).forEach(suggestion => {
|
|
300
|
+
console.log(` - ${suggestion.tableName}.${suggestion.columnName}`);
|
|
301
|
+
console.log(` Type: ${suggestion.indexType}, Metric: ${suggestion.metric}`);
|
|
302
|
+
console.log(` Confidence: ${(suggestion.confidence * 100).toFixed(1)}%`);
|
|
303
|
+
console.log(` SQL: ${suggestion.createSql}`);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// ========================================================================
|
|
307
|
+
// 6. Pattern Recognition
|
|
308
|
+
// ========================================================================
|
|
309
|
+
console.log('\n6. Pattern Recognition');
|
|
310
|
+
console.log(' ' + '-'.repeat(50));
|
|
311
|
+
|
|
312
|
+
// Learn patterns from history
|
|
313
|
+
patternRecognizer.learnFromHistory(queryHistory);
|
|
314
|
+
|
|
315
|
+
const patterns = patternRecognizer.detectPatterns();
|
|
316
|
+
console.log(` Detected ${patterns.length} patterns`);
|
|
317
|
+
|
|
318
|
+
console.log('\n Top patterns by occurrence:');
|
|
319
|
+
patterns.slice(0, 5).forEach((pattern, i) => {
|
|
320
|
+
console.log(` ${i + 1}. ${pattern.type} (${pattern.occurrences} occurrences)`);
|
|
321
|
+
console.log(` Confidence: ${(pattern.confidence * 100).toFixed(1)}%`);
|
|
322
|
+
if (pattern.temporal) {
|
|
323
|
+
console.log(` Periodic: ${pattern.temporal.isPeriodic}`);
|
|
324
|
+
console.log(` Peak hours: ${pattern.temporal.peakHours.join(', ')}`);
|
|
325
|
+
}
|
|
326
|
+
console.log(` Performance trend: ${pattern.performance.responseTrend}`);
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
// ========================================================================
|
|
330
|
+
// 7. Anomaly Detection
|
|
331
|
+
// ========================================================================
|
|
332
|
+
console.log('\n7. Anomaly Detection');
|
|
333
|
+
console.log(' ' + '-'.repeat(50));
|
|
334
|
+
|
|
335
|
+
// Simulate some anomalous queries
|
|
336
|
+
const anomalousQueries = [
|
|
337
|
+
"SELECT * FROM documents", // No limit - potential full scan
|
|
338
|
+
"SELECT * FROM documents d1, documents d2", // Cartesian product
|
|
339
|
+
];
|
|
340
|
+
|
|
341
|
+
const anomalies = patternRecognizer.detectAnomalies(anomalousQueries);
|
|
342
|
+
|
|
343
|
+
if (anomalies.length > 0) {
|
|
344
|
+
console.log(` Detected ${anomalies.length} anomalies:`);
|
|
345
|
+
anomalies.forEach((anomaly, i) => {
|
|
346
|
+
console.log(`\n ${i + 1}. ${anomaly.type}`);
|
|
347
|
+
console.log(` Query: ${anomaly.query.slice(0, 50)}...`);
|
|
348
|
+
console.log(` Severity: ${anomaly.severity}/10`);
|
|
349
|
+
console.log(` Description: ${anomaly.description}`);
|
|
350
|
+
console.log(` Possible causes:`);
|
|
351
|
+
anomaly.possibleCauses.forEach(cause => console.log(` - ${cause}`));
|
|
352
|
+
console.log(` Recommendations:`);
|
|
353
|
+
anomaly.recommendations.forEach(rec => console.log(` - ${rec}`));
|
|
354
|
+
});
|
|
355
|
+
} else {
|
|
356
|
+
console.log(' No anomalies detected in the analyzed queries');
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// ========================================================================
|
|
360
|
+
// 8. Learning Statistics
|
|
361
|
+
// ========================================================================
|
|
362
|
+
console.log('\n8. Learning Statistics');
|
|
363
|
+
console.log(' ' + '-'.repeat(50));
|
|
364
|
+
|
|
365
|
+
const stats = learningLoop.getStats();
|
|
366
|
+
console.log(' Current learning state:');
|
|
367
|
+
console.log(` Total patterns: ${stats.totalPatterns}`);
|
|
368
|
+
console.log(` Active patterns: ${stats.activePatterns}`);
|
|
369
|
+
console.log(` Micro-learning events: ${stats.microLearningEvents}`);
|
|
370
|
+
console.log(` Background learning cycles: ${stats.backgroundLearningCycles}`);
|
|
371
|
+
console.log(` EWC consolidations: ${stats.ewcConsolidations}`);
|
|
372
|
+
console.log(` Avg learning time: ${stats.avgLearningTimeMs.toFixed(3)}ms`);
|
|
373
|
+
console.log(` Memory usage: ${(stats.memoryUsageBytes / 1024).toFixed(2)} KB`);
|
|
374
|
+
console.log(` Last learning: ${stats.lastLearningTimestamp.toISOString()}`);
|
|
375
|
+
|
|
376
|
+
// EWC state
|
|
377
|
+
const ewcState = learningLoop.getEWCState();
|
|
378
|
+
console.log('\n EWC++ Protection State:');
|
|
379
|
+
console.log(` Protected patterns: ${ewcState.protectedPatterns.size}`);
|
|
380
|
+
console.log(` Consolidation count: ${ewcState.consolidationCount}`);
|
|
381
|
+
console.log(` Fisher matrix entries: ${ewcState.fisherDiagonal.size}`);
|
|
382
|
+
|
|
383
|
+
// ========================================================================
|
|
384
|
+
// 9. Query Statistics
|
|
385
|
+
// ========================================================================
|
|
386
|
+
console.log('\n9. Query Statistics');
|
|
387
|
+
console.log(' ' + '-'.repeat(50));
|
|
388
|
+
|
|
389
|
+
const queryStats = queryOptimizer.getQueryStats() as Array<{
|
|
390
|
+
fingerprint: string;
|
|
391
|
+
sql: string;
|
|
392
|
+
executionCount: number;
|
|
393
|
+
avgDurationMs: number;
|
|
394
|
+
p95DurationMs: number;
|
|
395
|
+
}>;
|
|
396
|
+
|
|
397
|
+
if (Array.isArray(queryStats) && queryStats.length > 0) {
|
|
398
|
+
console.log(` Tracked ${queryStats.length} unique query patterns`);
|
|
399
|
+
|
|
400
|
+
// Sort by execution count
|
|
401
|
+
const topQueries = queryStats
|
|
402
|
+
.sort((a, b) => b.executionCount - a.executionCount)
|
|
403
|
+
.slice(0, 5);
|
|
404
|
+
|
|
405
|
+
console.log('\n Top queries by frequency:');
|
|
406
|
+
topQueries.forEach((stat, i) => {
|
|
407
|
+
console.log(` ${i + 1}. ${stat.sql.slice(0, 50)}...`);
|
|
408
|
+
console.log(` Executions: ${stat.executionCount}`);
|
|
409
|
+
console.log(` Avg duration: ${stat.avgDurationMs.toFixed(2)}ms`);
|
|
410
|
+
console.log(` P95 duration: ${stat.p95DurationMs.toFixed(2)}ms`);
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// ========================================================================
|
|
415
|
+
// 10. Stop Learning Loop
|
|
416
|
+
// ========================================================================
|
|
417
|
+
console.log('\n10. Stopping Learning Loop');
|
|
418
|
+
console.log(' ' + '-'.repeat(50));
|
|
419
|
+
|
|
420
|
+
learningLoop.stop();
|
|
421
|
+
console.log(' Learning loop stopped');
|
|
422
|
+
console.log(` Final stats:`);
|
|
423
|
+
console.log(` - Total patterns learned: ${learningLoop.getStats().totalPatterns}`);
|
|
424
|
+
console.log(` - Total micro-learning events: ${learningLoop.getStats().microLearningEvents}`);
|
|
425
|
+
|
|
426
|
+
// ========================================================================
|
|
427
|
+
// Done
|
|
428
|
+
// ========================================================================
|
|
429
|
+
console.log('\n' + '='.repeat(55));
|
|
430
|
+
console.log('Self-learning example completed!');
|
|
431
|
+
console.log('='.repeat(55));
|
|
432
|
+
|
|
433
|
+
} catch (error) {
|
|
434
|
+
console.error('Error:', error);
|
|
435
|
+
throw error;
|
|
436
|
+
} finally {
|
|
437
|
+
// Ensure learning loop is stopped
|
|
438
|
+
if (learningLoop.isActive()) {
|
|
439
|
+
learningLoop.stop();
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
await bridge.disconnect();
|
|
443
|
+
console.log('\nDisconnected from PostgreSQL.');
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
main().catch(console.error);
|