#7771: Hooks: wire lifecycle events and tests
channel: discord
channel: imessage
channel: signal
channel: slack
channel: telegram
app: web-ui
gateway
agents
stale
## Summary
- Emit session_start/session_end hooks with resume info + message counts
- Emit before/after compaction and gateway start/stop hook events
- Wire message_sending/message_sent hooks for outbound delivery + reply dispatcher
- Add unit tests for session and dispatcher hook payloads
- Include tool hook runner context with toolCallId
## Testing
- pnpm vitest run --config vitest.unit.config.ts src/auto-reply/reply/reply-dispatcher.hooks.test.ts src/auto-reply/reply/session.hooks.test.ts
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR wires additional plugin hook events across the agent lifecycle and outbound messaging pipeline. It adds a new unified `wrapToolWithHookRunner` to emit `before_tool_call`/`after_tool_call` (including `toolCallId`), emits `session_start`/`session_end` with resume info and message counts, emits compaction and gateway start/stop events, and adds unit tests validating dispatcher/session hook payloads.
Main things to double-check are behavioral differences in error handling: some new hook invocations are fire-and-forget without `.catch()` (risking unhandled rejections), and the new tool wrapper changes behavior when `before_tool_call` throws (it currently blocks tool execution, whereas the previous wrapper continued).
<h3>Confidence Score: 3/5</h3>
- Moderately safe to merge, but there are a couple of behavioral/error-handling issues worth addressing first.
- Most changes are additive hook emissions plus tests, but there are some non-trivial behavior changes: unhandled promise rejection risk from detached hook calls, and the new tool wrapper now fails tool execution if `before_tool_call` throws (likely unintended regression).
- src/agents/pi-tools.hooks.ts, src/auto-reply/reply/session.ts, src/auto-reply/reply/agent-runner.ts, src/infra/outbound/deliver.ts, src/auto-reply/reply/reply-dispatcher.ts
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</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
82.5%
#19565: feat: add agent lifecycle hook events (session, message, error)
by tag-assistant · 2026-02-17
81.8%
#19922: feat(hooks): add message:received and message:sent hook events
by NOVA-Openclaw · 2026-02-18
80.2%
#10109: feat(plugins): invoke message_received and message_sent hooks
by nezovskii · 2026-02-06
79.9%
#9906: feat: wire message_sending hook in outbound delivery
by teempai · 2026-02-05
79.3%
#8084: fix(plugins): wire up message_sending hook in outbound delivery
by lailoo · 2026-02-03
79.3%
#11597: feat(hooks): implement message:received hook
by gnufoo · 2026-02-08
79.2%
#15732: [AI-assisted] feat: emit agent:response internal hook after replies
by zontasticality · 2026-02-13
78.9%
#7301: fix(hooks): use resolveAgentIdFromSessionKey instead of split(":")[0]
by tsukhani · 2026-02-02
78.8%
#15571: feat: infrastructure foundation — hooks, model failover, sessions, ...
by tangcruz · 2026-02-13
78.7%