import { createHash } from "crypto";
const DEFAULT_MAX_KEYWORDS = 14;
const DEFAULT_MAX_PHRASES = 2;
const TOKEN_PATTERN = /[\p{L}\p{N}_-]+/gu;
const STOPWORDS = new Set([
    "the",
    "and",
    "for",
    "with",
    "that",
    "this",
    "from",
    "into",
    "should",
    "must",
    "have",
    "been",
    "were",
    "are",
    "was",
    "not",
    "use",
    "using",
    "하다",
    "해서",
    "하면",
    "그리고",
    "으로",
    "에서",
    "에게",
    "좀",
    "현재",
    "일단",
]);
/**
 * Render a compact, non-verbatim reference for a user prompt or goal.
 *
 * Goal-followup prompts should carry enough context for Kimi to infer the next
 * action without re-sending the user's original input as the next prompt.
 */
export function renderPromptDigest(title, value, options = {}) {
    const normalized = normalizePromptText(value ?? "");
    if (!normalized)
        return "";
    const keywords = extractPromptKeywords(normalized, options.maxKeywords ?? DEFAULT_MAX_KEYWORDS);
    const intentSketch = sketchPromptIntent(normalized, options.maxPhrases ?? DEFAULT_MAX_PHRASES);
    return [
        `${title}:`,
        `- digest: ${promptDigestFingerprint(normalized)}`,
        `- keywords: ${keywords.length > 0 ? keywords.join(", ") : "none"}`,
        `- intent sketch: ${intentSketch.length > 0 ? intentSketch.join(" / ") : "context unavailable"}`,
        `- verbatim source: omitted to prevent input replay; synthesize from evidence and state.`,
    ].join("\n");
}
export function promptDigestFingerprint(value) {
    return createHash("sha256")
        .update(normalizePromptText(value))
        .digest("hex")
        .slice(0, 12);
}
export function extractPromptKeywords(value, maxKeywords = DEFAULT_MAX_KEYWORDS) {
    const seen = new Set();
    const tokens = normalizePromptText(value).toLocaleLowerCase().match(TOKEN_PATTERN) ?? [];
    const result = [];
    for (const token of tokens) {
        if (token.length < 2)
            continue;
        if (/^\d+$/u.test(token))
            continue;
        if (STOPWORDS.has(token))
            continue;
        if (seen.has(token))
            continue;
        seen.add(token);
        result.push(token);
        if (result.length >= maxKeywords)
            break;
    }
    return result;
}
function sketchPromptIntent(value, maxPhrases) {
    const phrases = [];
    const clauses = normalizePromptText(value)
        .split(/[.!?;\n]+/u)
        .map((part) => part.trim())
        .filter(Boolean);
    for (const clause of clauses) {
        const clauseKeywords = extractPromptKeywords(clause, 7);
        if (clauseKeywords.length === 0)
            continue;
        phrases.push(clauseKeywords.join(" "));
        if (phrases.length >= maxPhrases)
            break;
    }
    return phrases;
}
function normalizePromptText(value) {
    return redactPromptSecrets(value
        .normalize("NFKC")
        .replace(/\s+/g, " ")
        .trim());
}
function redactPromptSecrets(value) {
    return value
        .replace(/Bearer\s+[A-Za-z0-9._~+/=-]{12,}/gi, "Bearer [REDACTED_TOKEN]")
        .replace(/sk-[A-Za-z0-9_-]{16,}/g, "[REDACTED_API_KEY]")
        .replace(/(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{16,}/g, "[REDACTED_GITHUB_TOKEN]")
        .replace(/AKIA[0-9A-Z]{16}/g, "[REDACTED_AWS_KEY]")
        .replace(/[A-Z][A-Z0-9_]*(?:SECRET|TOKEN|KEY|PASSWORD)\s*=\s*[^\s`'"]{6,}/g, "[REDACTED_ENV_SECRET]")
        .replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g, "[REDACTED_PRIVATE_KEY]");
}
