const fs = require("fs"); const crypto = require("crypto"); const { resolveData } = require("./paths"); const { writeJsonAtomicSync } = require("../../../src/services/safe-files"); class SafeAnswerCache { constructor(getConfig) { this.getConfig = getConfig; this.file = resolveData("cache", "gate-answers.json"); } key({ message, role, platform }) { const normalized = String(message || "").toLowerCase().replace(/\s+/g, " ").trim(); return crypto.createHash("sha256") .update(`gate-cache-v2\n${role || "user"}\n${platform || "webui"}\n${normalized}`) .digest("hex"); } get(input) { const entry = this.read().entries[this.key(input)]; if (!entry) return null; if (new Date(entry.expires_at).getTime() <= Date.now()) { this.delete(input); return null; } return entry; } set(input, answer) { if (!answer?.text || answer.safe !== true) return null; const ttlSeconds = Math.max(30, Number(this.getConfig()?.gate?.cache_ttl_seconds) || 3600); const store = this.read(); const key = this.key(input); store.entries[key] = { text: String(answer.text), links: Array.isArray(answer.links) ? answer.links.slice(0, 8) : [], source: answer.source || null, created_at: new Date().toISOString(), expires_at: new Date(Date.now() + ttlSeconds * 1000).toISOString() }; this.write(store); return store.entries[key]; } delete(input) { const store = this.read(); delete store.entries[this.key(input)]; this.write(store); } read() { try { const parsed = JSON.parse(fs.readFileSync(this.file, "utf8")); return { entries: parsed.entries || {} }; } catch { return { entries: {} }; } } write(store) { writeJsonAtomicSync(this.file, store); } } module.exports = { SafeAnswerCache };