Skip to content

feat(hooks): post_compact event with realized compaction outcome#218

Merged
emal-avala merged 1 commit intomainfrom
feat/hook-post-compact-event
Apr 23, 2026
Merged

feat(hooks): post_compact event with realized compaction outcome#218
emal-avala merged 1 commit intomainfrom
feat/hook-post-compact-event

Conversation

@emal-avala
Copy link
Copy Markdown
Member

Summary

Pairs with `PreCompact` (which fires before compaction with an estimated tokens-freed number). `PostCompact` fires after compaction finishes, carrying the ground-truth delta: `messages_before`, `messages_after`, and the actual `freed_tokens`.

Audit hooks can now record both the forecast and the reality. That matters because the three compaction paths — microcompact, LLM compaction, and the context-collapse fallback — don't always free what the estimate predicted. LLM compaction can be blocked by a cancel; the collapse fallback frees a different shape of context; and in the no-op case nothing changes at all.

Wiring

  • New `HookEvent::PostCompact` variant with snake_case serde
  • `fire_post_compact_hooks(messages_before, messages_after, freed_tokens)` on `QueryEngine`
  • `/compact` handler fires it after microcompact, including on no-op (`freed=0`), so user-invoked `/compact` always reaches hooks
  • `run_turn_with_sink` fires it once at the end of the auto-compact block with the cumulative delta across all paths taken; skipped when nothing actually changed so hooks aren't spammed every turn
  • `HOOK_EVENT_CATALOG`, `format_hook_event`, `parse_hook_event`, and the module-header docs all updated

Test plan

  • `cargo clippy --workspace --tests --no-deps -- -D warnings` — clean
  • `cargo test -p agent-code-lib --lib hooks::` — 5 pass (4 prior + 1 new)
  • `cargo test -p agent-code-lib --lib config::` — 69 pass (includes new serde round-trip)
  • `cargo test -p agent-code --bin agent commands::tests::parse_hook_event` — 6 pass (5 prior + 1 new)
  • `format_hook_event_covers_every_variant` now asserts `PostCompact` is mapped
  • `parse_hook_event_covers_every_variant_in_catalog` keeps catalog and parser in lock-step

Pairs with PreCompact (which fires before compaction with estimates).
PostCompact fires AFTER compaction finishes, carrying the ground-truth
delta: messages_before, messages_after, and actual tokens freed. Audit
hooks can now record both the forecast and the reality, which matters
because the three compaction paths (microcompact, LLM compaction,
context collapse fallback) don't always free what the estimate
predicted — e.g. LLM compaction can be blocked by a cancel, and the
collapse fallback frees a different shape of context.

Wiring:

- New HookEvent::PostCompact variant with snake_case serde
- fire_post_compact_hooks(messages_before, messages_after, freed_tokens)
  on QueryEngine
- /compact handler fires it after microcompact, including for no-op
  compactions (freed=0) so hooks see every user-invoked /compact
- run_turn_with_sink fires it once at the end of the auto-compact
  block with the cumulative delta across all paths taken; skipped
  when nothing actually changed so hooks aren't spammed every turn
- HOOK_EVENT_CATALOG, format_hook_event, parse_hook_event, and the
  module-header docs all updated

3 new tests: schema serde round-trip, dispatcher fires for PostCompact,
and parse_hook_event handles both snake_case and hyphenated forms.
Existing format_hook_event_covers_every_variant now asserts PostCompact
is mapped, and parse_hook_event_covers_every_variant_in_catalog keeps
the catalog and parser in lock-step.
@emal-avala emal-avala merged commit cbfdfc1 into main Apr 23, 2026
14 checks passed
@emal-avala emal-avala deleted the feat/hook-post-compact-event branch April 23, 2026 19:09
@emal-avala emal-avala mentioned this pull request Apr 23, 2026
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant