test-semantic-search.jsā¢7.16 kB
#!/usr/bin/env node
import { SequentialGraphitiIntegration } from './src/core/SequentialGraphitiIntegration.js';
console.log('š Testing meMCP Semantic Search Functionality\n');
async function testSemanticSearch() {
const integration = new SequentialGraphitiIntegration();
try {
await integration.initialize();
console.log('ā
meMCP system initialized\n');
// Add diverse test facts for semantic testing
console.log('š Adding test facts for semantic search...\n');
const testFacts = [
{
content: 'React components should use hooks for state management instead of class-based state',
type: 'verified_pattern',
domain: 'react',
tags: ['react', 'hooks', 'state', 'components']
},
{
content: 'State management in React applications can be handled with useState and useEffect hooks',
type: 'verified_pattern',
domain: 'react',
tags: ['react', 'state', 'hooks', 'usestate', 'useeffect']
},
{
content: 'Component state in Vue.js is managed differently than React using reactive data properties',
type: 'verified_pattern',
domain: 'vue',
tags: ['vue', 'state', 'reactive', 'components']
},
{
content: 'JavaScript async/await syntax provides better error handling than Promise chains',
type: 'optimization',
domain: 'javascript',
tags: ['javascript', 'async', 'promises', 'error-handling']
},
{
content: 'Error handling in JavaScript can be improved using try-catch blocks with async functions',
type: 'optimization',
domain: 'javascript',
tags: ['javascript', 'error-handling', 'async', 'try-catch']
},
{
content: 'CSS Grid layout system provides two-dimensional control over web page layouts',
type: 'verified_pattern',
domain: 'css',
tags: ['css', 'grid', 'layout', 'web-design']
},
{
content: 'Web page layouts can be created using CSS Flexbox for one-dimensional arrangements',
type: 'verified_pattern',
domain: 'css',
tags: ['css', 'flexbox', 'layout', 'web-design']
},
{
content: 'Database query optimization improves application performance significantly',
type: 'optimization',
domain: 'database',
tags: ['database', 'performance', 'queries', 'optimization']
},
{
content: 'Application performance can be enhanced through efficient database indexing strategies',
type: 'optimization',
domain: 'database',
tags: ['database', 'performance', 'indexing', 'optimization']
},
{
content: 'Security vulnerabilities in web applications often stem from inadequate input validation',
type: 'security_concern',
domain: 'security',
tags: ['security', 'validation', 'web-applications', 'vulnerabilities']
}
];
for (const fact of testFacts) {
await integration.memoryTools.storeInsight(fact);
}
console.log(`ā
Added ${testFacts.length} test facts for semantic analysis\n`);
// Test semantic search capabilities
console.log('š Testing semantic search queries...\n');
const testQueries = [
'state management in frontend frameworks',
'error handling best practices',
'layout techniques for web design',
'performance optimization strategies',
'web application security'
];
for (const query of testQueries) {
console.log(`\n--- Query: "${query}" ---`);
const result = await integration.factStore.queryFacts({
query,
limit: 3,
sortBy: 'relevance'
});
if (result.facts && result.facts.length > 0) {
result.facts.forEach((fact, index) => {
console.log(`${index + 1}. [${fact.type}] Score: ${fact.relevanceScore?.toFixed(2) || 'N/A'}`);
console.log(` "${fact.content.substring(0, 80)}..."`);
if (fact.semanticScore !== undefined) {
console.log(` Semantic: ${fact.semanticScore.toFixed(3)}, Keyword: ${fact.keywordScore || 0}`);
}
});
} else {
console.log(' No results found');
}
}
// Test semantic statistics
console.log('\nš Semantic Index Statistics:');
const semanticStats = integration.factStore.getSemanticStats();
console.log(` Total Documents: ${semanticStats.totalDocuments}`);
console.log(` Vocabulary Size: ${semanticStats.vocabularySize}`);
console.log(` Average Doc Length: ${semanticStats.averageDocumentLength.toFixed(1)} terms`);
if (semanticStats.topTerms && semanticStats.topTerms.length > 0) {
console.log(` Top Terms: ${semanticStats.topTerms.slice(0, 5).map(t => t.term).join(', ')}`);
}
// Test similar document finding
console.log('\nš Testing similar document finding...');
const allFacts = await integration.factStore.getAllFacts();
if (allFacts.length > 0) {
const testFactId = allFacts[0].id;
const similarFacts = await integration.factStore.findSimilarFacts(testFactId, {
limit: 3,
threshold: 0.2
});
console.log(`\nSimilar to: "${allFacts[0].content.substring(0, 60)}..."`);
similarFacts.forEach((fact, index) => {
console.log(`${index + 1}. Similarity: ${fact.similarity.toFixed(3)}`);
console.log(` "${fact.content.substring(0, 80)}..."`);
});
}
// Test keyword extraction
console.log('\nš·ļø Testing keyword extraction...');
if (allFacts.length > 0) {
const testFactId = allFacts[0].id;
const keywords = integration.factStore.getFactKeywords(testFactId, 5);
console.log(`\nKeywords for: "${allFacts[0].content.substring(0, 60)}..."`);
keywords.forEach((keyword, index) => {
console.log(`${index + 1}. "${keyword.term}" (score: ${keyword.score.toFixed(3)})`);
});
}
// Compare semantic vs keyword search
console.log('\nāļø Comparing semantic vs keyword search...');
const comparisonQuery = 'frontend state';
console.log(`\nQuery: "${comparisonQuery}"`);
// Force keyword search by using a smaller semantic index
const originalStats = integration.factStore.semanticIndex.getStats();
console.log(`\nš Semantic Search (${originalStats.totalDocuments} docs in index):`);
const semanticResult = await integration.factStore.queryFacts({
query: comparisonQuery,
limit: 3,
sortBy: 'relevance'
});
if (semanticResult.facts && semanticResult.facts.length > 0) {
semanticResult.facts.forEach((fact, index) => {
console.log(`${index + 1}. Score: ${fact.relevanceScore?.toFixed(2) || 'N/A'}`);
console.log(` "${fact.content.substring(0, 80)}..."`);
});
}
console.log('\nā
Semantic search testing completed successfully!');
} catch (error) {
console.error('ā Error in semantic search test:', error);
} finally {
await integration.shutdown();
}
}
testSemanticSearch().catch(console.error);