FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat(core): proportional compaction with context-restoration prompt by ryangamerdev · Pull Request #5 · gignit/opencode · GitHub

forked from anomalyco/opencode

feat(core): proportional compaction with context-restoration prompt - #5

Open
ryangamerdev wants to merge 1 commit into
devfrom
compaction-ratios
Open

feat(core): proportional compaction with context-restoration prompt#5
ryangamerdev wants to merge 1 commit into
devfrom
compaction-ratios

Conversation

ryangamerdev commented Aug 26, 2026
edited
Loading

Copy link
Copy Markdown

Issue for this PR

Closes anomalyco#37551
Closes anomalyco#41358
Related: anomalyco#43703, anomalyco#37629

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Compaction sizing is currently absolute-token based (preserve_recent_tokens) and the auto-trigger uses a fixed reserved headroom. Two problems follow from that:

  1. When a session is smaller than preserve_recent_tokens, select() walks every turn without exceeding the budget, ends with keep.start === 0, and returns "head = everything, no tail" — so the whole conversation gets summarized and nothing is kept verbatim.
  2. A fixed reserved buffer makes the effective trigger point scale with the model's context window, so the same config compacts a small-context model very differently from a large one (the concern raised in [FEATURE]: per-model compaction threshold (reserved/buffer) anomalyco/opencode#43703).

This adds three opt-in, token-based knobs. When they are unset, selection and trigger behavior are unchanged.

  • extract_ratio / recent_ratio: size the verbatim tail as (1 - extract_ratio) of the current scoped tokens, and size the recent-context slice as recent_ratio of it. Because they scale with the conversation, a small session is never fully summarized.
  • trigger_ratio: compact when usage reaches trigger_ratio x context — a percentage of the window — instead of the fixed-headroom threshold. This is inherently context-window-relative, which is what multi-model setups need.

It also improves the summary itself: the compaction prompt is a context-restoration document, and the newest slice of the conversation is passed to the summarizer as a relevance signal (<recent_context>) so the summary is weighted toward the session's current direction. This helps the agent keep the task goal across the compaction boundary (anomalyco#41358).

All three ratios are computed on demand from the scoped conversation (history minus hidden prior-compaction turns).

Recommended settings ("infinite session")

These are the settings I've been using for about 6-8 months (even before this new compaction system). You can raise extract_ratio to compact more of the session to have more context remaining between compactions, but in my testing anything near the 0.6 range loses too much fidelity for the agent to continue seamlessly, as if nothing happened. With these settings my long-running sessions keep going without the agent losing track of what it was doing — or how to do something it was doing well before the compaction.

"compaction": {
  "trigger_ratio": 0.85,
  "extract_ratio": 0.4,
  "recent_ratio": 0.15
}

Because the ratios scale with the conversation, the same config behaves sensibly on both small and large sessions.

How did you verify your code works?

  • bun typecheck passes in packages/core and packages/opencode, rebased on current dev.
  • Ran a real ~815k-token session through a manual compaction: with extract_ratio: 0.4 / recent_ratio: 0.15, the summary was produced as the restoration document, the verbatim tail was preserved via tail_start_id, and follow-up questions were answered from the preserved tail. Verified the split is token-based (via the model token estimate), not message-count based.
  • Verified the small-session case: with a ratio set, a session smaller than the old absolute budget keeps its proportional tail instead of summarizing everything.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Improves compaction so long sessions stay coherent after compacting, and
fixes a small-session edge case in the existing absolute-token approach.

Three related changes, all opt-in (unset falls back to current behavior):

- Context-restoration prompt: replaces the terse summary template with a
  6-section restoration document, and feeds the newest slice of the
  conversation to the summarizer as a relevance signal (<recent_context>)
  so the summary is weighted toward the session's current direction.

- Proportional selection (extract_ratio / recent_ratio): sizes the verbatim
  tail as (1 - extract_ratio) of the current scoped tokens instead of an
  absolute budget. This fixes the case where a session smaller than
  preserve_recent_tokens summarizes the ENTIRE conversation and keeps nothing
  verbatim (select() returns keep.start === 0). Ratios scale with session
  size, so a small session is never fully summarized. recent_ratio sizes the
  relevance signal proportionally.

- Proportional trigger (trigger_ratio): compacts proactively at
  trigger_ratio x context (a percentage of the window) instead of the fixed
  reserved-headroom threshold, leaving room for a rich summary at high fill.

All three are token-based and computed on demand from the scoped conversation
(history minus hidden prior-compaction turns). When the new keys are unset,
selection and trigger behavior are unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant


Back | FazBrowse Home | New Git URL