Skip to content
Cavemandocs
MIT

Compaction

A fail-closed ladder: recover, summarise, clamp, then stop. Only inside a declared budget.

Compaction runs only inside a declared token or USD budget. It is not a background summariser that fires because the context "looks large". The runtime applies a fail-closed ladder, then stops.

1 · Exact-recovery eviction. Drop what can be fetched back byte for byte.
↓ still over budget
2 · Typed summary. Replace eligible history with a cave.context-summary.v2 capsule.
↓ still over budget
3 · Output clamp. Bound what the model may still emit.
↓ still over budget
4 · Stop. The run ends. The receipt keeps every call that already happened.

Ember is the last exit. Nothing after stop invents a cheaper context.

typescript
import { run, type RunBudget } from "@caveman-ai/agent";

const budget: RunBudget = {
maxTokens: 120_000,
onExhausted: "compact",
compaction: {
keepRecentTokens: 8_000,
summaryMaxTokens: 2_048,
preserveFirstUserMessage: true,
},
};

const result = await run(support, "Continue investigation.", { budget });

onExhausted: "stop" skips the compact rungs and ends the run at the cap.

Capsule rules#

The public API lives at @caveman-ai/agent/compaction.

typescript
import {
parseContextSummary,
summarizationInstruction,
validateContextSummaryTransition,
} from "@caveman-ai/agent/compaction";

A replacement is accepted only when all of these hold:

  • the schema parses
  • generation increments by exactly one
  • required user sources are covered, with matching source IDs and SHA-256 digests
  • every prior critical anchor survives byte-identically, unless a later current user source grounds a new critical anchor with an explicit supersedes edge
  • root user intent and a self-contained recent tail remain verbatim
  • the rewritten context is smaller
  • tool content cannot mint critical policy

One paid summary is the default. Structural support for repeated compaction is tested. A higher default is not shipped without repeated live-model semantic evidence, and that evidence is not claimed here.

Harness#

typescript
import {
runContextCompactionHarness,
type ContextCompactionSummarizer,
} from "@caveman-ai/agent/compaction";

const summarize: ContextCompactionSummarizer = async (request) => {
return explicitClient.complete({
messages: [
...request.messages,
{ role: "user", content: request.instruction },
],
maxTokens: 2_048,
});
};

const report = await runContextCompactionHarness(fixture, summarize, {
repetitions: 20,
});
if (!report.stable) throw new Error(report.failures.join("\n"));

The harness owns fixtures and validation. The adapter owns the model and transport, with explicit credentials. Test code does not inherit ambient secrets. The public harness measures transition validity, anchor recall, exact-recovery coverage, and compression ratio. Structural stability is tested. Semantic superiority is not claimed.

Compaction events land on the run receipt with the rest of the spend.

What it will not do#

Compaction is not a quality improvement. A smaller context that dropped a commitment is a failed transition, not a savings. Ratios from the harness are local, inferred, per run. They are not monthly figures and not verified.