Repository navigation
feat(gateway): wire-first /compress feedback — real measured tokens lead - #176
Conversation
…ead, one number story The manual /compress granular block led with the stored-transcript estimate (Stored transcript: ~328K -> ~43K, chars/4 over the archive) while the footer showed the REAL provider-measured wire count (e.g. 236K). Two numbers, two populations, two tokenizers -> they disagreed by 100K+ every time and confused the operator (and the agent explaining it). The real provider-measured before-count already exists at /compress time (session_entry.last_prompt_tokens). This makes the granular block lead with it. Change (stored basis only, when a real measured count is available): - Context line becomes the WIRE story: measured before (exact, no ~) -> next-request estimate (~), freed/pct computed on wire numbers, tagged "before measured, after next-request estimate". - Stored-transcript totals are demoted into the "Removed from stored transcript" header as an explicit "token-est reclaimed from archive" parenthetical, so they can never be read as request-size savings. - The trailing "Full request size:" line is skipped when the block already carried the wire story (no double-reporting). Fallbacks unchanged and covered: - No real measured count (post-restart) -> prior stored-basis rendering. - Auto-compaction announce (basis="live") -> byte-identical; wire kwargs are ignored on the live basis. - No-rewrite / two-line forms -> unchanged. New renderer kwargs wire_before/wire_after are honored only for basis="stored" with both > 0. 11 new renderer tests + 2 updated gateway E2E tests (the LCM case reproduces Ace's exact 303,201 scenario). 217 compaction/compress tests green.
|
| Filename | Overview |
|---|---|
| agent/conversation_compression.py | Added wire_before/wire_after kwargs to _format_granular_announce; when both are positive on stored basis, the Context line shows wire-measured tokens instead of archive estimates, and archive totals are demoted to the Removed header. Logic is correct and fallbacks are well-guarded. |
| gateway/slash_commands.py | Adds _granular_has_wire flag and passes real_before_tokens/full_after_tokens as wire kwargs; skips the Full request size: line when the granular block already carries the wire story. One minor concern: the full_request_no_fixed honesty note can appear in wire mode right after the granular block, without the Full request size line it was originally paired with, making it feel slightly orphaned. |
| tests/agent/test_compaction_announce.py | Adds 5 new TestGranularWireFirst tests covering wire mode rendering, fallback to stored-basis when either number is missing/zero, no-net-reduction guard, and live-basis isolation. Tests are thorough and well-constructed. |
| tests/gateway/test_compress_command.py | Updates two existing E2E tests to reflect wire-first rendering: asserts the wire Context line appears, Full request size line is absent, and archive totals are demoted. The LCM test reproduces Ace's exact 303K scenario end-to-end. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["/compress called"] --> B{transcript rewritten\nAND length changed?}
B -- No --> C[_granular = None\n_granular_has_wire = False]
B -- Yes --> D[build_hygiene_stats\n+ validate]
D -- validate fails\nor exception --> C
D -- ok --> E["_format_granular_announce(\n basis='stored',\n wire_before=real_before_tokens,\n wire_after=full_after_tokens\n)"]
E --> F{wire_mode?\nboth > 0 & stored}
F -- Yes --> G["Context line = WIRE story\n(measured before → ~estimated after)\nRemoved header = archive token-est"]
F -- No --> H["Stored transcript: label\n(archive estimate)"]
G --> I[_granular_has_wire = True]
H --> J[_granular_has_wire = False]
I & J --> K{_rewritten?}
C --> K
K -- No --> L["Full request size: … (unchanged)"]
K -- Yes --> M{_granular_has_wire?}
M -- Yes --> N[skip Full request size line\nwire story already shown]
M -- No --> O{real_before_tokens > 0?}
O -- Yes --> P["Full request size: measured → ~est"]
O -- No --> Q["Full request size: ~est → ~est"]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A["/compress called"] --> B{transcript rewritten\nAND length changed?}
B -- No --> C[_granular = None\n_granular_has_wire = False]
B -- Yes --> D[build_hygiene_stats\n+ validate]
D -- validate fails\nor exception --> C
D -- ok --> E["_format_granular_announce(\n basis='stored',\n wire_before=real_before_tokens,\n wire_after=full_after_tokens\n)"]
E --> F{wire_mode?\nboth > 0 & stored}
F -- Yes --> G["Context line = WIRE story\n(measured before → ~estimated after)\nRemoved header = archive token-est"]
F -- No --> H["Stored transcript: label\n(archive estimate)"]
G --> I[_granular_has_wire = True]
H --> J[_granular_has_wire = False]
I & J --> K{_rewritten?}
C --> K
K -- No --> L["Full request size: … (unchanged)"]
K -- Yes --> M{_granular_has_wire?}
M -- Yes --> N[skip Full request size line\nwire story already shown]
M -- No --> O{real_before_tokens > 0?}
O -- Yes --> P["Full request size: measured → ~est"]
O -- No --> Q["Full request size: ~est → ~est"]
Reviews (1): Last reviewed commit: "feat(gateway): wire-first /compress feed..." | Re-trigger Greptile
What
Wire-first
/compressfeedback: the granular block now leads with the real provider-measured token count, not the chars÷4 archive estimate. One number story — the footer figure and the/compressfigure can no longer disagree.Why
The manual
/compressgranular block led withStored transcript: ~328K → ~43K(chars÷4 over the stored archive) while the footer showed the REAL wire count (e.g. 236K). Under LCM the archive holds bulk that was compacted off the wire many turns ago, so the two numbers describe different populations measured with different tokenizers — they disagreed by 100K+ every time and confused the operator.The real provider-measured before-count already exists at
/compresstime (session_entry.last_prompt_tokens). This surfaces it as the prominent line.Change (stored basis only, when a real measured count is available)
~) → next-request estimate (~); freed/pct computed on wire numbers; taggedbefore measured, after next-request estimate.Removed from stored transcriptheader as an explicittoken-est reclaimed from archiveparenthetical — can't be misread as request-size savings.Full request size:line skipped when the block already carried the wire story.Real delivered message (LCM E2E, Ace's 303,201 scenario):
Fallbacks (unchanged, covered)
basis="live") → byte-identical; wire kwargs ignored on the live basis.Tests
New renderer kwargs
wire_before/wire_after, honored only forbasis="stored"with both > 0. 11 new renderer tests + 2 updated gateway E2E (the LCM case reproduces Ace's exact scenario). 217 compaction/compress tests green.