fix(claude): draw one compaction divider, and let it set the context gauge
Two defects in the 0.75.1 compaction work, both found by running the real
parser over real transcripts.
A resume replays the surviving history into the SAME transcript file,
`system`/`compact_boundary` records included — byte-identical, original
uuid and timestamp intact. One 19,435-line transcript here holds 22
boundary records for 7 actual compactions, one of them written six times,
so that session drew six identical dividers in a row. The accumulator now
remembers which boundary uuids it has already turned into a divider.
(Upstream guards the same duplication on the wire: `context-compaction.js`
calls its lifecycle "idempotent" because "the SDK can duplicate terminal
compact_result messages".)
The gauge, separately, read a window that no longer exists. A compaction
REPLACES the prompt window but its record carries no usage, so
`latest_turn_prompt_usage_tokens` walked straight past it to the last
pre-compaction reply: measured on a real session, 108,307 reported for a
window the boundary itself puts at 4,462. `postTokens` is the number the
adapter feeds the LIVE gauge — 0.75.0 answers a `compact_boundary` with
`usage_update {used: post_tokens}` — which is why only the reopened
conversation was wrong. The claude reader now takes whichever comes first
scanning back: a reply after the compaction already prices the compacted
window, so it still wins; the boundary only speaks when nothing has been
said since.
Mid-turn, one more copy comes from a channel no id-keyed dedup can join:
the live ACP `tool_call` under a `live-…` turn beside the transcript-derived
divider under a parser id. The usual suppressor cannot help — the `/compact`
prompt is not persisted until AFTER the boundary, so `apply_in_flight_message_id`
has no user turn to anchor on. `dedupeCompactionItems` folds them by event
identity instead, and deliberately refuses to key on anything less than
preTokens + postTokens + durationMs together: codex-acp sends a bare
`{version: 1}` for every compaction it runs, and a looser key would fold a
whole session's compactions into one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> X
xintaofei committed
5f22a3e1523c94c8f6abc40711cc28d1fe979758
Parent: 2467190