import { compactMemoryText } from "./event-summary.js";
export function createMemoryRetrievalRequest(options) {
    return {
        query: options.query.trim(),
        projectId: options.projectId,
        sessionId: options.sessionId,
        types: options.types,
        filePaths: options.filePaths,
        tags: options.tags,
        limit: options.limit ?? 8,
        maxCapsuleBytes: options.maxCapsuleBytes ?? 4096,
    };
}
export function toMemorySearchRequest(request) {
    return {
        query: request.query,
        projectId: request.projectId,
        sessionId: request.sessionId,
        types: request.types,
        filePaths: request.filePaths,
        tags: request.tags,
        limit: request.limit,
    };
}
function recencyScore(createdAt) {
    const timestamp = Date.parse(createdAt);
    if (!Number.isFinite(timestamp))
        return 0;
    const ageDays = Math.max(0, (Date.now() - timestamp) / 86_400_000);
    return Math.max(0, 1 - ageDays / 30);
}
function overlapScore(left, right) {
    if (!left || !right || left.length === 0 || right.length === 0)
        return 0;
    const rightSet = new Set(right);
    return left.filter((value) => rightSet.has(value)).length;
}
export function rankMemorySearchResults(results, request) {
    return results
        .map((result) => {
        const priorityScore = result.event.priority * 2;
        const fileScore = overlapScore(result.event.filePaths, request.filePaths) * 3;
        const tagScore = overlapScore(result.event.tags, request.tags) * 2;
        const typeScore = request.types?.includes(result.event.type) ? 2 : 0;
        const score = result.score + priorityScore + fileScore + tagScore + typeScore + recencyScore(result.event.createdAt);
        return {
            ...result,
            score,
            reason: `${result.reason}; hybrid priority/recency/path/tag ranking`,
        };
    })
        .sort((left, right) => right.score - left.score)
        .slice(0, request.limit);
}
export function createMemoryCitation(event) {
    const files = event.filePaths && event.filePaths.length > 0 ? ` files:${event.filePaths.join(",")}` : "";
    return `memory:${event.id} ${event.type} ${event.createdAt}${files}`;
}
export function parseMemoryCitation(citation) {
    const match = citation.match(/^memory:([^\s]+)(?:\s+([^\s]+))?(?:\s+([^\s]+))?(?:\s+files:(.+))?$/);
    if (!match)
        return undefined;
    const [, id, type, createdAt, files] = match;
    return {
        id,
        type: type,
        createdAt,
        filePaths: files ? files.split(",").filter(Boolean) : [],
    };
}
export function createMemoryCapsules(results, request) {
    const capsules = [];
    let bytes = 0;
    for (const result of rankMemorySearchResults(results, request)) {
        const capsule = {
            id: result.event.id,
            type: result.event.type,
            summary: compactMemoryText(result.event.summary, 320),
            citation: createMemoryCitation(result.event),
            createdAt: result.event.createdAt,
            score: result.score,
            reason: result.reason,
            filePaths: result.event.filePaths,
            tags: result.event.tags,
        };
        const nextBytes = Buffer.byteLength(JSON.stringify(capsule), "utf-8");
        if (bytes + nextBytes > request.maxCapsuleBytes && capsules.length > 0)
            break;
        bytes += nextBytes;
        capsules.push(capsule);
    }
    return capsules;
}
export function getMemoryWhy(capsules, selector) {
    const normalizedSelector = selector?.trim();
    const selected = normalizedSelector
        ? capsules.filter((capsule) => capsule.id === normalizedSelector || capsule.citation === normalizedSelector)
        : capsules;
    return selected.map((capsule) => ({
        citation: capsule.citation,
        summary: capsule.summary,
        reason: capsule.reason,
        score: capsule.score,
        filePaths: capsule.filePaths ?? [],
        tags: capsule.tags ?? [],
    }));
}
export function renderMemoryWhy(results) {
    if (results.length === 0)
        return "No memory citations matched.";
    return [
        "Threadwell memory why:",
        ...results.map((result) => {
            const files = result.filePaths.length > 0 ? `\n  files: ${result.filePaths.join(", ")}` : "";
            const tags = result.tags.length > 0 ? `\n  tags: ${result.tags.join(", ")}` : "";
            return `- [${result.citation}] score=${result.score.toFixed(2)}\n  reason: ${result.reason}\n  summary: ${result.summary}${files}${tags}`;
        }),
    ].join("\n");
}
export function renderMemoryCapsules(capsules) {
    if (capsules.length === 0)
        return undefined;
    return [
        "Relevant Threadwell memory:",
        ...capsules.map((capsule) => `- [${capsule.citation}] ${capsule.summary}`),
    ].join("\n");
}
//# sourceMappingURL=memory-retrieval.js.map