Skip to main content

Dynamic Context Pruning (DCP)

Mid-session reduction of the context payload sent to the LLM, performed without modifying the underlying session history. Where compaction summarizes everything at a hard threshold, DCP runs as a combination of model-driven compression and automatic cleanup strategies that fire on each LLM fetch — pruned spans are replaced with placeholders before the request is dispatched. Reference implementation: opencode-dcp — the @tarquinen/opencode-dcp plugin for OpenCode. Install:

The Problem It Solves

Long coding sessions accumulate three classes of dead weight in the active context:
  • Repeated tool calls (same tool, same args invoked across turns)
  • Errored tool inputs whose large input payload is no longer relevant once the error has been read
  • Closed/finished spans of conversation that the model no longer needs verbatim
These dilute attention and inflate per-request cost without contributing signal. DCP attacks each class with a different mechanism rather than waiting for full compaction.

Three Mechanisms

DCP composes three independent prune paths. Pruned content never leaves the session log on disk — it is only replaced with a placeholder in the outgoing request.

1. Compress (model-driven)

A compress tool exposed to the model. The model decides when to call it based on task completion, picking which spans no longer need verbatim representation. This is not automatic per turn — the model triggers it. Two modes:
  • range (default) — compresses contiguous spans of conversation into block summaries. When a new compression overlaps an earlier one, the earlier summary is nested inside the new one to preserve information across compression layers rather than dilute it.
  • message (experimental) — compresses individual raw messages independently. Allows much more surgical context management.
In both modes, protected tool outputs (subagents, skills, todos) and protected file patterns are appended to compression summaries, ensuring critical state is never lost. protectUserMessages keeps user messages verbatim during compression — but this means large pasted prompts (e.g. log files) will never be compressed away. DCP injects nudges to encourage compression based on context size:
  • Below minContextLimit (default 50K tokens): no reminders
  • Between min and max: reminders active, but soft
  • Above maxContextLimit (default 100K tokens): strong nudges, fires every nudgeFrequency fetches
Both limits accept an absolute number or a "X%" of the model’s context window. Per-model overrides via modelMinLimits / modelMaxLimits.

2. Deduplication (automatic)

Identifies repeated tool calls (same tool name, same arguments) and keeps only the most recent output. Recalculated on LLM fetch — i.e. when the request is being assembled, not on every tool-call event. Prompt cache impact is therefore aligned with compression events, not interspersed mid-turn.

3. Purge Errors (automatic)

Prunes the input payload of errored tool calls after a configurable number of turns (default: 4). Error messages themselves are preserved — only the potentially large input content is removed. Recalculated alongside compress.

How It Differs From Compaction

The two are complementary: DCP keeps the active payload lean continuously; compaction handles wholesale summarization at end of session or near hard limits.

Commands

DCP exposes a /dcp slash command:

Protected Tools

By default these tools are never pruned:
The commands.protectedTools and strategies.deduplication.protectedTools / strategies.purgeErrors.protectedTools arrays add to this default list. The compress.protectedTools array works differently — those tool outputs get appended to compression summaries rather than excluded.

Prompt Cache Trade-Off

LLM providers cache prompts based on exact prefix matching. Because DCP rewrites the outgoing request — replacing pruned content with placeholders — it invalidates cached prefixes from the prune point forward. Reported numbers from the plugin’s testing:
  • ~85% cache hit rate with DCP
  • ~90% cache hit rate without DCP
Lost cache reads are traded for token savings on reduced context size and fewer hallucinations from stale content. In long sessions, savings outweigh cache miss cost. No impact for:
  • Request-based billing (e.g. GitHub Copilot — charges per request, not tokens)
  • Uniform token pricing (e.g. Cerebras — same rate for cached and uncached)

Relation to Clear-Over-Compact

Context Compression Strategies documents that clear-over-compact has become community consensus for harness-based AFK workflows. DCP fits the interactive path:
  • Sessions with safe clear points → clear (Pocock workflow)
  • Long interactive sessions where clearing loses unrecoverable state → DCP + compaction
  • Fully automated AFK loops → worktree isolation gives each task fresh context (no DCP needed)
DCP is most valuable for interactive sessions with no natural clear point, especially with smaller-context models (GitHub Copilot, local) where the minContextLimit / maxContextLimit values should be lowered to match.

Relation to Lean-Session

The lean-session plugin (custom, in templates/) and DCP solve overlapping problems via different hook surfaces:
  • lean-session uses OpenCode’s experimental.session.compacting hook — intervenes in the compaction process itself.
  • DCP introduces a compress tool plus automatic tool.execute-time strategies — works mostly outside compaction.
They are complementary, not competing: lean-session shapes the compaction summary when compaction does fire; DCP keeps the active context lean so compaction fires later, less often, and on cleaner input.