rag-whatsapp / src /embeddings.js
DHEIVER's picture
feat: fallback de modelos HF + retry no embedding
08e2e65
Raw
History Blame Contribute Delete
1.26 kB
import { config } from './config.js';
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
export async function embed(texts, kind = 'passage') {
const inputs = (Array.isArray(texts) ? texts : [texts]).map(t => `${kind}: ${t}`);
const url = `${config.hfApiUrl}/hf-inference/models/${config.embedModel}/pipeline/feature-extraction`;
// Retry: o endpoint hf-inference às vezes dá 503/504 (modelo frio) — tenta de novo.
let lastErr = '';
for (let attempt = 1; attempt <= 4; attempt++) {
try {
const res = await fetch(url, {
method: 'POST',
headers: { Authorization: `Bearer ${config.hfToken}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ inputs, options: { wait_for_model: true } }),
});
if (res.ok) return res.json();
lastErr = `HF embed ${res.status}`;
} catch (e) {
lastErr = `HF embed: ${e.message}`;
}
if (attempt < 4) await sleep(attempt * 1500); // backoff: 1.5s, 3s, 4.5s
}
throw new Error(`${lastErr} (após 4 tentativas)`);
}
export function cosine(a, b) {
let dot = 0, na = 0, nb = 0;
for (let i = 0; i < a.length; i++) { dot += a[i]*b[i]; na += a[i]*a[i]; nb += b[i]*b[i]; }
return dot / (Math.sqrt(na) * Math.sqrt(nb) + 1e-8);
}