Home / Docs / Compaction Ladder

Compaction Ladder

Bound long agent runs without corrupting history

FabrCore v1.7.1 separates what a model sees during one call from what the application stores between turns. The result is a five-rung ladder ordered from cheap and reversible to permanent and protective.

0.50  layer 1  evict old tool results       free, reversible
0.80  layer 1  truncate oldest groups       free, reversible
0.87  layer 2  summarize persisted history  one LLM call, permanent
0.90  fuse     clip the read projection      last-resort insurance
1.00  stop     reject an oversized run       FabrCoreRunStoppedException

Two layers, two responsibilities

Layer 1: context compactionLayer 2: history compaction
RunsBefore every model call, including tool loopsBefore or after a turn
BoundsThe messages sent to this LLM callThe persisted MessageThreads record
ReversibleYes; messages are excluded from the request projectionNo; history is summarized and rewritten
LLM costNoneOne or more summarization calls
CustomizationCompactionStrategyOverride OnCompaction
Layer 1 does not persist its group index.

Persisting that index would duplicate the conversation and let a stale projection survive a layer-two rewrite. The deterministic index is rebuilt on activation.

Model configuration

For most deployments, set the model window and output reserve. FabrCore derives the input budget and orders the remaining rungs.

{
  "Name": "default",
  "Provider": "OpenAI",
  "Model": "gpt-5",
  "ApiKeyAlias": "openai",
  "ContextWindowTokens": 200000,
  "MaxOutputTokens": 16000,
  "ContextCompactionEnabled": true,
  "ContextEvictThreshold": 0.50,
  "ContextTruncateThreshold": 0.80,
  "CompactionEnabled": true,
  "CompactionThreshold": 0.87,
  "PerTurnMaxInputTokens": 400000,
  "MaxPromptInputTokens": 200000
}
FieldDefaultPurpose
ContextWindowTokensUnsetAnchor for every ladder rung.
MaxOutputTokensUnsetOutput reserve; layer 1 requires both values.
ContextCompactionEnabledtrueEnable reversible in-run compaction.
ContextEvictThreshold0.50Collapse old tool results.
ContextTruncateThreshold0.80Drop the oldest request groups.
CompactionEnabledtrueEnable persisted history consolidation.
CompactionThreshold0.87 with layer 1; 0.75 withoutStored-token threshold for history compaction.
CompactionKeepLastN20Recent messages retained verbatim.
CompactionStaleAfterMinutes60Preflight a dormant, over-threshold thread.

Agent-level overrides

Blueprint args can override individual rungs for one agent. Keys are case-sensitive.

"args": {
  "_ContextCompactionEnabled": "true",
  "_ContextEvictThreshold": "0.55",
  "_ContextTruncateThreshold": "0.82",
  "_CompactionThreshold": "0.88",
  "_PerTurnMaxInputTokens": "300000"
}

Diagnostics and monitoring

Every agent logs its resolved ladder once during compaction initialization. context:unconfigured means ContextWindowTokens or MaxOutputTokens is missing and no in-run context bound can be composed. [OUT OF ORDER] means a later rung would fire before an earlier one.

  • Layer 1 emits OpenTelemetry spans through compaction telemetry.
  • Layer 2 emits compaction.history.started, completed, and failed monitor events.
  • History events include a preflight or post-turn trigger.
  • Stored history may contain [Compacted History]; a model request may additionally contain transient [Tool Calls] and [Summary] messages.

Migration from mid-turn history compaction

MidTurnCompactionEnabled is retired.

The property remains deserializable, but it is obsolete and ignored. Replace it with ContextCompactionEnabled. FabrCoreRunStoppedException.CheckpointCount and the _fabrcore_checkpoint_count diagnostic were also removed.

Run safety now has one job: stop over-budget work. It no longer mutates persisted history while a tool loop is active.

Documentation