import crypto from "node:crypto";
export function buildStablePromptBlock(parts) {
    const text = parts
        .map((part) => [`<${part.title}>`, normalizeStableText(part.body), `</${part.title}>`].join("\n"))
        .join("\n\n");
    return {
        text,
        hash: crypto.createHash("sha256").update(text).digest("hex").slice(0, 16),
        approxTokens: approximateTokens(text),
    };
}
export class PrefixStabilityManager {
    pinned;
    current;
    changes = 0;
    checks = 0;
    last;
    check(systemText, tools) {
        const next = computePrefixFingerprint(systemText, tools);
        this.checks += 1;
        if (!this.pinned) {
            this.pinned = next;
            this.current = next;
            return { stable: true, fingerprint: next };
        }
        const previous = this.current ?? this.pinned;
        this.current = next;
        if (next.combinedSha256 === this.pinned.combinedSha256) {
            return { stable: true, fingerprint: next };
        }
        const systemChanged = next.systemSha256 !== this.pinned.systemSha256;
        const toolsChanged = next.toolsSha256 !== this.pinned.toolsSha256;
        const drift = {
            previous,
            current: next,
            systemChanged,
            toolsChanged,
            label: systemChanged && toolsChanged
                ? "system+tools"
                : systemChanged
                    ? "system"
                    : toolsChanged
                        ? "tools"
                        : "unknown",
        };
        this.last = drift;
        this.changes += 1;
        this.pinned = next;
        return { stable: false, drift };
    }
    snapshot() {
        const stableChecks = Math.max(0, this.checks - this.changes);
        return {
            checks: this.checks,
            changes: this.changes,
            stableRatio: this.checks > 0 ? stableChecks / this.checks : 1,
            last: this.last,
        };
    }
}
export function computePrefixFingerprint(systemText, tools) {
    const systemSha256 = sha256(systemText);
    const toolNames = tools.map((tool) => tool.name).sort().join(",");
    const toolsSha256 = sha256(toolNames);
    return {
        systemSha256,
        toolsSha256,
        combinedSha256: sha256(`${systemSha256}:${toolsSha256}`),
    };
}
export function buildDynamicPromptBlock(parts) {
    return parts
        .map((part) => [`<${part.title}>`, part.body.trim(), `</${part.title}>`].join("\n"))
        .join("\n\n");
}
export function cacheRate(hit, miss) {
    const h = hit ?? 0;
    const m = miss ?? 0;
    const total = h + m;
    if (total <= 0)
        return "n/a";
    return `${Math.round((h / total) * 100)}%`;
}
export function approximateTokens(text) {
    return Math.ceil(text.length / 4);
}
function normalizeStableText(text) {
    return text.replace(/\r\n/g, "\n").trim();
}
function sha256(text) {
    return crypto.createHash("sha256").update(text).digest("hex");
}
