function termFreq(text) { const words = text.toLowerCase().match(/\w+/g) || []; const freq = {}; words.forEach(w => freq[w] = (freq[w] || 0) + 1); return freq; } export function cosineSimilarity(textA, textB) { const fA = termFreq(textA); const fB = termFreq(textB); const words = new Set([...Object.keys(fA), ...Object.keys(fB)]); let dot = 0, magA = 0, magB = 0; words.forEach(w => { const a = fA[w] || 0; const b = fB[w] || 0; dot += a * b; magA += a * a; magB += b * b; }); if (!magA || !magB) return 0; return dot / (Math.sqrt(magA) * Math.sqrt(magB)); } export function searchChunks(query, chunks, topK = 2) { if (!chunks || chunks.length === 0) return []; return chunks .map(c => ({ text: c, score: cosineSimilarity(query, c) })) .sort((a, b) => b.score - a.score) .slice(0, topK) .map(item => item.text); }