177 lines
6.2 KiB
JavaScript
177 lines
6.2 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* Test ReasoningBank retrieval algorithm with MMR
|
||
*/
|
||
import { upsertMemory, upsertEmbedding, fetchMemoryCandidates } from './db/queries.js';
|
||
import { loadConfig } from './utils/config.js';
|
||
import { ulid } from 'ulid';
|
||
console.log('🧪 Testing ReasoningBank Retrieval Algorithm\n');
|
||
// Helper to create synthetic embedding
|
||
function createEmbedding(seed, dims = 1024) {
|
||
const vec = new Float32Array(dims);
|
||
for (let i = 0; i < dims; i++) {
|
||
vec[i] = Math.sin(seed * (i + 1) * 0.01) * 0.1 + Math.cos(seed * i * 0.02) * 0.05;
|
||
}
|
||
// Normalize
|
||
let mag = 0;
|
||
for (let i = 0; i < dims; i++)
|
||
mag += vec[i] * vec[i];
|
||
mag = Math.sqrt(mag);
|
||
for (let i = 0; i < dims; i++)
|
||
vec[i] /= mag;
|
||
return vec;
|
||
}
|
||
// Insert test memories
|
||
console.log('1️⃣ Inserting test memories...');
|
||
const testMemories = [
|
||
{
|
||
title: 'CSRF Token Handling',
|
||
description: 'Extract and include CSRF tokens in form submissions',
|
||
content: '1) Check for CSRF token in meta tags or form inputs. 2) Include in request. 3) Verify before submit.',
|
||
tags: ['csrf', 'web', 'security'],
|
||
domain: 'test.web',
|
||
confidence: 0.88,
|
||
seed: 42
|
||
},
|
||
{
|
||
title: 'Authentication Cookie Validation',
|
||
description: 'Always validate auth cookies before protected requests',
|
||
content: '1) Check for auth cookie. 2) Validate expiry. 3) Refresh if needed.',
|
||
tags: ['auth', 'cookies', 'security'],
|
||
domain: 'test.web',
|
||
confidence: 0.82,
|
||
seed: 123
|
||
},
|
||
{
|
||
title: 'API Rate Limiting Backoff',
|
||
description: 'Implement exponential backoff for rate-limited APIs',
|
||
content: '1) Detect 429 status. 2) Parse Retry-After header. 3) Exponential backoff.',
|
||
tags: ['api', 'rate-limit', 'retry'],
|
||
domain: 'test.api',
|
||
confidence: 0.91,
|
||
seed: 456
|
||
},
|
||
{
|
||
title: 'Form Validation Before Submit',
|
||
description: 'Validate all form fields before submission to avoid errors',
|
||
content: '1) Check required fields. 2) Validate formats. 3) Show inline errors.',
|
||
tags: ['forms', 'validation', 'web'],
|
||
domain: 'test.web',
|
||
confidence: 0.75,
|
||
seed: 789
|
||
},
|
||
{
|
||
title: 'Database Transaction Retry Logic',
|
||
description: 'Retry failed transactions with proper isolation levels',
|
||
content: '1) Begin transaction. 2) Execute queries. 3) Retry on deadlock.',
|
||
tags: ['database', 'transactions', 'retry'],
|
||
domain: 'test.db',
|
||
confidence: 0.86,
|
||
seed: 101
|
||
}
|
||
];
|
||
for (const mem of testMemories) {
|
||
const id = ulid();
|
||
const memory = {
|
||
id,
|
||
type: 'reasoning_memory',
|
||
pattern_data: {
|
||
title: mem.title,
|
||
description: mem.description,
|
||
content: mem.content,
|
||
source: {
|
||
task_id: 'test_task',
|
||
agent_id: 'test_agent',
|
||
outcome: 'Success',
|
||
evidence: ['step_1']
|
||
},
|
||
tags: mem.tags,
|
||
domain: mem.domain,
|
||
created_at: new Date().toISOString(),
|
||
confidence: mem.confidence,
|
||
n_uses: 0
|
||
},
|
||
confidence: mem.confidence,
|
||
usage_count: 0
|
||
};
|
||
upsertMemory(memory);
|
||
upsertEmbedding({
|
||
id,
|
||
model: 'test-model',
|
||
dims: 1024,
|
||
vector: createEmbedding(mem.seed),
|
||
created_at: new Date().toISOString()
|
||
});
|
||
}
|
||
console.log(` ✅ Inserted ${testMemories.length} test memories\n`);
|
||
// Test retrieval
|
||
console.log('2️⃣ Testing retrieval with different queries...\n');
|
||
const queries = [
|
||
{
|
||
query: 'How to handle CSRF tokens in web forms?',
|
||
expectedTitles: ['CSRF Token Handling', 'Form Validation Before Submit'],
|
||
domain: 'test.web'
|
||
},
|
||
{
|
||
query: 'API rate limiting and retry strategies',
|
||
expectedTitles: ['API Rate Limiting Backoff'],
|
||
domain: 'test.api'
|
||
},
|
||
{
|
||
query: 'Database error recovery and transaction handling',
|
||
expectedTitles: ['Database Transaction Retry Logic'],
|
||
domain: 'test.db'
|
||
}
|
||
];
|
||
const config = loadConfig();
|
||
for (const test of queries) {
|
||
console.log(`Query: "${test.query}"`);
|
||
console.log(`Domain filter: ${test.domain}`);
|
||
const candidates = fetchMemoryCandidates({
|
||
domain: test.domain,
|
||
minConfidence: config.retrieve.min_score
|
||
});
|
||
console.log(`Retrieved ${candidates.length} candidates:`);
|
||
candidates.forEach((c, idx) => {
|
||
console.log(` ${idx + 1}. ${c.pattern_data.title} (conf: ${c.confidence}, age: ${c.age_days}d)`);
|
||
});
|
||
// Simple scoring simulation (without actual embeddings comparison)
|
||
console.log(`\nTop-k (k=${config.retrieve.k}) selection would use:`);
|
||
console.log(` α=${config.retrieve.alpha} (similarity)`);
|
||
console.log(` β=${config.retrieve.beta} (recency)`);
|
||
console.log(` γ=${config.retrieve.gamma} (reliability)`);
|
||
console.log(` δ=${config.retrieve.delta} (diversity/MMR)`);
|
||
console.log('\n---\n');
|
||
}
|
||
// Test cosine similarity
|
||
console.log('3️⃣ Testing cosine similarity...\n');
|
||
function cosineSimilarity(a, b) {
|
||
let dot = 0, magA = 0, magB = 0;
|
||
for (let i = 0; i < a.length; i++) {
|
||
dot += a[i] * b[i];
|
||
magA += a[i] * a[i];
|
||
magB += b[i] * b[i];
|
||
}
|
||
return dot / (Math.sqrt(magA) * Math.sqrt(magB));
|
||
}
|
||
const vec1 = createEmbedding(42);
|
||
const vec2 = createEmbedding(42); // identical
|
||
const vec3 = createEmbedding(123); // different
|
||
const sim12 = cosineSimilarity(vec1, vec2);
|
||
const sim13 = cosineSimilarity(vec1, vec3);
|
||
console.log(`Cosine similarity (identical vectors): ${sim12.toFixed(4)}`);
|
||
console.log(`Cosine similarity (different vectors): ${sim13.toFixed(4)}`);
|
||
if (Math.abs(sim12 - 1.0) < 0.001) {
|
||
console.log(' ✅ Identical vectors have similarity ≈ 1.0');
|
||
}
|
||
else {
|
||
console.log(` ⚠️ Identical vectors similarity is ${sim12}, expected ≈ 1.0`);
|
||
}
|
||
if (sim13 < sim12) {
|
||
console.log(' ✅ Different vectors have lower similarity');
|
||
}
|
||
else {
|
||
console.log(' ⚠️ Different vectors similarity is unexpectedly high');
|
||
}
|
||
console.log('\n✅ Retrieval algorithm validation complete!\n');
|
||
//# sourceMappingURL=test-retrieval.js.map
|