"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MockEmbedding = exports.SentenceTransformerEmbedding = void 0;
const child_process_1 = require("child_process");
const logger_1 = __importDefault(require("../utils/logger"));
class SentenceTransformerEmbedding {
constructor(model = 'all-MiniLM-L6-v2') {
this.pythonProcess = null;
this.model = model;
}
async embed(text) {
const results = await this.embedBatch([text]);
return results[0];
}
async embedBatch(texts) {
return new Promise((resolve, reject) => {
// Use a simple Python script approach for now
const pythonScript = `
import sys
import json
from sentence_transformers import SentenceTransformer
try:
model = SentenceTransformer('${this.model}')
texts = json.loads(sys.argv[1])
embeddings = model.encode(texts).tolist()
print(json.dumps(embeddings))
except Exception as e:
print(f"ERROR: {str(e)}", file=sys.stderr)
sys.exit(1)
`;
const python = (0, child_process_1.spawn)('python3', ['-c', pythonScript, JSON.stringify(texts)]);
let stdout = '';
let stderr = '';
python.stdout.on('data', (data) => {
stdout += data.toString();
});
python.stderr.on('data', (data) => {
stderr += data.toString();
});
python.on('close', (code) => {
if (code !== 0) {
logger_1.default.error('Python embedding process failed', { stderr, code });
reject(new Error(`Embedding failed: ${stderr}`));
return;
}
try {
const embeddings = JSON.parse(stdout.trim());
resolve(embeddings);
}
catch (error) {
logger_1.default.error('Failed to parse embedding results', { stdout, error });
reject(new Error('Failed to parse embedding results'));
}
});
python.on('error', (error) => {
logger_1.default.error('Failed to spawn Python process', { error });
reject(new Error(`Failed to spawn Python process: ${error.message}`));
});
});
}
}
exports.SentenceTransformerEmbedding = SentenceTransformerEmbedding;
// Simple mock embedding for testing without Python dependencies
class MockEmbedding {
async embed(text) {
// Generate deterministic embedding based on text hash
const hash = this.simpleHash(text);
const embedding = [];
for (let i = 0; i < 384; i++) {
embedding.push((Math.sin(hash + i) + 1) / 2); // Normalize to [0,1]
}
return embedding;
}
async embedBatch(texts) {
return Promise.all(texts.map(text => this.embed(text)));
}
simpleHash(str) {
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32-bit integer
}
return Math.abs(hash);
}
}
exports.MockEmbedding = MockEmbedding;