How to Configure Context Compaction Strategies in Forge
Forge provides a pluggable compaction system via the ContextManager class in src/forge/context/manager.py, which delegates token-budget enforcement to strategy objects like NoCompact, SlidingWindowCompact, or TieredCompact defined in src/forge/context/strategies.py.
The antoinezambelli/forge repository implements a sophisticated context management system to prevent LLM prompts from exceeding token limits. Understanding how to configure context compaction strategies in Forge allows you to optimize memory usage while preserving critical conversation history across long-running workflows.
Understanding Forge's Context Management Architecture
Forge separates budgeting logic from compaction algorithms. The ContextManager maintains the token budget and monitors usage, while a CompactStrategy implementation handles the actual message reduction when thresholds are breached.
The ContextManager Core
The ContextManager class in src/forge/context/manager.py orchestrates the compaction lifecycle. It tracks the budget_tokens limit and uses estimate_tokens—which relies on either a cached token count from the LLM backend or a character-count heuristic—to monitor prompt size. When maybe_compact is triggered, the manager delegates to the configured strategy. If compaction occurs (phase index > 0), the manager instantiates a CompactEvent (defined in lines 12-22 of manager.py) and fires the optional on_compact callback for logging or UI feedback.
The CompactStrategy Interface
All strategies inherit from the base class in src/forge/context/strategies.py and implement the compact(messages, budget, ...) method. This method returns a tuple containing the compacted message list and a phase index where 0 indicates no compaction occurred and 1-3 represent increasingly aggressive compaction phases. This design allows you to swap or extend strategies without modifying the manager's token-budgeting logic.
Built-in Context Compaction Strategies
Forge ships with three production-ready strategies in src/forge/context/strategies.py, each optimized for different memory constraints and workflow patterns.
NoCompact for Unrestricted Workflows
Use NoCompact for very small or short-lived workflows, or when running on hardware with abundant VRAM (≥ 32 GB). This strategy accepts no parameters and returns the message history unchanged, effectively disabling compaction.
from forge.context.manager import ContextManager
from forge.context.strategies import NoCompact
ctx = ContextManager(
strategy=NoCompact(),
budget_tokens=12_000, # typical 8 K-token LLM budget
)
SlidingWindowCompact for Predictable Truncation
SlidingWindowCompact provides simple, predictable truncation that preserves the system prompt, the original user request, and the last N iterations of conversation. It accepts two core parameters:
keep_recent(int): Specifies how many recent loop iterations to retain untouched.compact_threshold(float): The fraction of the token budget that triggers compaction (default 0.75).
from forge.context.strategies import SlidingWindowCompact
# Keep the last 3 iterations fully intact; start compacting at 75 % of the budget
strategy = SlidingWindowCompact(keep_recent=3, compact_threshold=0.75)
ctx = ContextManager(strategy=strategy, budget_tokens=12_000)
TieredCompact for Aggressive Memory Management
TieredCompact implements a three-phase compaction algorithm designed for aggressive memory conservation. The strategy progressively discards information: first removing nudges and truncating tool results, then dropping tool results entirely, and finally keeping only tool-call skeletons. Configuration parameters include:
keep_recent(int, default 2): Recent iterations to preserve.compact_threshold(float): Fallback threshold ifphase_thresholdsis omitted.phase_thresholds(tuple[float, float, float]): Per-phase trigger fractions (e.g.,(0.60, 0.75, 0.90)).
from forge.context.strategies import TieredCompact
# Keep 2 recent iterations; shrink aggressively as the budget fills:
# Phase 1 @ 60 % → drop nudges / truncate tool results (≈200 chars)
# Phase 2 @ 75 % → drop tool results entirely
# Phase 3 @ 90 % → keep only tool-call skeletons
strategy = TieredCompact(
keep_recent=2,
phase_thresholds=(0.60, 0.75, 0.90)
)
ctx = ContextManager(strategy=strategy, budget_tokens=12_000)
Configuring Compaction Callbacks and Monitoring
The ContextManager accepts optional callback hooks for observability. The on_compact parameter receives a CompactEvent object containing phase_reached, tokens_before, tokens_after, messages_before, and messages_after. You can also supply on_context_threshold to inject warning strings before inference calls when check_thresholds is enabled.
def log_compaction(event):
print(
f"Compaction (phase {event.phase_reached}) "
f"reduced tokens {event.tokens_before}->{event.tokens_after} "
f"and messages {event.messages_before}->{event.messages_after}"
)
ctx = ContextManager(
strategy=TieredCompact(),
budget_tokens=12_000,
on_compact=log_compaction,
)
Integrating with Workflow Runners
In production deployments, you typically inject the configured ContextManager into a WorkflowRunner. The WorkflowRunner class in src/forge/core/runner.py automatically invokes ctx_manager.maybe_compact(...) during the execution loop, ensuring context limits are enforced without manual intervention.
from forge.core.runner import WorkflowRunner
from forge.context.strategies import TieredCompact
strategy = TieredCompact(keep_recent=4)
ctx_manager = ContextManager(strategy=strategy, budget_tokens=16_000)
runner = WorkflowRunner(context_manager=ctx_manager)
runner.run(workflow) # the runner will call ctx_manager.maybe_compact(...)
Server-side implementations in src/forge/server.py and proxy scenarios in src/forge/proxy/proxy.py demonstrate additional patterns for instantiating a fresh ContextManager per request or session.
Summary
- Three strategies control how Forge manages token budgets:
NoCompact,SlidingWindowCompact, andTieredCompact. - Configuration occurs through the
ContextManagerconstructor, passing the strategy instance and abudget_tokensinteger. - TieredCompact offers granular control via
phase_thresholds, triggering three distinct compaction phases at specified budget percentages. - Monitoring is implemented via the
on_compactcallback, which receives aCompactEventdetailing the compaction impact. - Integration requires passing the configured manager to
WorkflowRunneror using it directly in custom inference loops.
Frequently Asked Questions
What is the default compaction threshold in Forge?
The default compact_threshold is 0.75 (75% of the token budget) for both SlidingWindowCompact and TieredCompact. However, TieredCompact can override this with per-phase thresholds via the phase_thresholds parameter, allowing Phase 1 to trigger at 60%, Phase 2 at 75%, and Phase 3 at 90%.
When should I use TieredCompact versus SlidingWindowCompact?
Use SlidingWindowCompact for simple, predictable workflows where you only need to truncate older iterations while keeping the system prompt and recent history intact. Choose TieredCompact for complex, long-running agents that generate tool results and reasoning chains, as its three-phase approach aggressively preserves the most critical information while shedding auxiliary data like nudges and detailed tool outputs.
How do I implement a custom compaction strategy?
Subclass the CompactStrategy base class from src/forge/context/strategies.py and implement the compact(messages, budget, **kwargs) method. Your implementation must return a tuple of (compacted_messages, phase_index), where phase_index is 0 for no compaction or 1-3 indicating the severity of reduction performed. Pass your custom instance to ContextManager(strategy=YourStrategy()).
Where is the token estimation logic implemented?
The ContextManager.estimate_tokens method in src/forge/context/manager.py handles token counting. It uses either a cached token count updated from the LLM backend or falls back to a simple character-count divided by four heuristic when cached counts are unavailable.
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 →