feat(hooks): add session:compact:pre and session:compact:post events#6768
feat(hooks): add session:compact:pre and session:compact:post events#6768g1itchbot8888-del wants to merge 1 commit into
Conversation
Adds hook events before and after context compaction to allow agents to save and restore working state across compaction boundaries. Events: - session:compact:pre: fired before compaction, includes message count - session:compact:post: fired after, includes summary and token counts Use case: Memory systems can capture active task state before compaction wipes the context, then inject it back after compaction completes.
| // Trigger pre-compaction hook | ||
| const preCompactEvent = createInternalHookEvent( | ||
| "session", | ||
| "compact:pre", | ||
| params.sessionKey ?? params.sessionId, | ||
| { | ||
| sessionId: params.sessionId, | ||
| sessionFile: params.sessionFile, | ||
| workspaceDir: effectiveWorkspace, | ||
| messageCount: session.messages.length, | ||
| }, |
There was a problem hiding this comment.
[P0] session:compact:pre is fired after messages are already replaced/limited
The doc says “before context compaction begins”, but this event is emitted after limitHistoryTurns() and session.agent.replaceMessages(limited) have already mutated the session history; hooks that want to snapshot “current task state / working context” will see a truncated view (and messageCount will reflect the truncated count). If the intent is to snapshot the pre-compaction state, emit the hook before any pruning/replacement (or pass both counts / both message sets in context).
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/compact.ts
Line: 430:440
Comment:
[P0] `session:compact:pre` is fired after messages are already replaced/limited
The doc says “before context compaction begins”, but this event is emitted after `limitHistoryTurns()` and `session.agent.replaceMessages(limited)` have already mutated the session history; hooks that want to snapshot “current task state / working context” will see a truncated view (and `messageCount` will reflect the truncated count). If the intent is to snapshot the pre-compaction state, emit the hook before any pruning/replacement (or pass both counts / both message sets in context).
How can I resolve this? If you propose a fix, please make it concise.| const result = await session.compact(params.customInstructions); | ||
| // Estimate tokens after compaction by summing token estimates for remaining messages | ||
| let tokensAfter: number | undefined; |
There was a problem hiding this comment.
[P1] Hook failures are silently swallowed; compaction proceeds even if hooks need to block
triggerInternalHook() catches and logs handler errors internally, so a failing compact:pre/compact:post hook won’t stop compaction and the caller can’t tell it failed. If these events are meant for state preservation across compaction, this can lead to “lost state” without any surfaced error. Consider whether compaction should fail fast (or at least return warnings) when these hooks error, especially for compact:pre.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/compact.ts
Line: 444:446
Comment:
[P1] Hook failures are silently swallowed; compaction proceeds even if hooks need to block
`triggerInternalHook()` catches and logs handler errors internally, so a failing `compact:pre`/`compact:post` hook won’t stop compaction and the caller can’t tell it failed. If these events are meant for state preservation across compaction, this can lead to “lost state” without any surfaced error. Consider whether compaction should fail fast (or at least return warnings) when these hooks error, especially for `compact:pre`.
How can I resolve this? If you propose a fix, please make it concise.|
Closing as duplicate of #8244. If this is incorrect, comment and we can reopen. |
Summary
Adds hook events before and after context compaction to allow agents to save and restore working state across compaction boundaries.
Motivation
When context compaction occurs (either manually via
/compactor automatically on context overflow), agents lose their working state. This makes it difficult for memory systems to preserve continuity across compaction.With these hooks, a memory skill can:
Events
session:compact:preFired before compaction begins. Context includes:
sessionId: Session identifiersessionFile: Path to session transcriptworkspaceDir: Agent workspace directorymessageCount: Number of messages before compactionsession:compact:postFired after compaction completes. Context includes:
sessionId: Session identifiersessionFile: Path to session transcriptworkspaceDir: Agent workspace directorysummary: Compaction summary generated by the modeltokensBefore: Token count before compactiontokensAfter: Token count after compactionfirstKeptEntryId: ID of first kept messageExample Hook
Testing
/compactcommandRelated
This enables memory skills like openclaw-memory to maintain continuity across compaction events.
Greptile Overview
Greptile Summary
Adds two new internal hook events around Pi session compaction (
session:compact:preandsession:compact:post) so hooks can persist and restore agent working state across manual or automatic compaction. Implementation wires these events into the embedded Pi compaction flow (src/agents/pi-embedded-runner/compact.ts) and documents the new events and their context fields indocs/hooks.md.Confidence Score: 3/5
session:compact:precurrently fires after history is already pruned/replaced, which undermines the primary use-case (capturing full pre-compaction state). Additionally, hook errors are swallowed by the internal hook dispatcher so failures won’t be visible to callers.(2/5) Greptile learns from your feedback when you react with thumbs up/down!
Context used:
dashboard- CLAUDE.md (source)dashboard- AGENTS.md (source)