Files
wifi-densepose/vendor/ruvector/.claude/intelligence/tests/v2-features.js

188 lines
5.8 KiB
JavaScript

#!/usr/bin/env node
/**
* Test v2 Intelligence Features:
* - Hyperbolic distance
* - Confidence Calibration
* - A/B Testing
* - Feedback Loop
* - Active Learning
* - Pattern Decay
*/
import RuVectorIntelligence from '../index.js';
let passed = 0, failed = 0;
async function test(name, fn) {
try {
const result = await fn();
if (result.pass) {
console.log(`${name}`);
console.log(` ${result.evidence}`);
passed++;
} else {
console.log(`${name}`);
console.log(` ${result.got}`);
failed++;
}
} catch (e) {
console.log(`${name}: ${e.message}`);
failed++;
}
}
async function main() {
console.log('\n🧪 Testing v2 Intelligence Features\n');
console.log('='.repeat(50) + '\n');
const intel = new RuVectorIntelligence({ hyperbolic: true });
await intel.init();
// === 1. Hyperbolic Distance ===
console.log('🔮 Hyperbolic Distance:\n');
await test('Hyperbolic mode is enabled', async () => {
const stats = intel.stats();
return {
pass: stats.memory.usingHyperbolic === true,
evidence: `usingHyperbolic: ${stats.memory.usingHyperbolic}`
};
});
await test('Hyperbolic search produces different scores than cosine', async () => {
// Hyperbolic similarity should be lower due to curved space
const results = await intel.recall('edit rs file', 3);
const avgScore = results.reduce((s, r) => s + r.score, 0) / results.length;
// Hyperbolic scores are typically lower (0.01-0.2 range vs 0.7+ for cosine)
return {
pass: results.length > 0,
evidence: `Avg hyperbolic similarity: ${avgScore.toFixed(4)} (curved space metric)`
};
});
// === 2. Confidence Calibration ===
console.log('\n📊 Confidence Calibration:\n');
await test('Calibration records predictions', async () => {
intel.recordCalibration('coder', 'coder', 0.8);
intel.recordCalibration('coder', 'reviewer', 0.6);
intel.recordCalibration('tester', 'tester', 0.9);
const stats = intel.stats();
const hasBuckets = Object.keys(stats.calibration.buckets).length > 0;
return {
pass: hasBuckets,
evidence: `Calibration buckets: ${JSON.stringify(stats.calibration.buckets)}`
};
});
await test('Calibration error is calculated', async () => {
const stats = intel.stats();
return {
pass: stats.calibration.calibrationError !== undefined,
evidence: `Calibration error: ${stats.calibration.calibrationError}`
};
});
// === 3. A/B Testing ===
console.log('\n🔬 A/B Testing:\n');
await test('A/B group is assigned (treatment or control)', async () => {
const suggestion = intel.suggest('test_state', ['a', 'b', 'c']);
const validGroup = ['treatment', 'control'].includes(suggestion.abGroup);
return {
pass: validGroup,
evidence: `Assigned to group: ${suggestion.abGroup}`
};
});
await test('A/B stats are tracked', async () => {
const stats = intel.stats();
return {
pass: stats.abTest.treatment !== undefined && stats.abTest.control !== undefined,
evidence: `Treatment: ${stats.abTest.treatment.total}, Control: ${stats.abTest.control.total}`
};
});
// === 4. Feedback Loop ===
console.log('\n🔄 Feedback Loop:\n');
await test('Routing returns suggestionId for feedback', async () => {
const routing = await intel.route('test task', { fileType: 'rs' });
return {
pass: routing.suggestionId && routing.suggestionId.startsWith('sug-'),
evidence: `SuggestionId: ${routing.suggestionId}`
};
});
await test('Feedback can be recorded', async () => {
const routing = await intel.route('another task', { fileType: 'ts' });
intel.recordFeedback(routing.suggestionId, routing.recommended, true);
// No error = success
return {
pass: true,
evidence: `Recorded feedback for ${routing.suggestionId}`
};
});
// === 5. Active Learning ===
console.log('\n🎯 Active Learning:\n');
await test('Uncertain states are identified', async () => {
// Create some states with close Q-values
intel.learn('uncertain_state_1', 'action_a', 'outcome', 0.3);
intel.learn('uncertain_state_1', 'action_b', 'outcome', 0.28);
const stats = intel.stats();
return {
pass: stats.uncertainStates !== undefined,
evidence: `Uncertain states found: ${stats.uncertainStates.length}`
};
});
await test('Suggestion flags uncertain states', async () => {
// Query a state with no prior data
const suggestion = intel.suggest('completely_novel_state_xyz', ['a', 'b', 'c']);
return {
pass: suggestion.isUncertain !== undefined,
evidence: `isUncertain: ${suggestion.isUncertain}, gap: ${suggestion.uncertaintyGap}`
};
});
// === 6. Pattern Decay ===
console.log('\n⏰ Pattern Decay:\n');
await test('Q-table tracks metadata for decay', async () => {
intel.learn('decay_test_state', 'action', 'outcome', 1.0);
const qTable = intel.reasoning.qTable;
const hasMetadata = qTable['decay_test_state']?._meta?.lastUpdate !== undefined;
return {
pass: hasMetadata,
evidence: `Last update tracked: ${qTable['decay_test_state']?._meta?.lastUpdate}`
};
});
await test('Update count is tracked', async () => {
intel.learn('decay_test_state', 'action', 'outcome', 0.5);
intel.learn('decay_test_state', 'action', 'outcome', 0.8);
const updateCount = intel.reasoning.qTable['decay_test_state']?._meta?.updateCount || 0;
return {
pass: updateCount >= 2,
evidence: `Update count: ${updateCount}`
};
});
// === Summary ===
console.log('\n' + '='.repeat(50));
console.log(`\n📊 V2 Features: ${passed} passed, ${failed} failed\n`);
if (failed === 0) {
console.log('✅ All v2 features working correctly\n');
} else {
console.log('⚠️ Some v2 features need attention\n');
process.exit(1);
}
}
main().catch(console.error);