From 4cb14e17cdac0c377a60b8a678416d7b74230ddf Mon Sep 17 00:00:00 2001 From: Pandadadadazxf <2273529713@qq.com> Date: Sat, 14 Mar 2026 08:32:35 +0800 Subject: [PATCH] Compaction: preserve recent-turn suffix when capping summary Include preservedTurnsSection in the reserved suffix so it survives truncation. Truncation keeps the prefix (slice(0, budget)), so the tail is dropped first; the 'preserved recent turns' block was in the body and could disappear on long summaries. Move it into the suffix with diagnostics and workspace rules. Made-with: Cursor --- .../pi-extensions/compaction-safeguard.ts | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/agents/pi-extensions/compaction-safeguard.ts b/src/agents/pi-extensions/compaction-safeguard.ts index 2ad4485844c..838cc1c7a04 100644 --- a/src/agents/pi-extensions/compaction-safeguard.ts +++ b/src/agents/pi-extensions/compaction-safeguard.ts @@ -957,6 +957,7 @@ export default function compactionSafeguardExtension(api: ExtensionAPI): void { const effectivePreviousSummary = droppedSummary ?? preparation.previousSummary; let summary = ""; + let lastSummaryWithoutPreservedTurns = ""; let currentInstructions = structuredInstructions; const totalAttempts = qualityGuardEnabled ? qualityGuardMaxRetries + 1 : 1; let lastSuccessfulSummary: string | null = null; @@ -1021,6 +1022,7 @@ export default function compactionSafeguardExtension(api: ExtensionAPI): void { throw attemptError; } lastSuccessfulSummary = summaryWithPreservedTurns; + lastSummaryWithoutPreservedTurns = summaryWithoutPreservedTurns; const canRegenerate = messagesToSummarize.length > 0 || @@ -1053,21 +1055,26 @@ export default function compactionSafeguardExtension(api: ExtensionAPI): void { : `${structuredInstructions}\n\n${qualityFeedbackInstruction}`; } - // Cap the main history body first, then append diagnostics and workspace rules - // so they survive truncation. Truncation keeps the prefix (slice(0, budget)), - // so sections appended at the end would be dropped first—tool failures and - // file ops are high-signal diagnostics we want to preserve. - const diagnosticSuffix = appendSummarySection( - appendSummarySection("", toolFailureSection), + // Cap the main history body first, then append preserved turns, diagnostics, + // and workspace rules so they survive truncation. Truncation keeps the prefix + // (slice(0, budget)), so sections at the end of the body would be dropped + // first—preserved turns, tool failures, and file ops must be in the suffix. + const reservedSuffix = appendSummarySection( + appendSummarySection(appendSummarySection("", preservedTurnsSection), toolFailureSection), fileOpsSummary, ); const workspaceContext = await readWorkspaceContextForSummary(); - const reservedSuffix = appendSummarySection(diagnosticSuffix, workspaceContext); + const fullReservedSuffix = appendSummarySection(reservedSuffix, workspaceContext); // Ensure leading separator so suffix does not merge with body (e.g. when body // ends without newline from buildStructuredFallbackSummary: "...## Exact identifiers## Tool Failures"). const normalizedSuffix = - reservedSuffix && !/^\s/.test(reservedSuffix) ? `\n\n${reservedSuffix}` : reservedSuffix; - summary = capCompactionSummaryPreservingSuffix(summary, normalizedSuffix); + fullReservedSuffix && !/^\s/.test(fullReservedSuffix) + ? `\n\n${fullReservedSuffix}` + : fullReservedSuffix; + summary = capCompactionSummaryPreservingSuffix( + lastSummaryWithoutPreservedTurns, + normalizedSuffix, + ); return { compaction: {