"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.SUMMARIZATION_SYSTEM_PROMPT = void 0;exports.computeFileLists = computeFileLists;exports.createFileOps = createFileOps;exports.extractFileOpsFromMessage = extractFileOpsFromMessage;exports.formatFileOperations = formatFileOperations;exports.serializeConversation = serializeConversation; /** * Shared utilities for compaction and branch summarization. */ function createFileOps() { return { read: new Set(), written: new Set(), edited: new Set() }; } /** * Extract file operations from tool calls in an assistant message. */ function extractFileOpsFromMessage(message, fileOps) { if (message.role !== "assistant") return; if (!("content" in message) || !Array.isArray(message.content)) return; for (const block of message.content) { if (typeof block !== "object" || block === null) continue; if (!("type" in block) || block.type !== "toolCall") continue; if (!("arguments" in block) || !("name" in block)) continue; const args = block.arguments; if (!args) continue; const path = typeof args.path === "string" ? args.path : undefined; if (!path) continue; switch (block.name) { case "read": fileOps.read.add(path); break; case "write": fileOps.written.add(path); break; case "edit": fileOps.edited.add(path); break; } } } /** * Compute final file lists from file operations. * Returns readFiles (files only read, not modified) and modifiedFiles. */ function computeFileLists(fileOps) { const modified = new Set([...fileOps.edited, ...fileOps.written]); const readOnly = [...fileOps.read].filter((f) => !modified.has(f)).sort(); const modifiedFiles = [...modified].sort(); return { readFiles: readOnly, modifiedFiles }; } /** * Format file operations as XML tags for summary. */ function formatFileOperations(readFiles, modifiedFiles) { const sections = []; if (readFiles.length > 0) { sections.push(`\n${readFiles.join("\n")}\n`); } if (modifiedFiles.length > 0) { sections.push(`\n${modifiedFiles.join("\n")}\n`); } if (sections.length === 0) return ""; return `\n\n${sections.join("\n\n")}`; } // ============================================================================ // Message Serialization // ============================================================================ /** Maximum characters for a tool result in serialized summaries. */ const TOOL_RESULT_MAX_CHARS = 2000; /** * Truncate text to a maximum character length for summarization. * Keeps the beginning and appends a truncation marker. */ function truncateForSummary(text, maxChars) { if (text.length <= maxChars) return text; const truncatedChars = text.length - maxChars; return `${text.slice(0, maxChars)}\n\n[... ${truncatedChars} more characters truncated]`; } /** * Serialize LLM messages to text for summarization. * This prevents the model from treating it as a conversation to continue. * Call convertToLlm() first to handle custom message types. * * Tool results are truncated to keep the summarization request within * reasonable token budgets. Full content is not needed for summarization. */ function serializeConversation(messages) { const parts = []; for (const msg of messages) { if (msg.role === "user") { const content = typeof msg.content === "string" ? msg.content : msg.content. filter((c) => c.type === "text"). map((c) => c.text). join(""); if (content) parts.push(`[User]: ${content}`); } else if (msg.role === "assistant") { const textParts = []; const thinkingParts = []; const toolCalls = []; for (const block of msg.content) { if (block.type === "text") { textParts.push(block.text); } else if (block.type === "thinking") { thinkingParts.push(block.thinking); } else if (block.type === "toolCall") { const args = block.arguments; const argsStr = Object.entries(args). map(([k, v]) => `${k}=${JSON.stringify(v)}`). join(", "); toolCalls.push(`${block.name}(${argsStr})`); } } if (thinkingParts.length > 0) { parts.push(`[Assistant thinking]: ${thinkingParts.join("\n")}`); } if (textParts.length > 0) { parts.push(`[Assistant]: ${textParts.join("\n")}`); } if (toolCalls.length > 0) { parts.push(`[Assistant tool calls]: ${toolCalls.join("; ")}`); } } else if (msg.role === "toolResult") { const content = msg.content. filter((c) => c.type === "text"). map((c) => c.text). join(""); if (content) { parts.push(`[Tool result]: ${truncateForSummary(content, TOOL_RESULT_MAX_CHARS)}`); } } } return parts.join("\n\n"); } // ============================================================================ // Summarization System Prompt // ============================================================================ const SUMMARIZATION_SYSTEM_PROMPT = exports.SUMMARIZATION_SYSTEM_PROMPT = `You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified. Do NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.`; /* v9-fc874a30f36fe2fd */