← Back to PRs

#18004: feat: Add before_message_dispatch hook for blocking inbound messages

by Andy-Haigh open 2026-02-16 11:21 View on GitHub →
stale size: S
## 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