Every agent framework implements hooks differently. Claude Code has shell-based hooks. Strands has steering callbacks. Spring AI has advisors. Your safety policy, logging, and steering logic gets rewritten for each one. Agent Hooks is a portable Java API that lets you write hook logic once and run it on any runtime that has an adapter. The core module has zero dependencies — it defines the event model, decision types, and registry. Adapters (Spring AI, Claude Agent SDK, and Gemini CLI) wire the core into their runtime’s tool-call lifecycle. Your hooks move with you when your agent infrastructure changes.Documentation Index
Fetch the complete documentation index at: https://lab.pollack.ai/llms.txt
Use this file to discover all available pages before exploring further.
Why Hooks
LLMs are probabilistic — prompt-based instructions drift under token pressure. Agents skip steps, forget constraints, and ignore guardrails. Hooks solve this by moving critical logic out of the prompt and into deterministic code that intercepts every tool call, the same way servlet filters intercept HTTP requests:- Safety — Block dangerous operations before they execute. A
Blockdecision short-circuits immediately and cannot be overridden by later hooks. - Observability — Log every tool call, capture timing data, and feed traces into Agent Journal for behavioral analysis.
- Steering — Modify tool inputs in flight. Subsequent hooks see the modified input, so transformations chain cleanly.
How It Works
Hooks intercept at two points in the tool-call lifecycle:Decision Model
HookDecision is a sealed type with four variants:
| Decision | When | Behavior |
|---|---|---|
Proceed | Default | Tool executes normally |
Block | Safety / policy | Short-circuits immediately — later hooks never run |
Modify | Input transformation | Passes modified input to the next hook in the chain |
Retry | AfterToolCall only | Re-executes the tool (e.g., after transient failure) |
Modules
| Module | What it does | Dependencies |
|---|---|---|
agent-hooks-core | Pure Java 17 API — events, decisions, registry | Zero (portable) |
agent-hooks-spring | Spring AI adapter — wraps ToolCallback with hook dispatch, auto-configures via Boot | Spring AI, Spring Boot |
agent-hooks-claude | Claude Agent SDK adapter — bridges hook providers to Claude CLI hooks via AgentHookBridge | Claude Code SDK (provided) |
agent-hooks-gemini | Gemini CLI adapter — stateless stdin/stdout dispatcher for Gemini’s subprocess-per-event model | Jackson (compile) |
Event Hierarchy
The event system is open (unsealed) — you can define custom events for your runtime:| Event | Interface | Decisions |
|---|---|---|
BeforeToolCall | ToolEvent | Proceed, Block, Modify |
AfterToolCall | ToolEvent | Proceed, Retry |
SessionStart | HookEvent | Observation only |
SessionEnd | HookEvent | Observation only |
UserPromptSubmit | HookEvent | Observation only (Claude adapter) |
AgentStop | HookEvent | Observation only (Claude adapter) |
SubagentStop | HookEvent | Observation only (Claude adapter) |
PreCompact | HookEvent | Observation only (Claude adapter) |
GeminiBeforeAgent | HookEvent | Observation only (Gemini adapter) |
GeminiAfterAgent | HookEvent | Observation only (Gemini adapter) |
GeminiBeforeModel | HookEvent | Observation only (Gemini adapter) |
GeminiAfterModel | HookEvent | Observation only (Gemini adapter) |
GeminiBeforeToolSelection | HookEvent | Observation only (Gemini adapter) |
GeminiNotification | HookEvent | Observation only (Gemini adapter) |
GeminiPreCompress | HookEvent | Observation only (Gemini adapter) |
Quick Start
Write Once, Run Anywhere
The sameAgentHookProvider works on all three runtimes — this is the core value proposition.
@Component bean, auto-configuration handles the rest:
HookRegistry:
HookOutput.
Tool call duration is tracked via wall-clock timing across the pre/post hook boundary.
Each Claude session gets its own HookContext for isolated state and history.
Gemini CLI — stateless subprocess dispatcher reads JSON from stdin:
HookEvent records.
HookContext is fresh per invocation — stateless hooks (security gates, audit logging) work out of the box.
Note: Gemini BeforeTool can only allow or block — Modify is downgraded to allow with a warning.
Documentation
Source Code
Core API, Spring AI adapter, Claude adapter, and Gemini adapter
Design Notes
Architecture decisions, event hierarchy, dispatch semantics
Used By
- Agent Workflow — hooks apply automatically to any workflow step that invokes tools
- Agent Journal — hook provider that logs tool-call events to a journal Run