function truncateText(text: string, headChars: number, tailChars: number, label: string): { text: string; truncated: boolean } { if (text.length <= headChars + tailChars) { return { text, truncated: false }; } const head = text.slice(0, Math.max(0, headChars)); const tail = text.slice(Math.max(0, text.length - Math.max(0, tailChars))); return { text: `[${label}: ${text.length} chars, showing first ${head.length} and last ${tail.length}]\n${head}\n\n…\n\n${tail}`, truncated: true, }; } export function truncateOversizedText( text: string, options: { headChars: number; tailChars: number; maxChars: number }, ): { text: string; truncated: boolean } { if (text.length <= options.maxChars) { return { text, truncated: false }; } return truncateText(text, options.headChars, options.tailChars, "message truncated"); } export function compressToolResultText( text: string, options: { headLines: number; tailLines: number; maxChars: number }, ): { text: string; truncated: boolean } { const lines = text.split("\n"); const lineBudget = options.headLines + options.tailLines; if (text.length <= options.maxChars && lines.length <= lineBudget + 1) { return { text, truncated: false }; } if (lines.length > lineBudget + 1) { const head = lines.slice(0, Math.max(0, options.headLines)).join("\n"); const tail = lines.slice(Math.max(0, lines.length - Math.max(0, options.tailLines))).join("\n"); const omitted = Math.max(0, lines.length - options.headLines - options.tailLines); return { text: `[tool result compressed: ${lines.length} lines, ${text.length} chars, omitted ${omitted} middle lines]\n` + head + "\n\n…\n\n" + tail, truncated: true, }; } return truncateText(text, Math.floor(options.maxChars / 3), Math.floor((options.maxChars * 2) / 3), "tool result compressed"); }