Include Luna AI Assistant design docs covering channels, configuration, core architecture, memory, scheduler, and skills. Add reference docs from OpenClaw and ZeroClaw projects, plus Mistral and OpenAI API specs.
7.9 KiB
Compaction Strategy
OpenClaw employs a multi-layered conversation compaction system to manage long-running sessions within finite model context windows. Unlike basic truncation, this system uses LLM-driven summarization, token-budget gating, and quality safeguards to preserve critical state, identifiers, and recent context.
Trigger & Token Gating
Compaction is primarily triggered by "preflight" checks before processing a new turn, ensuring the model has sufficient headroom for its next response. This process is managed in auto-reply/reply/agent-runner-memory.ts and memory-flush.ts.
Gating Logic
The decision to compact is based on a projected token count compared against a computed threshold:
- Threshold Formula:
contextWindowTokens - reserveTokensFloor - softThresholdTokens - Reserve Floor: Defaults to 20,000 tokens (
reserveTokensFloor), providing a safety buffer for tool outputs and reasoning. - Soft Threshold: An additional 4,000 token buffer (
softThresholdTokens) to prevent compaction oscillations at the exact limit. - Token Estimation: Performed by
estimateMessagesTokens(), which stripstoolResult.detailsfor security and applies aSAFETY_MARGINof 1.2 to account for estimation inaccuracies.
Execution Hooks
- shouldRunPreflightCompaction: Runs before a turn to ensure the input fits the budget.
- shouldRunMemoryFlush: Evaluates if the session should be "flushed" to long-term memory based on token pressure.
- Deduplication:
hasAlreadyFlushedForCurrentCompactionprevents redundant flushes within a single compaction cycle. - Manual Trigger: The
/compactcommand allows users to manually force a compaction cycle.
Summarization Core
The core summarization engine in agents/compaction.ts orchestrates the transformation of raw history into structured summaries.
Resource Allocation
- SUMMARIZATION_OVERHEAD_TOKENS: 4,096 tokens are reserved for the summarization prompt, system instructions, and previous summaries.
- Adaptive Chunking:
computeAdaptiveChunkRatioshrinks chunk sizes as the average message size increases. If a single message exceeds 50% of the context window, it is flagged asisOversizedForSummaryand handled via fallback mechanisms.
Orchestration Pipeline
- summarizeChunks: Splits the history into chunks based on
maxChunkTokens. - summarizeWithFallback: Attempts a full summary. On failure, it separates "small" messages from "oversized" ones, summarizing the small messages and annotating the oversized ones (e.g.,
[Large message (~15K tokens) omitted from summary]). - summarizeInStages: For very large histories, it generates partial summaries and then merges them using
MERGE_SUMMARIES_INSTRUCTIONS.
Preservation Priorities
The system uses MERGE_SUMMARIES_INSTRUCTIONS to ensure the model retains:
- Active tasks and current status (in-progress, blocked, pending).
- Commitments, decisions, and their rationale.
- Unresolved user asks and key factual identifiers.
- Recent context over older history.
Safeguard Extension
The compaction-safeguard.ts hook acts as a safety layer, registering on session_before_compact to manage context sharing and content preservation.
Context Preservation
- Recent Turns: Preserves
DEFAULT_RECENT_TURNS_PRESERVE = 3turns verbatim to maintain immediate conversational flow. - History Pruning:
pruneHistoryForContextSharedrops older chunks if the new content consumes too much of the history budget. Dropped messages are summarized and prepended as apreviousSummary. - Suffix Protection: Critical metadata is appended to a protected suffix that survives truncation:
- Tool failures (capped at 8 failures).
- File operations (read/modified lists).
- Workspace rules (extracted from
AGENTS.md).
Length Constraints
- MAX_COMPACTION_SUMMARY_CHARS: 16,000 characters cap for the total summary.
- MAX_FILE_OPS_SECTION_CHARS: 2,000 characters for file operation logs.
- MAX_FILE_OPS_LIST_CHARS: 900 characters for the list of files.
Quality Guard
The Quality Guard (compaction-safeguard-quality.ts) ensures the LLM-generated summary meets strict structural and content requirements.
Required Sections
Every summary must contain these exact Markdown headings:
## Decisions## Open TODOs## Constraints/Rules## Pending user asks## Exact identifiers
Identifier Preservation
The system extracts opaque identifiers (URLs, file paths, hex IDs, ports) using regex and enforces their preservation.
- Strict Policy: If
identifierPolicyis set tostrict, the guard validates that all extracted identifiers appear in the final summary. - Audit Loop:
auditSummaryQualitychecks for section presence and identifier integrity. If checks fail, the system triggers a regeneration withqualityFeedbackInstruction.
Default Instructions
Default behavior is governed by compaction-instructions.ts, which merges user-defined, runtime, and system-level instructions.
export const DEFAULT_COMPACTION_INSTRUCTIONS =
"Write the summary body in the primary language used in the conversation.\n" +
"Focus on factual content: what was discussed, decisions made, and current state.\n" +
"Keep the required summary structure and section headers unchanged.\n" +
"Do not translate or alter code, file paths, identifiers, or error messages.";
Instructions are capped at MAX_INSTRUCTION_LENGTH = 800 characters to prevent prompt bloat.
Runtime Execution & Truncation
The compact.ts runner provides the entry point for both automated and manual compaction.
Execution Flow
- Preparation: Opens the session, sanitizes history, and runs
before_compactionhooks. - Safety Timeout: Wraps the LLM call in
compactWithSafetyTimeoutto prevent hanging processes. - Post-Processing: Runs
after_compactionhooks and estimates the resulting token count.
Session Truncation
If enabled via config.agents.defaults.compaction.truncateAfterCompaction, the system physically rewrites the session JSONL file using session-truncation.ts.
- Removal: Deletes message entries that were summarized.
- Re-parenting: Re-parents orphaned entries to the nearest kept ancestor to maintain the integrity of the session tree.
- Archiving: Optionally creates an archive of the original session file before truncation.
Configuration Knobs
Compaction behavior can be tuned via OpenClawConfig:
config.agents.defaults.compaction.model: Override the model used for summarization.config.agents.defaults.compaction.reserveTokensFloor: Minimum buffer (default ~20,000).config.agents.defaults.compaction.timeoutSeconds: Max time allowed for a summarization call.config.agents.defaults.compaction.truncateAfterCompaction: Boolean to enable physical file cleanup.memoryFlush: Configuration for soft thresholds and forced flush triggers.
Relevance to Luna
Luna currently uses a basic LibrarianAgent for compaction with no token-budget gating, no quality guards, and no structured instruction sets. To achieve OpenClaw-level reliability, Luna should adopt:
- Token-Budget Gating: Triggering compaction based on projected context usage rather than arbitrary turn counts.
- Structured Sections: Enforcing a specific Markdown schema in summaries to ensure critical state is never lost.
- Identifier Preservation: Using regex extraction and quality audits to protect file paths and IDs.
- Quality Audit Loop: Implementing a verification step that can re-trigger summarization if requirements are missed.
- Session Truncation: Physically cleaning up on-disk history files to prevent unbounded growth.
Patterns like the compaction-safeguard provide a more resilient approach for long-term project management in Luna by ensuring the project state, goals, and critical constraints are always prioritized in the model's working memory.
See also: Core, Configuration, Session Management