Problem
There's no way for consuming applications to react to compaction events. When LCM compacts context, the CompactResult is returned to the caller but not broadcast to any hook/event system. This prevents use cases like:
- Triggering self-improvement evaluation after compaction
- Writing compacted knowledge to external stores (Obsidian, Notion)
- Notifying users when significant context was compacted
- Metrics/telemetry on compaction frequency and efficiency
Proposed Solution
Add optional callback hooks to the plugin config:
onCompactionComplete(result: CompactResult) — fires after compact() succeeds, with the full summary content, token delta, and message IDs that were compacted
onSummaryCreated(summary: Summary) — fires when a new summary node is inserted into the DAG
beforeCompaction(context: CompactionContext) — fires before compaction starts, allowing pre-processing
These could be implemented as:
- Config-defined webhook URLs
- Shell command hooks (like Claude Code's hook system)
- Event emitter on the ContextEngine interface
Workaround
Currently polling the SQLite DB directly for new summaries, which works but is fragile and doesn't give real-time notification.
Context
The engine.ts compact() method and compaction.ts are the natural insertion points. The CompactResult type already contains all the data needed for hooks.
Problem
There's no way for consuming applications to react to compaction events. When LCM compacts context, the
CompactResultis returned to the caller but not broadcast to any hook/event system. This prevents use cases like:Proposed Solution
Add optional callback hooks to the plugin config:
onCompactionComplete(result: CompactResult)— fires aftercompact()succeeds, with the full summary content, token delta, and message IDs that were compactedonSummaryCreated(summary: Summary)— fires when a new summary node is inserted into the DAGbeforeCompaction(context: CompactionContext)— fires before compaction starts, allowing pre-processingThese could be implemented as:
Workaround
Currently polling the SQLite DB directly for new summaries, which works but is fragile and doesn't give real-time notification.
Context
The
engine.tscompact() method andcompaction.tsare the natural insertion points. TheCompactResulttype already contains all the data needed for hooks.