#18004: feat: Add before_message_dispatch hook for blocking inbound messages
stale
size: S
Cluster:
Plugin and Hook Enhancements
## Summary
This PR adds a new `before_message_dispatch` hook that runs after `message_received` but before agent/LLM processing. This allows plugins to:
- **Block messages** before incurring LLM costs (useful for permission systems, rate limiting)
- **Send direct responses** instead of calling the agent
- **Pass context downstream** via `HookContext` for use by subsequent processing
## Use Cases
- Permission systems that need to validate users before allowing queries
- Rate limiting that blocks excessive requests
- Content filtering for inappropriate messages
- Pre-processing that may need to short-circuit message handling
## Hook Interface
**Event** (input):
```typescript
{
from: string; // Sender identifier
content: string; // Message content
sessionKey?: string; // Session key for conversation
senderId?: string; // Platform-specific sender ID
senderName?: string; // Display name
senderUsername?: string;// Username/handle
threadId?: string; // Thread ID if in a thread
timestamp?: number; // Message timestamp
metadata?: Record<string, unknown>; // Platform-specific metadata
}
```
**Result** (output):
```typescript
{
block?: boolean; // If true, stop processing
blockReason?: string; // Reason for blocking (for logging)
response?: string; // Direct response to send instead
context?: Record<string, unknown>; // Context to pass downstream
}
```
## Changes
- `src/plugins/types.ts` - Added types for the new hook
- `src/plugins/hooks.ts` - Added `runBeforeMessageDispatch` runner function
- `src/auto-reply/reply/dispatch-from-config.ts` - Added hook call site
## Testing
- TypeScript compilation passes
- Hook is opt-in (only runs if plugins register handlers)
- Graceful error handling (continues on hook failure)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds a new `before_message_dispatch` hook that runs after `message_received` but before agent/LLM processing, enabling plugins to block messages, send direct responses, or pass context downstream.
**Key Changes:**
- New hook types in `src/plugins/types.ts` with event/result interfaces
- Runner function in `src/plugins/hooks.ts` with sequential execution and result merging
- Integration in `src/auto-reply/reply/dispatch-from-config.ts` that blocks messages when `block: true`
**Behavioral Notes:**
- All handlers run sequentially (no early exit when blocked)
- Results merge with `next.block ?? acc?.block` pattern - once any handler blocks, the message stays blocked
- Hook errors are caught and logged without blocking message processing
- The `context` field is documented but not currently consumed downstream
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge with low risk
- The implementation follows established patterns for modifying hooks, includes proper error handling, and is opt-in. Two pre-existing issues were already flagged in previous review threads. The merge logic ensures blocking is sticky (once blocked, stays blocked), which is reasonable for a security-oriented hook.
- No files require special attention - previous review threads already cover the two existing concerns
<sub>Last reviewed commit: 09d6f89</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#10539: feat(hooks): add blocking capability to message_received hookFeat/m...
by khalidovicGPT · 2026-02-06
85.5%
#20067: feat(plugins): add before_agent_reply hook for message interception
by JoshuaLelon · 2026-02-18
83.7%
#14544: feat: add before_context_send plugin hook
by Windelly · 2026-02-12
81.5%
#11124: feat(plugins): add before_llm_request hook for custom LLM headers
by johnlanni · 2026-02-07
80.5%
#11681: feat(plugins): add cancel support to message_received hook
by PrimeTenet · 2026-02-08
79.7%
#22624: feat(plugins): add before_context_send hook and model routing via b...
by davidrudduck · 2026-02-21
79.5%
#7545: feat(hooks): add message:received hook for pre-turn automation
by wangtian24 · 2026-02-02
79.4%
#7580: feat: add message:received internal hook with prompt injection
by rodrigoschott · 2026-02-03
79.0%
#19922: feat(hooks): add message:received and message:sent hook events
by NOVA-Openclaw · 2026-02-18
78.6%
#15577: feat(hooks): add message:preprocessed hook event
by heybeaux · 2026-02-13
78.5%