fix(compact): harden summarization convergence

Use maxTokens as the provider generation cap and remove the confusing stored-summary max config.

Strip reasoning blocks before storing compaction summaries, reject non-shrinking summaries, and retry bounded re-compaction when the surface remains over threshold.

Add config validation for numeric and type-shaped knobs plus unit and real-API e2e coverage for reasoning-capable summarization.
This commit is contained in:
Hypatia May
2026-06-29 16:56:44 +08:00
parent 1f35a4446d
commit 1808570933
8 changed files with 319 additions and 149 deletions

View File

@@ -40,18 +40,17 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('compaction: a long session compa
await writeFile(join(workdir, `file${i}.txt`), `This is file number ${i}. `.repeat(40))
}
// Tiny window so a couple of steps crosses the threshold. The convergence
// invariant requires summarizationMaxTokens + retainTokens to be strictly
// BELOW the threshold = floor(contextWindow * thresholdRatio) =
// floor(2400 * 0.5) = 1200; 600 + 500 = 1100 < 1200. The summary cap
// stays high enough for the live model to emit the required checkpoint
// sections; a truncated checkpoint fails closed and leaves no summary.
// Tiny window so a couple of steps crosses the threshold. The generation
// cap is deliberately larger than the final checkpoint because
// reasoning-capable APIs count reasoning tokens against the provider output
// budget even though those blocks are stripped before the checkpoint is
// stored.
ctx = await codingHarness(workdir, {
compact: {
contextWindow: 2400,
thresholdRatio: 0.5,
retainTokens: 500,
summarizationMaxTokens: 600,
maxTokens: 2048,
},
persistenceRoot: './.sessions',
})