UNPKG

secuprompt

Version:

Protect your AI from Prompt Injection

91 lines (90 loc) 2.87 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.score_signatures = void 0; const data_1 = require("../data"); const embedding_1 = require("../core/embedding"); const make_trie = (phrases) => { const root = { next: {} }; for (const raw of phrases) { const w = raw.toLowerCase(); let cur = root; for (const ch of w) { cur = cur.next[ch] ?? (cur.next[ch] = { next: {} }); } ; (cur.end ?? (cur.end = [])).push(w); } return root; }; const sig_trie = make_trie(data_1.signature_patterns); const scan_trie = (txt) => { const hits = new Set(); const lo = txt.toLowerCase(); for (let i = 0; i < lo.length; i++) { let cur = sig_trie; let j = i; while (j < lo.length) { const ch = lo[j]; const nxt = cur.next[ch]; if (!nxt) break; cur = nxt; if (cur.end) cur.end.forEach(s => hits.add(s)); j++; } } return [...hits]; }; const levenshtein = (a, b) => { const la = a.length, lb = b.length; if (la === 0) return lb; if (lb === 0) return la; const prev = new Array(lb + 1).fill(0); const cur = new Array(lb + 1).fill(0); for (let j = 0; j <= lb; j++) prev[j] = j; for (let i = 1; i <= la; i++) { cur[0] = i; const ca = a.charCodeAt(i - 1); for (let j = 1; j <= lb; j++) { const cb = b.charCodeAt(j - 1); if (ca === cb) cur[j] = prev[j - 1]; else cur[j] = Math.min(prev[j - 1], prev[j], cur[j - 1]) + 1; } for (let j = 0; j <= lb; j++) prev[j] = cur[j]; } return cur[lb]; }; const fuzzy_hits = (txt) => { const segs = (0, embedding_1.seg_text)(txt); const result = []; for (const phrase of data_1.signature_patterns) { for (const seg of segs) { const lv = levenshtein(seg, phrase); const sim = 1 - lv / Math.max(seg.length, phrase.length); if (sim > 0.82) result.push({ phrase, sim }); } } return result; }; const score_signatures = (txt) => { const exact = scan_trie(txt); const fuzzy = fuzzy_hits(txt); const reasons = []; if (exact.length) reasons.push("direct_signature_" + exact[0]); if (fuzzy.length) reasons.push("fuzzy_signature_" + fuzzy[0].phrase); const ex_score = exact.length ? Math.min(1, 0.6 + 0.1 * (exact.length - 1)) : 0; const f_best = fuzzy.reduce((m, v) => Math.max(m, v.sim), 0); const f_score = f_best ? ((f_best - 0.82) / (1 - 0.82)) * 0.6 : 0; return { score: (0, embedding_1.normalize)(ex_score + f_score), detail: reasons }; }; exports.score_signatures = score_signatures;