UNPKG

@nataliapc/mcp-openmsx

Version:

Model context protocol server for openMSX automation and control

62 lines (61 loc) 1.98 kB
/** * Vector Database wrapper class * * @author Natalia Pujol Cremades (@nataliapc) * @license GPL2 */ import path from 'path'; import { LocalIndex } from 'vectra'; import embeddings from '@themaximalist/embeddings.js'; export class VectorDB { static instance; static vectorDbDir = path.join('..', 'vector-db'); index; static getInstance() { if (!VectorDB.instance) { VectorDB.instance = new VectorDB(); } return VectorDB.instance; } static setIndexDirectory(dbDir) { VectorDB.vectorDbDir = dbDir; } constructor(dbDir = VectorDB.vectorDbDir) { this.index = new LocalIndex(dbDir); if (!this.initDatabase()) { throw new Error('Failed to initialize VectorDB: Index does not exist'); } } async initDatabase() { return await this.index.isIndexCreated(); } async getVector(text) { const response = await embeddings(text); if (!response || !Array.isArray(response) || response.length === 0) { throw new Error('Failed to generate embedding vector'); } return response; } async query(text) { const vector = await this.getVector(text); let results = []; try { results = await this.index.queryItems(vector, text, 10); if (results.length > 0) { return results.map(result => { return { score: result.score.toFixed(4), uri: result.item.metadata?.uri || 'unknown', title: result.item.metadata?.title || 'unknown', document: String(result.item.metadata?.document || ''), id: result.item.metadata?.id || 'unknown', }; }); } } catch (error) { throw new Error(`Query failed: ${error}`); } return results; } }