n8n-nodes-rag
Version:
Advanced RAG (Retrieval-Augmented Generation) knowledge base nodes for n8n
137 lines • 5.06 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EmbeddingGenerator = void 0;
const axios_1 = __importDefault(require("axios"));
class EmbeddingGenerator {
static async generateEmbeddings(chunks, options) {
if (!options.enabled) {
return chunks;
}
switch (options.provider) {
case 'openai':
return this.generateOpenAIEmbeddings(chunks, options);
case 'huggingface':
return this.generateHuggingFaceEmbeddings(chunks, options);
case 'custom':
return this.generateCustomEmbeddings(chunks, options);
default:
throw new Error(`Unknown embedding provider: ${options.provider}`);
}
}
static async generateOpenAIEmbeddings(chunks, options) {
const model = options.model || 'text-embedding-ada-002';
const apiKey = options.apiKey;
if (!apiKey) {
throw new Error('OpenAI API key is required');
}
const result = [];
const batchSize = 100;
for (let i = 0; i < chunks.length; i += batchSize) {
const batch = chunks.slice(i, i + batchSize);
const texts = batch.map(chunk => chunk.text);
try {
const response = await axios_1.default.post('https://api.openai.com/v1/embeddings', {
input: texts,
model: model,
}, {
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
});
const embeddings = response.data.data;
for (let j = 0; j < batch.length; j++) {
result.push({
...batch[j],
embedding: embeddings[j].embedding,
});
}
}
catch (error) {
throw new Error(`OpenAI API error: ${error}`);
}
}
return result;
}
static async generateHuggingFaceEmbeddings(chunks, options) {
const model = options.model || 'sentence-transformers/all-MiniLM-L6-v2';
const apiKey = options.apiKey;
if (!apiKey) {
throw new Error('Hugging Face API key is required');
}
const result = [];
for (const chunk of chunks) {
try {
const response = await axios_1.default.post(`https://api-inference.huggingface.co/pipeline/feature-extraction/${model}`, {
inputs: chunk.text,
}, {
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
});
const embedding = Array.isArray(response.data[0]) ? response.data[0] : response.data;
result.push({
...chunk,
embedding: embedding,
});
}
catch (error) {
throw new Error(`Hugging Face API error: ${error}`);
}
}
return result;
}
static async generateCustomEmbeddings(chunks, options) {
const endpoint = options.endpoint;
const apiKey = options.apiKey;
if (!endpoint) {
throw new Error('Custom endpoint is required');
}
const result = [];
for (const chunk of chunks) {
try {
const headers = {
'Content-Type': 'application/json',
};
if (apiKey) {
headers['Authorization'] = `Bearer ${apiKey}`;
}
const response = await axios_1.default.post(endpoint, {
text: chunk.text,
model: options.model,
}, { headers });
result.push({
...chunk,
embedding: response.data.embedding,
});
}
catch (error) {
throw new Error(`Custom API error: ${error}`);
}
}
return result;
}
static cosineSimilarity(a, b) {
if (a.length !== b.length) {
throw new Error('Vectors must have the same length');
}
let dotProduct = 0;
let normA = 0;
let normB = 0;
for (let i = 0; i < a.length; i++) {
dotProduct += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
if (normA === 0 || normB === 0) {
return 0;
}
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}
}
exports.EmbeddingGenerator = EmbeddingGenerator;
//# sourceMappingURL=EmbeddingGenerator.js.map