@sema-agent/core
Version:
Stateless, task-oriented AI agent core
41 lines (40 loc) • 1.22 kB
JavaScript
const CJK_RUN = /[\u3040-\u30FF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\u9FFF\uAC00-\uD7A3\uF900-\uFAFF]+/g;
export function termSet(s) {
const lower = s.toLowerCase();
const out = new Set();
for (const run of lower.split(/[^a-z0-9]+/))
if (run)
out.add(run);
for (const m of lower.matchAll(CJK_RUN)) {
const chars = [...m[0]];
for (const c of chars)
out.add(c);
for (let i = 0; i + 1 < chars.length; i++)
out.add(chars[i] + chars[i + 1]);
}
return out;
}
export function jaccardDistance(query, text) {
const t = termSet(text);
let inter = 0;
for (const term of query) {
if (t.has(term))
inter++;
}
const union = query.size + t.size - inter;
const jaccard = union === 0 ? 0 : inter / union;
return jaccard === 0 ? null : 1 - jaccard;
}
export function cosineDistance(a, b) {
let dot = 0;
let na = 0;
let nb = 0;
const n = Math.min(a.length, b.length);
for (let i = 0; i < n; i++) {
dot += a[i] * b[i];
na += a[i] * a[i];
nb += b[i] * b[i];
}
const denom = Math.sqrt(na) * Math.sqrt(nb);
return denom === 0 ? 1 : 1 - dot / denom;
}