Skip to content

feat(agent): preview what a compression would keep, without calling a model - #312

Merged
yusiwen merged 1 commit into
masterfrom
feat/compression-preview
Oct 31, 2026
Merged

yusiwen merged 1 commit into
masterfrom
feat/compression-preview

Conversation

@yusiwen

@yusiwen yusiwen commented Oct 31, 2026

Copy link
Copy Markdown
Owner

What changed

  • agent/compression.go: the partition is now a value — compressionPlan (head, middle, pinned, tail,
    tokens, threshold) produced by planCompression, with the reason it cannot be built when it cannot.
    compressHistory executes the plan instead of re-deriving the same boundaries.
  • agent/compression_preview.go (new): CompressionPreview() renders the plan — whether automatic
    compression would fire, each kept region's messages (role + first line, capped at 12) and token count,
    and the middle's token count. No provider call.
  • tui/update.go: /compress preview prints it; still refused while a run is active (reading a slice the
    run appends to is a data race even though nothing is written).
  • Docs: CODEBASE.md (the plan and the preview), roadmap B5 (S1–S3 landed, S4 open), test count
    1277 → 1285.

Why

A compression is destructive and was opaque until it ran. "What would be kept" is a question with a cheap
answer — the partition — and the preview is that answer. Making the compression execute the same plan is
what keeps the answer true: a second implementation of the boundaries would drift, and the drift would
only be visible after a summary had already replaced the turns.

Verification

  • go test ./... -count=1 → 16 packages ok; go vet and gofmt -l clean.
  • Mutation checks, both load-bearing assertions:
    • a provider call added to the preview → TestCompressionPreviewCallsNoModel fails with the preview called the provider 1 times;
    • pinned and tail swapped in the compression → TestCompressionPreviewMatchesTheCompression fails with
      pinned message 0 differs.
  • New tests: the preview calls no model; it names every kept region and reports the middle by size; it
    says why nothing can be compressed (fewer than four turns, disabled, all-pinned middle); the plan and
    the compression agree message for message; the over/under-threshold wording; firstLine clipping; and
    the TUI command, including the run guard.
  • git log --format='%h %G? %s' → G.

Honest scope

  • The preview describes what a compression would do on the current history. If the history changes
    between the preview and the command (another turn, or a run), the partition changes with it; there is no
    reservation.
  • It reports the pinned middle as the pinned region when a plan exists. A middle that is entirely pinned
    has no plan at all — compression would do nothing — so the preview reports the reason instead of empty
    sections.
  • No interactive confirmation: /compress preview prints, /compress still compresses without asking.

Follow-ups

Refs #306, #168

… model

B5's S3. `/compress` was all-or-nothing and silent until it ran: a user had no
way to see which turns would be kept, which would be folded into a summary, and
what the summary would replace.

The partition now exists on its own: `planCompression` computes head, middle,
pinned groups, tail, the token estimate and the threshold, and `compressHistory`
executes that plan instead of re-deriving it. `/compress preview` reads the same
plan and prints it — each kept region with its first lines and size, the middle
by token count, and whether automatic compression would fire.

Because there is one plan, the preview cannot disagree with the thing it
previews; the test asserts the compression's output is the plan's head, summary,
pinned and tail in that order.

The preview makes no provider call, which is the acceptance that matters most: a
preview that asks a model is a compression. It is still refused while a run is
active — reading a slice the run goroutine appends to is a data race even when
nothing is written.

Verified: go test ./... -count=1, 16 packages ok; go vet and gofmt clean; both
load-bearing assertions mutation-checked — adding a provider call to the preview
fails "the preview called the provider 1 times", and swapping pinned and tail in
the compression fails "pinned message 0 differs".

Refs #306, #168
@yusiwen yusiwen added the feature A new capability rather than an improvement to existing behaviour label Oct 31, 2026
@yusiwen
yusiwen merged commit 8d1ccb8 into master Oct 31, 2026
9 checks passed
@yusiwen
yusiwen deleted the feat/compression-preview branch October 31, 2026 04:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature A new capability rather than an improvement to existing behaviour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant