Spaces:
Paused
Paused
| 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); | |
| } | |