#14887: feat(compaction): configurable auto-compaction notifications with optional metrics
size: M
Cluster:
Compaction Enhancements and Features
## Summary
This PR improves visibility and operator control for **auto-compaction notifications** in OpenClaw reply flows.
### What’s included
- Adds config: `agents.defaults.compaction.notify`
- `verbose` (default): show auto-compaction notice in verbose modes
- `always`: always show auto-compaction notice when compaction completes
- `off`: suppress auto-compaction notice
- Standardizes auto-compaction notice formatting across:
- main reply path
- followup runner path
- Adds adaptive metric display in notices:
- when available: token reduction + context window occupancy
- when unavailable: clean fallback notice text (no noisy placeholders)
## Motivation
Auto-compaction can materially change context state, but users/operators may not clearly see when it happened or how much reduction occurred.
This change keeps behavior backward-compatible while improving observability and making notification policy explicit and configurable.
## Scope / Non-goals
### In scope
- Notification policy (`verbose | always | off`)
- Notification text/formatting consistency in auto-compaction reply paths
- Optional stats rendering when engine event data exists
### Out of scope
- Compaction trigger thresholds
- Compaction algorithm/selection logic
- Manual `/compact` command formatting path
## Config
```json
{
"agents": {
"defaults": {
"compaction": {
"notify": "verbose"
}
}
}
}
```
Allowed values: `"verbose" | "always" | "off"`.
## Testing
### 1) Targeted unit tests (auto-compaction notice behavior)
```bash
npx -y pnpm@10.23.0 vitest run \
src/auto-reply/reply/followup-runner.test.ts \
src/auto-reply/reply/agent-runner.heartbeat-typing.runreplyagent-typing-heartbeat.signals-typing-block-replies.test.ts
```
Result: **13 passed**
Covers:
- verbose notice emission
- notify=always behavior even when verbose is off
- metrics-present formatting
- metrics-absent fallback path
### 2) Additional verification (isolated forced-injection path)
To validate both branches safely without affecting a live gateway, I verified behavior in an isolated workspace (`/tmp/openclaw-upstream`) using mock/forced compaction event injection.
- **stats-present path**
- notice includes reduction metrics (e.g. `100k→40k`, window occupancy)
- **stats-absent path**
- notice still appears with clean fallback text
### 3) E2E command-path check
```bash
npx -y pnpm@10.23.0 vitest --config vitest.e2e.config.ts run \
src/auto-reply/reply.triggers.trigger-handling.runs-compact-as-gated-command.e2e.test.ts
```
Result: **3 passed**
## Manual `/compact` vs auto-compaction (important distinction)
- Manual `/compact` output (`⚙️ Compacted ...`) is an existing upstream command-path UI.
- This PR targets **auto-compaction notification delivery** in agent/reply flows.
- Different strings between these two paths are expected and intentional.
## Notes for stable users (`v2026.2.9`)
- Upstream source can support `agents.defaults.compaction.notify` with schema/type updates in this PR.
- Current stable `v2026.2.9` has strict schema and rejects this key until a release containing these changes is published.
## Backward compatibility
- Default mode remains `verbose`.
- If compaction metric fields are missing from engine events, behavior degrades gracefully to text-only notices.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR adds a configurable notification policy for auto-compaction (`agents.defaults.compaction.notify`), standardizes the auto-compaction notice text across the main reply runner and followup runner, and optionally includes compaction metrics (tokens before/after and context window occupancy) when engines emit them via compaction events. It also adds a verbose-full “Compaction summary” block.
Most changes are localized to the reply/followup runners and `session-updates.ts` helpers for deciding whether to emit the notice and formatting the notice/summary text, plus schema/type updates to accept the new config key.
<h3>Confidence Score: 4/5</h3>
- Mostly safe to merge, but should fix one correctness issue around session token totals after auto-compaction.
- Notification policy, formatting, and schema updates are straightforward and covered by tests, but the new compaction stats plumbing isn’t used to persist post-compaction token totals (unlike the manual /compact path), which can leave session usage metadata stale.
- src/auto-reply/reply/agent-runner.ts, src/auto-reply/reply/followup-runner.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#21547: feat: add compaction.announce config to notify users of compaction ...
by jlwestsr · 2026-02-20
84.7%
#11089: feat(compaction): support customInstructions and model override for...
by p697 · 2026-02-07
83.7%
#20038: (fix): Compaction: preserve recent context and sync session memory ...
by rodrigouroz · 2026-02-18
82.5%
#14021: feat(compaction): optional memory flush before manual /compact
by phenomenoner · 2026-02-11
81.7%
#19923: feat: track held messages during compaction gate and split verifica...
by PrivacySmurf · 2026-02-18
81.5%
#15322: feat: post-compaction target token trimming + fallback strategy
by echoVic · 2026-02-13
80.9%
#10505: feat(compaction): add timeout, model override, and diagnostic logging
by thebtf · 2026-02-06
80.1%
#18997: fix: improve context overflow error messages and docs
by realhoratiobot · 2026-02-17
80.1%
#18663: feat: progressive compaction escalation and mechanical flush fallback
by Adamya05 · 2026-02-16
79.9%
#19593: feat(compaction): proactive handover before context overflow
by qualiobra · 2026-02-18
79.6%