#7091: feat: add pre-answer hooks system for automatic context injection
docs
size: XS
## Summary
Add a pre-answer hooks system that runs custom logic before an agent generates a response. This enables automatic context retrieval from external systems (e.g., memory search, RAG, database lookups) and injection into the agent's working memory.
## Motivation
Agents should be aware of persistent context across sessions without manual intervention. This feature institutionalizes memory awareness by automatically searching the memory graph before answering questions.
## Implementation
### New Files
- `src/agents/agent-hooks-types.ts` - Hook interfaces and types
- `src/agents/agent-hooks-registry.ts` - Hook registry with global singleton
- `src/agents/hooks/memory-search-hook.ts` - Memory search hook implementation
- `src/agents/agent-hooks.ts` - Export aggregation
- `docs/concepts/pre-answer-hooks.md` - Documentation
### Modified Files
- `src/auto-reply/reply/agent-runner.ts` - Hook registration and execution before `runAgentTurnWithFallback`
### Key Changes
1. Hook infrastructure with priority-based execution
2. Memory search hook that queries Memory Gateway (via mcporter HTTP API)
3. Hook execution timeout (30s default)
4. Diagnostic event emission for hook execution tracking
5. Context injection into command body before agent turn
## Usage
```typescript
// Hooks register themselves via the global registry
preAnswerHookRegistry.register(memorySearchHook);
// Hooks execute automatically before agent turns
const fragments = await preAnswerHookRegistry.executeAndCollect(params);
const enhancedCommandBody = `${context}\n\n${commandBody}`;
```
## Configuration (Future)
```json
{
"preAnswerHooks": {
"enabled": true,
"hooks": {
"memory-search": {
"enabled": true,
"config": {
"maxResults": 10,
"timeoutMs": 10000
}
}
}
}
}
```
## Benefits
- Automatic context enrichment without manual tool calls
- Composable hook system for multiple data sources
- Non-intrusive: Hooks run invisibly behind existing flow
- Extensible: Easy to add RAG, database, API call hooks
## Testing
- Manual testing with local development setup
- Pending: Unit tests for hook registry and execution
- Pending: Integration tests for memory search hook
## Breaking Changes
None - hooks are opt-in via registration
## Documentation
- `docs/concepts/pre-answer-hooks.md` - Configuration and usage guide
Closes #[TBD]
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR introduces a pre-answer hook system that runs before `runAgentTurnWithFallback` in `src/auto-reply/reply/agent-runner.ts`, allowing hooks to return weighted context fragments that get injected ahead of the user’s `commandBody`. It adds a registry (`src/agents/agent-hooks-registry.ts`) and shared types (`src/agents/agent-hooks-types.ts`), exports them via `src/agents/agent-hooks.ts`, and includes an initial built-in `memory-search` hook that calls a Memory Gateway endpoint and formats results into injected prompt fragments.
Main integration point is `runReplyAgent`, which now registers the built-in hook once per process and executes enabled hooks to build an `enhancedCommandBody`. Diagnostics optionally emit a custom event summarizing hook execution.
Key issues to address before merge:
- The memory hook’s imports/require paths are incorrect relative to its folder, which will break builds/runtime.
- `globalThis.openclawHooksRegistered` is used without any TS global typing, which can cause typecheck failures.
- Diagnostic event shape is cast to `any`, risking schema drift vs existing diagnostic consumers/docs.
- Docs include environment-specific paths that conflict with repo docs guidelines.
<h3>Confidence Score: 2/5</h3>
- Not safe to merge as-is due to a build/runtime-breaking import path issue in the new memory hook and likely TS typing issues around global state.
- The hook registry design is straightforward, but `memory-search-hook.ts` currently references non-existent relative paths (will fail immediately when imported/registered). Additionally, `globalThis.openclawHooksRegistered` is untyped and may fail TS builds, and diagnostic emission uses `as any`, which can silently break downstream tooling.
- src/agents/hooks/memory-search-hook.ts, src/auto-reply/reply/agent-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
#10591: feat(hooks): add session-start-memory bundled hook
by morningstar-daemon · 2026-02-06
82.7%
#11732: feat(plugins): add injectMessages to before_agent_start hook
by antra-tess · 2026-02-08
78.8%
#7580: feat: add message:received internal hook with prompt injection
by rodrigoschott · 2026-02-03
78.1%
#7545: feat(hooks): add message:received hook for pre-turn automation
by wangtian24 · 2026-02-02
77.9%
#11921: feat(hooks): support systemPrompt injection in before_agent_start hook
by jungdaesuh · 2026-02-08
77.6%
#8919: Pr/memory flush improvements
by shortbus · 2026-02-04
77.3%
#7771: Hooks: wire lifecycle events and tests
by rabsef-bicrym · 2026-02-03
77.2%
#22705: fix(agents): merge before_agent_start hook systemPrompt into sessio...
by mushuiyu422 · 2026-02-21
77.0%
#19565: feat: add agent lifecycle hook events (session, message, error)
by tag-assistant · 2026-02-17
76.8%
#11597: feat(hooks): implement message:received hook
by gnufoo · 2026-02-08
76.7%