How pi-compact-jev 0.5.1 works
September 20, 2026 · View on GitHub
This is the prune path that runs on Pi’s session_before_compact. It replaces Pi’s LLM summary of the dropped prefix. Kept text is verbatim. Landing page: README.md.
Order of operations
- Keep-windows on user/assistant text in the dropped region.
- Pin invoked skills, unresolved errors, git mutations, edit/write, images.
- Pair each
toolCallwith itstoolResult. Unpaired calls are not scored. - Ask Jev about unpinned pairs only.
- Apply useful → need-full.
- Render surviving messages as one markdown string. Flatten the previous compact under it (not Jev-scored).
Pi still cuts at firstKeptEntryId (about 20k live tokens). This package only rewrites the dropped prefix.
State (JSON, shared by every question batch)
Not the live transcript. Caps are characters.
| Field | What |
|---|---|
workspace | Folder name, depth-2 dirs (skips node_modules / .git / …), README ≤ 25,000 |
context | Fixed paragraph: this is a compaction |
first | First user + first assistant, pair ≤ 25,000 |
recent | Last 5 user/assistant pairs, each ≤ 5,000 |
carried | Previous compact, dumps stripped, ≤ 8,000. Mid-session commitments only. Not scored. |
Tool dumps are not in state. fitState shrinks those caps until estimated tokens ≤ 28,000. One state for every batch. Whole POST (state + questions) ≤ 64,000 estimated tokens.
Questions (float noul, 0–1)
Two questions per unpinned call, same dump view on both (head / middle / tail, 2,500c each). Both go in one POST; the threshold is applied after.
useful_tN
Give confidence the following context useful to the current project and/or session context or the latest prompt(s)?
[id, tool, args, dump windows]
full_tN
Do I need it in full?
[same dump windows]
Criteria for full: after compact this dump is gone and will not be re-run. False means keep first 25% + last 25%, each capped at 2,500.
keepThreshold 0.5, inclusive.
| useful | full | Action |
|---|---|---|
| < 0.5 | ignored | Drop call + result |
| ≥ 0.5 | ≥ 0.5 | Keep dump verbatim |
| ≥ 0.5 | < 0.5 | Stub: 25% head + 25% tail, cap 2,500 each |
Pinned calls skip Jev and stay.
Pins (Jev is not asked)
| Pin | Dump |
|---|---|
Unresolved isError (last fail per tool+path/command with no later same-key success) | Verbatim |
Git mutations (commit/push/…, not status/diff/log) | Cap 600c head |
edit/write | Path; edit old/new heads 300c; write body kept if ≤ 2,000c, else a length note |
| Images | Untouched |
Last invoked $skill load | Full body |
A unique-command error (cat /tmp/old.log) never gets a same-key success, so it stays pinned even if the user later says ignore it. Unpinning on any later success would drop a real test fail after a following Read. That tradeoff is intentional.
What we tried that did not ship
now/lateron full history — large, expensive, worse continuation.- Blind
full(“would the stub drop info?” with no dump) — zero unpinned full-keeps; broker needle died in the middle. - 600c cap on unresolved errors — buried failures vanished.
- Stripping every write body — HMAC in short Write args disappeared.
Restoring “Do I need it in full?” and putting dump windows on full is what made useful dumps stay whole (broker 0.89/0.68).
Known leftovers (not bugs to chase)
- Tiny listings can score useful ~0.65 and stub instead of drop. Noise.
- One-line facts may score
fulljust under 0.5; if the dump is short, the stub keeps the whole line anyway. - Carried previous compact is shown in state, not re-scored. Re-pruning S1 with Jev stacks loss.