hikma-engine
Version:
Code Knowledge Graph Indexer - A sophisticated TypeScript-based indexer that transforms Git repositories into multi-dimensional knowledge stores for AI agents
87 lines (86 loc) • 3.51 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.storeVector = storeVector;
exports.vectorSearch = vectorSearch;
exports.semanticSearch = semanticSearch;
exports.batchStoreEmbeddings = batchStoreEmbeddings;
const error_handling_1 = require("../../utils/error-handling");
const error_handling_2 = require("../../utils/error-handling");
async function storeVector(client, table, column, recordId, embedding) {
const db = client.getDb();
const embeddingBlob = Buffer.from(new Float32Array(embedding).buffer);
const sql = `UPDATE ${table} SET ${column} = ? WHERE id = ?`;
try {
db.prepare(sql).run(embeddingBlob, recordId);
}
catch (error) {
throw new error_handling_1.DatabaseOperationError('SQLite', 'storeVector', (0, error_handling_2.getErrorMessage)(error), error);
}
}
async function vectorSearch(client, table, column, queryEmbedding, limit = 10, threshold) {
const db = client.getDb();
const queryBlob = Buffer.from(new Float32Array(queryEmbedding).buffer);
let sql = `
SELECT id,
vec_distance_cosine(${column}, ?) as similarity,
*
FROM ${table}
WHERE ${column} IS NOT NULL
`;
const params = [queryBlob];
if (threshold !== undefined) {
const distanceThreshold = 1 - threshold;
sql += ` AND vec_distance_cosine(${column}, ?) <= ?`;
params.push(queryBlob, distanceThreshold);
}
sql += ` ORDER BY similarity ASC LIMIT ?`;
params.push(limit);
try {
const results = db.prepare(sql).all(...params);
return results.map((row) => ({
id: row.id,
similarity: 1 - row.similarity,
data: row,
}));
}
catch (error) {
throw new error_handling_1.DatabaseOperationError('SQLite', 'vectorSearch', (0, error_handling_2.getErrorMessage)(error), error);
}
}
async function semanticSearch(client, queryEmbedding, limit = 5) {
const [files, functions, commits, pullRequests] = await Promise.all([
vectorSearch(client, 'files', 'content_embedding', queryEmbedding, limit),
vectorSearch(client, 'functions', 'signature_embedding', queryEmbedding, limit),
vectorSearch(client, 'commits', 'message_embedding', queryEmbedding, limit),
vectorSearch(client, 'pull_requests', 'title_embedding', queryEmbedding, limit),
]);
return { files, functions, commits, pullRequests };
}
async function batchStoreEmbeddings(client, table, column, records) {
const db = client.getDb();
const stmt = db.prepare(`UPDATE ${table} SET ${column} = ? WHERE id = ?`);
let success = 0;
let failed = 0;
const errors = [];
const updateMany = db.transaction((recordList) => {
for (const record of recordList) {
try {
const embeddingBlob = Buffer.from(new Float32Array(record.embedding).buffer);
stmt.run(embeddingBlob, record.id);
success++;
}
catch (error) {
failed++;
const errorMsg = `Failed to store embedding for ${record.id}: ${(0, error_handling_2.getErrorMessage)(error)}`;
errors.push(errorMsg);
}
}
});
try {
updateMany(records);
}
catch (error) {
throw new error_handling_1.DatabaseOperationError('SQLite', 'batchStoreEmbeddings', (0, error_handling_2.getErrorMessage)(error), error);
}
return { success, failed, errors };
}