tasq/node_modules/agentic-flow/dist/reasoningbank/test-retrieval.js

177 lines
6.2 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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