Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Compaction's MIN_HEADROOM_RATIO floor produces a post-compaction context cliff

Open
#150 3 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
68/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
rust
Domain
ai, backend

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

P3

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_turns closes the gap; if it does, say so in the LlmCompaction docs next to trigger_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 LlmCompaction test uses MockProvider, 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

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from yologdev/yoagent

All issues in yologdev/yoagent

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.