#6103: feat(hooks): add agent:context_overflow event for context death handling
agents
## Summary
Add a new hook event `agent:context_overflow` that fires when an agent hits context overflow, allowing external tools (like ClawVault) to capture session state before the agent dies.
## Motivation
When an agent hits context limits, the session typically resets and all state is lost. External tools like ClawVault need to capture session state *before* the reset happens, but currently there's no hook to detect this moment.
This PR adds an event that fires at the critical moment between detecting overflow and resetting the session, enabling:
- Emergency session state saves
- Context death analytics
- Custom recovery strategies
- State handoff for session continuity
## Changes
### New Types (`src/hooks/internal-hooks.ts`)
- `AgentContextOverflowHookContext` - typed context for the event
- `AgentContextOverflowHookEvent` - typed event definition
- `isAgentContextOverflowEvent()` - type guard for event handling
### Event Emission
- `src/agents/pi-embedded-runner/run.ts`: Emit event when overflow is detected and returned as error payload
- `src/auto-reply/reply/agent-runner-execution.ts`: Emit event when overflow is thrown as exception
### Documentation
- Updated `src/hooks/bundled/README.md` with full event documentation
## Context Fields
| Field | Type | Description |
|-------|------|-------------|
| `sessionId` | string | The session ID that overflowed |
| `sessionFile` | string | Path to the session transcript file |
| `provider` | string | Model provider (e.g., "anthropic") |
| `model` | string | Model ID (e.g., "claude-sonnet-4-20250514") |
| `errorMessage` | string | Raw error message from the provider |
| `isCompactionFailure` | boolean | True if overflow occurred during compaction |
| `autoCompactionAttempted` | boolean | True if auto-compaction was tried |
| `thrownAsException` | boolean | True if thrown vs returned as payload |
## Usage Example
```typescript
import { registerHook, isAgentContextOverflowEvent } from './hooks/hooks.js';
registerHook('agent:context_overflow', async (event) => {
if (!isAgentContextOverflowEvent(event)) return;
const { sessionId, sessionFile, provider, model } = event.context;
// Save session state before it's lost
await emergencySave({
sessionId,
sessionFile,
metadata: { provider, model, timestamp: event.timestamp }
});
});
```
## Testing
The event is emitted via `void triggerInternalHook()` (fire-and-forget) to avoid blocking the error handling flow. Hooks can be tested by:
1. Registering a handler for `agent:context_overflow`
2. Triggering context overflow (e.g., very long prompt)
3. Verifying the handler receives the expected context
## Related
This enables ClawVault's `emergency-save` feature for automatic state capture on context death.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR adds a new internal hook event `agent:context_overflow` and emits it from both embedded-agent overflow payload handling (`src/agents/pi-embedded-runner/run.ts`) and exception-based overflow handling (`src/auto-reply/reply/agent-runner-execution.ts`). It also introduces typed context/event definitions plus a type guard in `src/hooks/internal-hooks.ts`, and documents the new event in `src/hooks/bundled/README.md` so bundled/custom hooks can react (e.g., to save session state before reset).
Key integration points:
- The embedded runner emits the event when it detects provider context overflow while building a user-facing error payload.
- The agent runner emits the event when overflow is thrown as an exception before a reply is produced.
- Hook consumers can register for `agent:context_overflow` using the existing internal hook registry/dispatcher.
<h3>Confidence Score: 3/5</h3>
- Reasonably safe, but hook payload consistency/identifiers need attention before relying on this in production tooling.
- The change is localized and uses the existing internal hook dispatch mechanism, but one emission path uses an empty `sessionKey` and another omits `provider`/`model`, while docs imply those fields exist. These inconsistencies can break downstream hook consumers even though core runtime behavior likely remains unchanged.
- src/auto-reply/reply/agent-runner-execution.ts, src/hooks/bundled/README.md, src/hooks/internal-hooks.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
**Context used:**
- Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8))
- Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13))
<!-- /greptile_comment -->
Most Similar PRs
#6630: feat(hooks): add agent:turn_start and agent:turn_end lifecycle events
by drdigital13 · 2026-02-01
78.8%
#9677: feat: expose incomingMessage in bootstrap hook context
by speedbal · 2026-02-05
78.0%
#19565: feat: add agent lifecycle hook events (session, message, error)
by tag-assistant · 2026-02-17
77.6%
#19922: feat(hooks): add message:received and message:sent hook events
by NOVA-Openclaw · 2026-02-18
77.0%
#7771: Hooks: wire lifecycle events and tests
by rabsef-bicrym · 2026-02-03
76.5%
#7580: feat: add message:received internal hook with prompt injection
by rodrigoschott · 2026-02-03
76.4%
#20268: feat(hooks): emit subagent:complete internal hook event
by AytuncYildizli · 2026-02-18
76.2%
#20418: feat(hooks): add session:pre-spawn and agent:pre-run hook events
by NOVA-Openclaw · 2026-02-18
75.7%
#13861: feat(hooks): add session:compaction hook event
by lailoo · 2026-02-11
74.8%
#7091: feat: add pre-answer hooks system for automatic context injection
by dizhaky · 2026-02-02
74.7%