LLM Compaction in Apache Maka: How It Manages Context Windows Without Losing History
LLM Compaction in Maka is a projection mechanism that creates compressed checkpoints of chat history when the Runtime Events Log exceeds the model's context window, replacing old events with a lossy summary while keeping the original log immutable for auditability.
When building long-running AI sessions, every conversation, tool call, and diagnostic output gets appended to Maka's Runtime Events Log. As this log grows, it eventually bumps against the model's token limit. Rather than deleting or truncating history, Maka implements LLM Compaction—a deterministic, auditable compression system that projects a smaller, semantically coherent view to the model while preserving every original event for debugging and replay.
What Is LLM Compaction
LLM Compaction is the process of folding a prefix of the Runtime Events Log into a compact checkpoint that can substitute for the original events in subsequent model requests. The checkpoint contains either a text summary generated by an LLM or a provider-native compact state (like OpenAI Codex's remote compaction). The key insight: this is a projection, not a mutation. The original events remain untouched; only what the model sees changes.
This design serves three goals:
- Bounded context: The model never receives more tokens than its window allows
- Auditability: Every event remains available for replay and debugging
- Fail-open safety: If compaction fails, the system falls back to the full log
Core Architecture Components
Maka's compaction system spans several modules in packages/runtime/src/. Here's how the pieces fit together.
Runtime Events Log
The Runtime Events Log is the canonical, append-only source of truth for all session activity—user messages, model completions, tool calls and results, and internal diagnostics. It lives implicitly across the runtime but is manipulated through the APIs in runtime-event.ts.
Safe Prefix Selection
Before any summarization happens, selectSafeCompactionPrefix in history-compaction.ts determines which contiguous prefix can be safely folded. This calculation respects:
reserveTailEvents: Keeps recent events untouchedisPinnedflags: Prevents certain events from being compacted- Tool call/result pairs: Never splits a pending tool operation
If no safe prefix exists, the compaction aborts with fail-open semantics—the original log proceeds to the model unchanged.
Compaction Policy
When should compaction trigger? context-budget-policy.ts implements the Compaction Policy that watches for:
- Manual requests (
sessions:compactcommand) - Pre-turn capacity breaches
- Active-turn overflow during generation
- Provider-side context-length rejections
Summarizer
The Summarizer (history-compact-summarizer.ts) transforms the selected prefix into a compact representation. Two modes exist:
| Mode | Implementation | Output |
|---|---|---|
| Text-based LLM | Default defaultSummarizer |
Plain text summary |
| Provider-native | openai-codex-history-compactor.ts |
openai.compaction part |
HistoryCompactCheckpoint
A HistoryCompactCheckpoint (history-compact-checkpoint.ts) is the durable artifact created by compaction. It stores:
- Coverage metadata: Event count, SHA-256 digest of covered events, boundary ID
- Compacted content: Text summary or provider-native state
- Lineage: Optional
previousCheckpointIdfor checkpoint chains
Projection and Replay
When building the next provider request, ai-sdk-backend.ts runs the prior-messages pipeline:
- Load the latest compatible checkpoint
- Validate its
sourceDigestagainst the immutable log - Materialize either a synthetic text checkpoint event or inject the provider-native state
- Append the raw tail events (events newer than the checkpoint coverage)
The model receives this projected view seamlessly.
How LLM Compaction Works: Step by Step
The compaction flow in history-compaction.ts follows seven deterministic stages:
-
Trigger detection — A
Compactcommand arrives from policy or user action. No events are modified. -
Safe-prefix calculation —
selectSafeCompactionPrefixscans the ordered events, respecting constraints. Returns a boundary or fails open. -
Summarization — The prefix (plus any newly folded events) passes to the configured
HistoryCompactionSummarizer. -
Checkpoint construction —
buildHistoryCompactCheckpointassembles theHistoryCompactCheckpointwith metadata, content, and lineage. -
Durable write — The checkpoint persists atomically alongside an
AgentRunEventof typehistory_compact_checkpoint_recorded. -
Projection for next request — The prior-messages pipeline validates and materializes the checkpoint, combining it with tail events.
-
Auditability and replay — Original events remain immutable. Debuggers can replay the full log; future compactions can fold further.
Every step through checkpoint construction is pure and side-effect-free. The runtime—not the LLM—retains authority over what gets projected, when it's used, and how it's validated.
Working with LLM Compaction: Code Examples
Manual Compaction from the Desktop Client
Trigger compaction programmatically via RuntimeKernel.compactSession:
import { RuntimeKernel } from '@maka/runtime';
await RuntimeKernel.compactSession({
sessionId: 'abcd-1234',
phase: 'standalone', // Manual fold, not mid-turn
orderedEvents: runtimeEvents, // Full ordered RuntimeEvent array
summarize: async ({ coveredRuntimeEvents }) => {
// Use default LLM text summarizer
return await defaultSummarizer(coveredRuntimeEvents);
},
});
This delegates to planHistoryCompaction in history-compaction.ts, which orchestrates prefix selection, summarization, and checkpoint persistence.
Programmatic Compaction in Custom Backends
For finer control, call planHistoryCompaction directly:
import { planHistoryCompaction } from '@maka/runtime';
import { defaultSummarizer } from '@maka/runtime/ai-sdk-compaction';
const result = await planHistoryCompaction({
sessionId: 'sess-001',
phase: 'mid_turn',
orderedEvents,
headAnchor: { runtimeEventId: curEvent.id, turnId: curEvent.turnId },
reserveTailEvents: 1,
summarize: defaultSummarizer,
});
if (result.decision === 'compacted') {
console.log('New checkpoint:', result.checkpoint.checkpointId);
console.log('Token reduction:', result.tokensBefore - result.tokensAfter);
}
The result reports the checkpoint, replacement events, and token estimates.
Inspecting Checkpoint Projections
Debug what the model will actually see:
import { applyRuntimeEventHistoryCompact } from '@maka/runtime';
const replay = applyRuntimeEventHistoryCompact(
runtimeEvents,
{ enabled: true, checkpoint: latestCheckpoint },
);
console.log('Effective events count:', replay.events.length);
console.log('First projected event:', replay.events[0]?.type);
applyRuntimeEventHistoryCompact validates the checkpoint's sourceDigest against the log before returning the projected list.
Key Source Files
| File | Purpose |
|---|---|
packages/runtime/src/history-compaction.ts |
Safe-prefix selection, planning logic, fail-open handling |
packages/runtime/src/history-compact-checkpoint.ts |
Checkpoint schema, coverage validation, replay materialization |
packages/runtime/src/history-compact-summarizer.ts |
Default LLM summarizer, prompt templates, repair logic |
packages/runtime/src/openai-codex-history-compactor.ts |
Provider-native compaction for OpenAI Codex |
packages/runtime/src/ai-sdk-backend.ts |
Prior-messages pipeline, checkpoint loading, request building |
packages/runtime/src/context-budget-policy.ts |
Trigger conditions, capacity management, policy defaults |
packages/runtime/src/runtime-kernel.ts |
Public compactSession API |
For the architectural narrative, see docs/architecture/llm-compaction-events-log-projection-draft.md.
Summary
- LLM Compaction in Maka creates lossy, auditable checkpoints that project compressed history to models without destroying the original log
- The Runtime Events Log remains immutable; only the view sent to the model changes
history-compaction.tsimplements safe-prefix selection with fail-open semantics- Checkpoints carry SHA-256 digests (
sourceDigest) enabling validation and replay - Two summarizer modes: text-based LLM prompts and provider-native compaction
- The system is pure until durable write, with the runtime—not the LLM—controlling all authority
Frequently Asked Questions
What triggers LLM Compaction in Maka?
Compaction triggers from four sources, all configured in context-budget-policy.ts: manual commands like sessions:compact, pre-turn capacity checks that estimate token counts before generation, active-turn overflow when generation exceeds the context window, and provider-side rejections for context-length violations. The trigger itself never modifies events—it only emits a Compact command for the planner.
Does LLM Compaction delete or lose my conversation history?
No. History is never deleted. The original Runtime Events Log stays append-only and immutable. Compaction creates a projection—a derived view that substitutes a checkpoint for old events only in what the model sees. Debuggers and future operations can always replay the complete log using applyRuntimeEventHistoryCompact or direct event inspection.
What happens if the summarizer fails during compaction?
The system fails open. If summarization throws, checkpoint validation fails, or the durable write doesn't complete, history-compaction.ts abandons the compaction attempt. The original ordered events proceed to the model unchanged. This guarantees that a buggy summarizer or transient error won't break session continuity.
Can I use provider-native compaction instead of LLM summarization?
Yes. Maka supports pluggable summarizers. The default defaultSummarizer in history-compact-summarizer.ts uses text prompts, but openai-codex-history-compactor.ts implements provider-native compaction that produces openai.compaction parts. Configure your summarizer in the compactSession or planHistoryCompaction call's summarize parameter.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →