Compaction's MIN_HEADROOM_RATIO floor produces a post-compaction context cliff
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 68/100
Research direction
Start from LlmCompaction and the compact_headroom_turns/trigger_ratio knobs, then run examples/long_horizon.rs and examples/llm_compaction_live.rs to measure the fallback rate live. Compare against compaction_keeps_a_usable_well_formed_transcript in src/context.rs to isolate why the live path collapses 22 messages to 1 (suspect shrink_tail or re-compacting compacted history). Done means: the gap is explained or closed and documented next to trigger_ratio, the collapse has a cause or fix, and a test covers the splice path beyond MockProvider.
Written by the indexing model from the issue text.
Description
Found by examples/long_horizon.rs running live against Sonnet 5 before the 0.18.0 release.
What happened
A 25-turn run over a tool returning ~60-line records, max_context_tokens: 30_000, LlmCompaction attached:
[compaction #1] Deterministic: 25 msgs / 19504 tok -> 3 msgs / 1665 tok
[compaction #2] Deterministic: 22 msgs / 21371 tok -> 1 msgs / 22 tok
[compaction #3] Deterministic: 25 msgs / 19508 tok -> 3 msgs / 1665 tok
[compaction #4] Deterministic: 25 msgs / 19892 tok -> 3 msgs / 1679 tok
Every compaction took the deterministic fallback. The briefing never landed, so the run got none of what LlmCompaction exists to provide, while still paying for the summarization requests. The agent then answered LOST when asked to recall a fact from before compaction.
Reproduced at trigger_ratio 0.6 and 0.35.
Why (partly understood)
Summarization is spawned when usage crosses trigger_ratio and spliced only when a later turn crosses the budget. With bulky tool output, the span between those two points is one or two turns — less than a summarization round-trip — so compact() finds Phase::Ready empty and falls back.
examples/llm_compaction_live.rs already documents the knob: "YO_TRIGGER … lower buys wall-clock headroom". But lowering it from 0.6 to 0.35 did not help here, which suggests the window is bounded by turns, not token fraction — one turn of a bulky tool can cross the whole gap regardless of where the trigger sits.
compact_headroom_turns exists and may be the right lever; it was left at its default in this run and is untested live.
Not explained
Compaction #2 collapsed 22 messages / 21371 tokens to 1 message / 22 tokens, far below keep_first(2) + keep_recent(6).
This did not reproduce in isolation. compaction_keeps_a_usable_well_formed_transcript (added in src/context.rs) drives the same shape through compact_messages and retains 15–24 messages / ~12.5k tokens, correctly and without orphaning tool calls. So the collapse comes from the live path — most likely LlmCompaction's own shrink_tail, or compaction running on already-compacted history — not from compact_messages.
Why it matters
Not a correctness bug: the loop always makes progress and the fallback is deliberate ("a slow or dead summarizer can never wedge it"). But a user who attaches LlmCompaction to a tool-heavy agent may pay for briefings they never receive, and silently get the lossy behaviour they were trying to avoid. CompactionMethod::Deterministic on the event is the only signal, and only if they listen for it.
Suggested work
- Establish whether
compact_headroom_turnscloses the gap; if it does, say so in theLlmCompactiondocs next totrigger_ratio. - Consider warning once per session when the fallback fires repeatedly — paying for briefings that never land is worth surfacing.
- Explain or fix the 22 → 1 message collapse.
- Live coverage for the splice path; every existing
LlmCompactiontest usesMockProvider, and none of them would have caught a fallback rate of 100%.
- Dominant language
- Rust
- Stars
- 327
- Forks
- 46
- Avg merge
- 2h 30m
- Merged PRs (30d)
- 143
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from yologdev/yoagent
-
enhancement P3
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
yologdev/yoagent#223 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 70/100
yologdev/yoagent#198 · 1 comment ·
Maintainers usually reply within 1 day
All issues in yologdev/yoagent
Similar issues
-
documentation
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
charles-hood/DiagramCraft#73 ·
-
Difficulty 1/5 1-3 hours Newbie friendliness 78/100
ontologyportal/sigma-rs#200 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
chipsalliance/caliptra-sw#4311 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
`image_generation`: `max_retries` is ignored for OpenAI-compatible providers (always 2 retries)Possibly taken @ericz7900 claimed this today. Openllm translation
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
Maintainers usually reply within 1 day