feat(core): enhanced compaction with ratios and combined context-restoration advancement - #45125
Open
ryangamerdev wants to merge 1 commit into
Open
feat(core): enhanced compaction with ratios and combined context-restoration advancement#45125ryangamerdev wants to merge 1 commit into
ryangamerdev wants to merge 1 commit into
Conversation
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.
Contributor
|
The following comment was made by an LLM, it may be inaccurate: Potential Duplicate/Related PRs Found#43713 -
#40601 -
#44898 -
These are contextually related but appear to be addressing different aspects of the compaction system rather than duplicating the same work. The current PR (#45125) specifically introduces the proportional/ratio-based approach with context-restoration, which is distinct from the per-model config support in #43713. |
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
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue for this PR
Closes #37551
Closes #41358
Related: #43703, #37629
Type of change
What does this PR do?
Compaction sizing is currently absolute-token based (
preserve_recent_tokens) and the auto-trigger uses a fixedreservedheadroom. Two problems follow from that:preserve_recent_tokens,select()walks every turn without exceeding the budget, ends withkeep.start === 0, and returns "head = everything, no tail" — so the whole conversation gets summarized and nothing is kept verbatim.reservedbuffer 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) #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 asrecent_ratioof it. Because they scale with the conversation, a small session is never fully summarized.trigger_ratio: compact when usage reachestrigger_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 (#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_ratioto 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.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 typecheckpasses inpackages/coreandpackages/opencode, rebased on currentdev.extract_ratio: 0.4/recent_ratio: 0.15, the summary was produced as the restoration document, the verbatim tail was preserved viatail_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.Checklist