Hooks
Hooks let you insert custom logic before and after each agent step — logging, dynamically modifying configuration, early loop termination, error handling — for fine-grained control over the execution flow.
During execution, an agent goes through multiple steps — model reasoning, tool calls, structured output. Hooks let you insert custom logic at key points in this flow, enabling logging, dynamic configuration, flow control, and error handling without modifying core code. Whether tracking each step's execution state or switching models based on runtime conditions, Hooks provide a clean and powerful extension mechanism.
Three Hooks
deepseek-kit provides three lifecycle hooks covering the complete agent execution flow:
| Hook | Trigger | Typical Use |
|---|---|---|
beforeStep | Before each step starts | Logging, dynamic config modification, early termination |
afterStep | After each step completes | Logging, result tracking, early termination |
onError | When a step execution error occurs | Error handling, custom error transformation |
Additionally, four Compact Hooks are available for controlling the context compaction process:
| Hook | Trigger | Typical Use |
|---|---|---|
beforeMessageCompact | Before conversation history is compacted | Skip compaction, early termination, logging |
afterMessageCompact | After conversation history is compacted | Quality inspection, metrics tracking |
beforeToolCompact | Before a tool result is compacted | Skip compaction, early termination, logging |
afterToolCompact | After a tool result is compacted | Quality inspection, metrics tracking |
beforeStep — Pre-Step Interception
beforeStep is called before each step starts, receiving the current step's context information and HookContext. You can use it to:
- Log execution progress
- Dynamically modify the current step's configuration
- Replace the current step's messages or tools
- Terminate the loop early
Parameters
beforeStep receives two parameters:
context— Current step's context informationhookCtx— Hook context, providing thestop()method
Logging
The simplest usage is logging the start of each step:
Dynamic Configuration Modification
beforeStep can return an object to modify the current step's configuration. The returned object is merged with the default configuration:
This switches the agent to the Pro model after step 6. Modifiable configuration items include:
config— Model configuration (model, temperature, maxTokens, etc.)messages— Message list for the current steptools— Available tools for the current step
Dynamic Tool Selection
Dynamically adjust available tools based on step number or context:
Modifying Messages
Inject additional messages before a specific step:
Early Termination
You can terminate the agent's execution loop early via hookCtx.stop() in any hook:
After calling stop(), the agent immediately ends the loop and returns the current results. This is useful when you need custom termination conditions.
afterStep — Post-Step Processing
afterStep is called after each step completes, receiving the step result and HookContext. The step type determines what information is available in the result:
Step Types
| Type | Description | Available Fields |
|---|---|---|
'tool' | Tool call step | toolCalls, text, usage |
'text' | Text generation step | text, usage |
'format' | Structured output step | text, usage |
Logging
Log the execution result of each step:
Token Usage Tracking
Track cumulative token consumption via afterStep:
Tool Call Monitoring
Specifically monitor tool call steps:
Early Termination
afterStep also supports early termination via hookCtx.stop():
onError — Error Handling
onError is called when a step execution error occurs, receiving an AgentError and HookContext. You can use it to:
- Log error information
- Customize error transformation
- Decide whether to continue execution based on error type
Error Types
AgentError contains a type field identifying the error category:
| Type | Description | Retryable |
|---|---|---|
'rate_limit' | API rate limit | ✅ |
'model_error' | Model returned error | ✅ |
'timeout' | Request timeout | ✅ |
'network_error' | Network connection error | ✅ |
'tool_error' | Tool execution error | ❌ |
'max_steps' | Maximum steps reached | ❌ |
'schema_error' | Structured output validation failure | ❌ |
Logging
Log error information for debugging:
Custom Error Transformation
onError can return a new AgentError to replace the original error, or return undefined to suppress the error (allowing the loop to continue):
Return value rules:
- Return
undefined— Suppress the error, the loop continues to the next step - Return
AgentError— Replace the original error with the new one; ifhookCtx.stop()is called, the loop terminates - Return nothing (void) — The original error continues to be thrown
Early Termination
Combining hookCtx.stop() in onError enables graceful termination when specific errors occur:
Compact Hooks
When the agent's context window approaches its limit, deepseek-kit automatically compacts conversation history and tool results to free up space. Compact Hooks let you observe and control this compaction process.
beforeMessageCompact — Pre-Compaction Interception
beforeMessageCompact is called before conversation history is compacted. You can use it to:
- Log compaction events (token count, threshold, etc.)
- Skip compaction for the current step via
hookCtx.skip() - Terminate the agent loop via
hookCtx.stop()
Skip Compaction
In some scenarios (e.g., code generation tasks), you may not want to lose conversation details. Use hookCtx.skip() to skip compaction for the current step:
After skip(), the agent continues normally without compacting. The skip state is automatically reset after each compaction decision.
Terminate on Compaction
If you want to stop the agent entirely when compaction would occur:
afterMessageCompact — Post-Compaction Processing
afterMessageCompact is called after conversation history has been compacted. You can use it to:
- Inspect the compaction result (messages before/after)
- Track token savings
- Validate summary quality
beforeToolCompact — Pre-Tool-Result-Compaction Interception
beforeToolCompact is called before a tool result is compacted. Similar to beforeMessageCompact, it supports skip() and stop():
afterToolCompact — Post-Tool-Result-Compaction Processing
afterToolCompact is called after a tool result has been compacted:
HookContext: stop() and skip()
HookContext provides two control methods:
| Method | Effect | Scope |
|---|---|---|
stop() | Terminate the entire agent loop | Permanent — the loop ends immediately |
skip() | Skip the current compaction operation | One-time — automatically resets after each decision |
skip() can be called from any hook, but it only takes effect in compact hooks (beforeMessageCompact and beforeToolCompact). Calling skip() in beforeStep or afterStep has no effect.
Combining Hooks
The three hooks are typically used together to build complete observability and control logic:
Complete Logging Middleware
Dynamic Model Switching
Dynamically switch models based on step progress — using a fast model early on, then switching to a high-precision model later:
Step Limits and Graceful Degradation
Gracefully terminate when there are too many steps, rather than throwing an error directly:
Token Budget Control
Set a token budget and terminate early when it's exceeded:
Execution Flow
The following shows when hooks are triggered in the agent loop:
beforeStep and afterStep are also triggered during structured output steps, where the step type is 'format'. During structured output retries, hooks are triggered for each retry attempt.
API Reference
GenerateTextHooks
undefined to suppress the error, or return a new AgentError to replace the original. hookCtx.skip() to skip compaction and hookCtx.stop() to terminate the loop. hookCtx.skip() to skip compaction and hookCtx.stop() to terminate the loop. BeforeStepContext
messages in the return value replaces the current step's messages. tools in the return value replaces the current step's tools. BeforeStepResult
model, temperature, maxTokens, thinking, etc. StepEvent
'tool' for tool call steps, 'text' for text generation steps, 'format' for structured output steps. 'tool' type steps). HookContext
beforeMessageCompact and beforeToolCompact hooks. The skip state is automatically reset after each compaction decision, so it only affects the current compaction. BeforeMessageCompactContext
0.85 means compaction triggers at 85% of context window). MessageCompactEvent
BeforeToolCompactContext
ToolCompactEvent
AgentError
'rate_limit', 'model_error', 'timeout', 'network_error', 'tool_error', 'max_steps', 'schema_error'. 'rate_limit', 'model_error', 'timeout', and 'network_error' errors are retryable by default. 
