crates/hooks and is wired by crates/agent and crates/gateway.
The design goal is simple: the agent loop should know lifecycle phases and typed contributions. It should not need memory-specific, skills-specific, or future domain-specific branches for every side behavior.
Why Hooks Exist
Some work must happen around a turn but should not be part of the main model/tool loop:- classify turn policy before prompt assembly;
- add compact context before prompt compilation;
- contribute model-visible tool bundles;
- add prompt sections;
- run post-turn extraction or cleanup;
- persist hook-run diagnostics for recovery and audit.
Core Types
| Type | Role |
|---|---|
HookPhase | Stable lifecycle phase such as turn.pre_policy, turn.pre_prompt_context, turn.post_preflight_prompt_context, turn.pre_tool_materialization, turn.pre_prompt_compile, and turn.post_turn. |
HookHandler | A domain implementation subscribed to one or more phases. |
HookSubscription | Registration that binds a handler to a phase with priority, dependencies, execution policy, failure policy, and visibility. |
HookHandlerRequest | Typed input plus effective policy and prompt context sets for the phase. |
HookContribution | Typed output such as policy, prompt context, prompt section, tool bundle, audit, or background job metadata. |
HookRuntime | Executes subscriptions, applies ordering/dependencies/timeouts, validates capabilities, and aggregates responses. |
Turn Phases
The phase names are stable because they are also useful in diagnostics, hook-run persistence, and future operator tooling.Contributions
Hooks communicate through typed contributions instead of raw JSON blobs.| Contribution | Used for |
|---|---|
| Policy | Turn-scoped domain policy, such as memory read/write rules. |
| Prompt context | Structured context that later prompt hooks can consume. |
| Prompt section | Rendered prompt text with ordering and budget metadata. |
| Tool bundle | Model-visible tool declarations plus runtime routing metadata. |
| Audit/diagnostic | Safe metadata for debugging and persistence. |
| Background job | Non-blocking work recorded through hook-run persistence. |
Execution Policy
Each subscription has execution behavior:| Policy | Meaning |
|---|---|
Blocking | Wait for the hook before continuing. |
Deadline | Wait up to a bounded timeout and continue/fail according to failure policy. |
FireAndRecord | Start work without delaying the user-visible path, but record lifecycle. |
Background | Queue/record background work where supported. |
Dependencies And Ordering
Subscriptions are sorted by priority and id, but explicit dependencies are the important mechanism. A hook can say it must run after another subscription on the same phase. The runtime detects missing dependencies, disabled dependencies, and cycles. Memory uses phase ordering for recall: deterministic memory runs atturn.pre_prompt_context, then active memory runs at turn.post_preflight_prompt_context after the internal preflight plan has been built. The active hook receives typed prompt context plus the preflight-owned active recall plan or fallback.
Persistence And Recovery
Gateway hook-run persistence records lifecycle state for subscribed work:- started;
- completed;
- skipped;
- failed;
- timed out;
- backgrounded;
- latency and attempt metadata;
- safe diagnostics and contribution hashes.
Memory As A Hooked Domain
Agent memory is the first heavy domain built on this runtime:MemoryPolicyClassifierHookruns atturn.pre_policy.MemoryDeterministicRecallHookruns atturn.pre_prompt_context.ActiveMemoryRecallHookruns atturn.post_preflight_prompt_context.MemoryToolBundleHookruns atturn.pre_tool_materialization.MemoryPromptContractHookruns atturn.pre_prompt_compile.MemoryPostTurnExtractorHookruns atturn.post_turn.
Adding A Hook
When adding a hook:- Define typed input/output using existing hook request and contribution types where possible.
- Give the handler a stable id and kind.
- Declare only the capabilities it needs.
- Register it with a phase, priority, execution policy, failure policy, and visibility.
- Add tests for descriptor stability, capabilities, ordering/dependencies, policy behavior, and diagnostics.
- Keep domain decisions inside the hook or its domain service, not in the agent loop.
Related Pages
- Agent Loop shows where turn phases are dispatched.
- Memory Architecture shows a full domain built on hooks.
- Prompt And Context explains how prompt sections and context reach the provider.