Skip to content

feat: configurable auto-compact threshold with Ctrl+L keybinding #1722

@aboimpinto

Description

@aboimpinto

Problem

At ~99.6% context saturation, the TUI becomes completely unresponsive (no keypresses, no UI updates) while the model is mid-turn. The status bar shows Memory 100% and Context 995.8K / 1M tokens, but the TUI event loop is effectively starved.

Root Cause

Two independent guardrails are both disabled by default since v0.8.11:

Layer Setting Default Effect when OFF
Capacity controller [capacity].enabled false No TargetedContextRefresh, no VerifyAndReplan
Compaction subsystem auto_compact false should_compact() returns false unconditionally

With both disabled, the only compaction trigger is the model suggesting /compact in its response — which becomes impossible at ~99.6% context saturation (chicken-and-egg deadlock).

Additionally, the pre-send auto-compact check (should_auto_compact_before_send()) fires at 95% (CONTEXT_CRITICAL_THRESHOLD_PERCENT), which is already in the danger zone where the model struggles to produce tokens. The system prompt tells the model to suggest /compact at 60%, but the engine does nothing automatic at that threshold.

Solution

This PR adds a configurable auto-compact threshold and a manual compaction keybinding, closing the gap between model guidance and engine action.

Changes

  1. New auto_compact_threshold_percent setting (default 70%)

    • Configurable via config.toml or /set auto_compact_threshold 70 --save
    • Validated to range 10–100
    • Respects the existing 500K-token hard floor (MINIMUM_AUTO_COMPACTION_TOKENS) so small sessions are never auto-compacted
  2. should_auto_compact_before_send() now uses the configurable threshold

    • Was: hardcoded to 95% (CONTEXT_CRITICAL_THRESHOLD_PERCENT)
    • Now: uses app.auto_compact_threshold_pct (default 70%) + checks 500K floor
    • Compaction fires before the danger zone, while the model is still responsive
  3. Early context-pressure warning at 60%

    • New CONTEXT_SUGGEST_COMPACT_THRESHOLD_PERCENT = 60.0
    • Non-intrusive status message: "Context building: 60% — Consider enabling auto_compact or use /compact."
    • Only shows when status_message is empty (never stomps on more important messages)
  4. Ctrl+L keybinding for manual compaction

    • Works even when the model is mid-turn (streaming)
    • Breaks the chicken-and-egg deadlock: user can compact without model assistance
    • Status: "Compacting context (Ctrl+L)..."
  5. Updated system prompt guidance

    • Model now knows about auto-compact threshold and Ctrl+L
    • "If auto_compact is enabled, the engine will automatically compact before the next send when context crosses the configured threshold (default 70%). The user can also press Ctrl+L at any time."

Files Changed

File Lines Description
crates/tui/src/settings.rs +25 New field, default, set handler with validation, help text
crates/tui/src/tui/app.rs +3 auto_compact_threshold_pct field + wiring from settings
crates/tui/src/tui/ui.rs +49 Constants, maybe_warn_context_pressure() early warning, should_auto_compact_before_send() configurable threshold, Ctrl+L keybinding
crates/tui/src/prompts.rs +1/-1 System prompt updates

Configuration

# ~/.deepseek/config.toml
auto_compact = true                     # master switch (still defaults to false)
auto_compact_threshold_percent = 70     # fires at 70% (NEW — default 70)

Or in-session:

/set auto_compact true --save
/set auto_compact_threshold 70 --save

Behavior Flow

Context % auto_compact=true auto_compact=false
60% Status: "Auto-compaction will fire before next send." Status: "Consider enabling auto_compact or use /compact."
70% Engine compacts before next send (if >500K tokens) Status: same 60% message
85% Status: "Context high — Auto-compaction is enabled." Status: "Context high — Consider /compact or /clear."
95% Status: "Context critical" (already compacted at 70%) Status: "Context critical — Consider /compact or /clear."
Any Ctrl+L → manual compaction Ctrl+L → manual compaction

Backward Compatibility

  • auto_compact still defaults to false — existing users see no change
  • auto_compact_threshold_percent defaults to 70.0 — only active when auto_compact = true
  • 500K hard floor unchanged — protects small/medium sessions from unnecessary cache destruction
  • Existing /compact slash command unchanged

Related

  • Closes the gap identified in the context-pressure UI freeze analysis
  • Complements the v0.8.11 decision to disable auto-compact by default (Context-limit handoff as a default replacement for routine compaction #664) by making it safer to re-enable
  • V4 prefix-cache economics preserved: 500K floor + 70% default threshold ensures compaction only fires when cache is already pressured

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions