39 lines
1.4 KiB
TypeScript
39 lines
1.4 KiB
TypeScript
import fs from "fs";
|
|
import { ASSISTANT_CANON_FILE } from "../config";
|
|
|
|
const FALLBACK_CANON = [
|
|
"Не выдумывай возможности.",
|
|
"Не обещай настройку 1С и админ-действия.",
|
|
"Не показывай внутренние технические термины пользователю.",
|
|
"Говори по-человечески и предлагай ближайший полезный поддерживаемый шаг."
|
|
].join(" ");
|
|
|
|
let cache: { mtimeMs: number; excerpt: string } | null = null;
|
|
|
|
function stripMarkdown(input: string): string {
|
|
return input
|
|
.replace(/^#{1,6}\s+/gm, "")
|
|
.replace(/[`*_>\-\[\]\(\)]/g, " ")
|
|
.replace(/\s+/g, " ")
|
|
.trim();
|
|
}
|
|
|
|
export function loadAssistantCanonExcerpt(maxChars = 900): string {
|
|
try {
|
|
const mtimeMs = fs.existsSync(ASSISTANT_CANON_FILE) ? fs.statSync(ASSISTANT_CANON_FILE).mtimeMs : -1;
|
|
if (cache && cache.mtimeMs === mtimeMs) {
|
|
return cache.excerpt;
|
|
}
|
|
if (!fs.existsSync(ASSISTANT_CANON_FILE)) {
|
|
return FALLBACK_CANON;
|
|
}
|
|
const raw = fs.readFileSync(ASSISTANT_CANON_FILE, "utf-8");
|
|
const normalized = stripMarkdown(raw);
|
|
const excerpt = normalized.length > maxChars ? `${normalized.slice(0, maxChars).trim()}...` : normalized;
|
|
cache = { mtimeMs, excerpt: excerpt || FALLBACK_CANON };
|
|
return cache.excerpt;
|
|
} catch {
|
|
return cache?.excerpt ?? FALLBACK_CANON;
|
|
}
|
|
}
|