A hook callback subscribes to a specific event type and runs when that event fires during agent execution. This page is the reference for every event: when each one fires across the lifecycle, the full catalogue of event types, and which properties you can modify to change agent behavior. To write and register a callback, see [Hooks](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md).

## Hook Event Lifecycle

### Single-Agent Lifecycle

The following diagram shows when hook events are emitted during a typical agent invocation where tools are invoked:

(( tab "Python" ))
> **Diagram:** Hook events in a single-agent invocation, in Python. Each stage groups its events in firing order. Request start: BeforeInvocationEvent, then MessageAddedEvent for the user's prompt. Then the agent loop. Model call: BeforeModelCallEvent, AfterModelCallEvent, then MessageAddedEvent for the model's message. If the model makes tool calls, tool execution runs: BeforeToolsEvent; then, for each tool call, BeforeToolCallEvent and AfterToolCallEvent; then AfterToolsEvent and MessageAddedEvent for the tool results, which go back to the model for the next model call. When the model makes no tool calls, the loop exits to request end: AfterInvocationEvent.
(( /tab "Python" ))

(( tab "TypeScript" ))
> **Diagram:** Hook events in a single-agent invocation, in TypeScript. Each stage groups its events in firing order. Request start: BeforeInvocationEvent, then MessageAddedEvent for the user's prompt. Then the agent loop. Model call: BeforeModelCallEvent, then ModelStreamUpdateEvent and ContentBlockEvent while the response streams, ModelMessageEvent, and AfterModelCallEvent. If the model makes tool calls, tool execution runs: BeforeToolsEvent; then, for each tool call, BeforeToolCallEvent, ToolStreamUpdateEvent, AfterToolCallEvent, and ToolResultEvent; then AfterToolsEvent, MessageAddedEvent for the model's message, and MessageAddedEvent for the tool results, which go back to the model for the next model call. When the model makes no tool calls, MessageAddedEvent fires for the model's message as the loop exits, and the request ends: AfterInvocationEvent, then AgentResultEvent. If tool execution is interrupted, InterruptEvent fires once per unanswered interrupt before the request ends.
(( /tab "TypeScript" ))

### Multi-Agent Lifecycle

The following diagram shows when multi-agent hook events are emitted during orchestrator execution:

(( tab "Python" ))
> **Diagram:** Multi-agent hook events, in Python. Each stage groups its events in firing order. Initialization, once when the orchestrator is initialized: MultiAgentInitializedEvent. Then, for each invocation: invocation start, BeforeMultiAgentInvocationEvent; node execution, BeforeNodeCallEvent and AfterNodeCallEvent for every node the orchestrator runs, repeating for the next node; and invocation end, AfterMultiAgentInvocationEvent.
(( /tab "Python" ))

(( tab "TypeScript" ))
> **Diagram:** Multi-agent hook events, in TypeScript. Each stage groups its events in firing order. Initialization, once when the orchestrator is initialized: MultiAgentInitializedEvent. Then, for each invocation: invocation start, BeforeMultiAgentInvocationEvent; node execution, BeforeNodeCallEvent, NodeStreamUpdateEvent while the node streams, NodeResultEvent, and AfterNodeCallEvent for every node the orchestrator runs; when execution moves on to the next node, MultiAgentHandoffEvent fires and node execution repeats; and invocation end, AfterMultiAgentInvocationEvent, then MultiAgentResultEvent.
(( /tab "TypeScript" ))

### Available Events

(( tab "Python" ))
| Event | Description |
| --- | --- |
| `AgentInitializedEvent` | Triggered when an agent has been constructed and finished initialization at the end of the agent constructor. |
| `BeforeInvocationEvent` | Triggered at the beginning of a new agent invocation request |
| `AfterInvocationEvent` | Triggered at the end of an agent request, regardless of success or failure. Uses reverse callback ordering |
| `MessageAddedEvent` | Triggered when a message is added to the agent’s conversation history |
| `BeforeModelCallEvent` | Triggered before the model is invoked for inference |
| `AfterModelCallEvent` | Triggered after model invocation completes. Uses reverse callback ordering |
| `BeforeToolsEvent` | Triggered before tools are executed in a batch |
| `BeforeToolCallEvent` | Triggered before a tool is invoked |
| `AfterToolCallEvent` | Triggered after tool invocation completes. Uses reverse callback ordering |
| `AfterToolsEvent` | Triggered after tools are executed in a batch. Uses reverse callback ordering |
| `MultiAgentInitializedEvent` | Triggered when multi-agent orchestrator is initialized |
| `BeforeMultiAgentInvocationEvent` | Triggered before orchestrator execution starts |
| `AfterMultiAgentInvocationEvent` | Triggered after orchestrator execution completes. Uses reverse callback ordering |
| `BeforeNodeCallEvent` | Triggered before individual node execution starts |
| `AfterNodeCallEvent` | Triggered after individual node execution completes. Uses reverse callback ordering |
(( /tab "Python" ))

(( tab "TypeScript" ))
All events extend `HookableEvent`, making them both streamable via `agent.stream()` and subscribable via hook callbacks.

| Event | Description |
| --- | --- |
| `AgentInitializedEvent` | Triggered when an agent has been constructed and finished initialization at the end of the agent constructor. |
| `BeforeInvocationEvent` | Triggered at the beginning of a new agent invocation request |
| `AfterInvocationEvent` | Triggered at the end of an agent request, regardless of success or failure. Uses reverse callback ordering |
| `MessageAddedEvent` | Triggered when a message is added to the agent’s conversation history |
| `BeforeModelCallEvent` | Triggered before the model is invoked for inference |
| `AfterModelCallEvent` | Triggered after model invocation completes. Uses reverse callback ordering |
| `ModelStreamUpdateEvent` | Wraps each transient streaming delta from the model during inference. Access via `.event` |
| `ContentBlockEvent` | Wraps a fully assembled content block (TextBlock, ToolUseBlock, ReasoningBlock). Access via `.contentBlock` |
| `ModelMessageEvent` | Wraps the complete model message after all blocks are assembled. Access via `.message` |
| `BeforeToolCallEvent` | Triggered before a tool is invoked |
| `AfterToolCallEvent` | Triggered after tool invocation completes. Uses reverse callback ordering |
| `BeforeToolsEvent` | Triggered before tools are executed in a batch |
| `AfterToolsEvent` | Triggered after tools are executed in a batch. Uses reverse callback ordering |
| `ToolStreamUpdateEvent` | Wraps streaming progress events from tool execution. Access via `.event` |
| `ToolResultEvent` | Wraps a completed tool result. Access via `.result` |
| `AgentResultEvent` | Wraps the final agent result at the end of the invocation. Access via `.result` |
| `InterruptEvent` | Fires once per unanswered interrupt when the agent halts to wait for responses. Access via `.interrupt` |
| `MultiAgentInitializedEvent` | Triggered when a multi-agent orchestrator has finished initialization |
| `BeforeMultiAgentInvocationEvent` | Triggered before orchestrator execution starts |
| `AfterMultiAgentInvocationEvent` | Triggered after orchestrator execution completes. Uses reverse callback ordering |
| `BeforeNodeCallEvent` | Triggered before individual node execution starts |
| `NodeStreamUpdateEvent` | Wraps an inner streaming event from a node with the node’s identity. Access via `.event` |
| `NodeCancelEvent` | Triggered when a node is cancelled via `BeforeNodeCallEvent.cancel` |
| `AfterNodeCallEvent` | Triggered after individual node execution completes. Uses reverse callback ordering |
| `NodeResultEvent` | Wraps a completed node result. Access via `.result` |
| `MultiAgentHandoffEvent` | Triggered when execution transitions between nodes |
| `MultiAgentResultEvent` | Wraps the final multi-agent result at the end of orchestration. Access via `.result` |
(( /tab "TypeScript" ))

## Event Properties

Most event properties are read-only to prevent unintended modifications. However, certain properties can be modified to influence agent behavior:

(( tab "Python" ))
-   [`AfterModelCallEvent`](/pr-cms-5317/docs/api/python/strands.hooks.events#AfterModelCallEvent)
    
    -   `retry` - Request a retry of the model invocation. See [Model Call Retry](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#model-call-retry).
-   [`BeforeToolsEvent`](/pr-cms-5317/docs/api/python/strands.hooks.events#BeforeToolsEvent)
    
    -   `cancel` - Cancel all tool calls in the batch with a message. See [Limit Tool Counts](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#limit-tool-counts).
-   [`BeforeToolCallEvent`](/pr-cms-5317/docs/api/python/strands.hooks.events#BeforeToolCallEvent)
    
    -   `cancel_tool` - Cancel tool execution with a message. See [Limit Tool Counts](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#limit-tool-counts).
    -   `selected_tool` - Replace the tool to be executed. See [Tool Interception](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#tool-interception).
    -   `tool_use` - Modify tool parameters before execution. See [Fixed Tool Arguments](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#fixed-tool-arguments).
-   [`AfterToolCallEvent`](/pr-cms-5317/docs/api/python/strands.hooks.events#AfterToolCallEvent)
    
    -   `result` - Modify the tool result. See [Result Modification](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#result-modification).
    -   `retry` - Request a retry of the tool invocation. See [Tool Call Retry](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#tool-call-retry).
    -   `exception` *(read-only)* - The original exception if the tool raised one, otherwise `None`. See [Exception Handling](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#exception-handling).
-   [`AfterToolsEvent`](/pr-cms-5317/docs/api/python/strands.hooks.events#AfterToolsEvent)
    
    -   `end_turn` - Halt the agent loop after the tool batch without calling the model again. Set `True` for a default final assistant message, a string to use as the final assistant message, or a list of content blocks to use as the final assistant message content directly. The returned result has `stop_reason="end_turn"`.
-   [`AfterInvocationEvent`](/pr-cms-5317/docs/api/python/strands.hooks.events#AfterInvocationEvent)
    
    -   `resume` - Trigger a follow-up agent invocation with new input. See [Invocation resume](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#invocation-resume).
(( /tab "Python" ))

(( tab "TypeScript" ))
-   `BeforeInvocationEvent`
    
    -   `cancel` - Cancel the agent invocation with a message.
-   `BeforeModelCallEvent`
    
    -   `cancel` - Cancel the model call with a message.
-   `BeforeToolsEvent`
    
    -   `cancel` - Cancel all tool calls in a batch with a message. See [Limit Tool Counts](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#limit-tool-counts).
-   `BeforeToolCallEvent`
    
    -   `cancel` - Cancel tool execution with a message. See [Limit Tool Counts](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#limit-tool-counts).
    -   `selectedTool` - Replace the tool to be executed with a different `Tool` instance. See [Tool Interception](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#tool-interception).
    -   `toolUse` - Mutable. Rewrite `name`, `toolUseId`, or `input` before execution. Renaming `name` re-resolves the tool from the registry when `selectedTool` is not set. See [Fixed Tool Arguments](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#fixed-tool-arguments).
-   `AfterModelCallEvent`
    
    -   `retry` - Request a retry of the model invocation.
-   `AfterToolCallEvent`
    
    -   `retry` - Request a retry of the tool invocation.
    -   `result` - Mutable. Rewrite the `ToolResultBlock` before it propagates to the model. See [Result Modification](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#result-modification).
-   `AfterToolsEvent`
    
    -   `endTurn` - Halt the agent loop after the tool batch without calling the model again. Set `true` for a default final assistant message, a string to use as the final assistant message, or a list of content blocks to use as the final assistant message content directly. The returned result has `stopReason="endTurn"`.
-   `AfterInvocationEvent`
    
    -   `resume` - Trigger a follow-up agent invocation with new input. Setting it re-enters the agent loop under the same invocation lock. See [Invocation resume](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md#invocation-resume).
(( /tab "TypeScript" ))

## Next Steps

-   Write and register a callback against any of these events in [Hooks](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md).
-   Bundle several callbacks together with [Plugins](/pr-cms-5317/docs/user-guide/sdk/plugins/index.md).
-   See the Agent API Reference for complete method documentation: [Python](/pr-cms-5317/docs/api/python/strands.agent.agent) | [TypeScript](/pr-cms-5317/docs/api/typescript/Agent/index.md)

## Related pages

- [Agent Loop](/pr-cms-5317/docs/user-guide/sdk/agents/agent-loop/index.md) (3 shared tags)
- [Hooks](/pr-cms-5317/docs/user-guide/sdk/agents/hooks/index.md) (3 shared tags)
- [Interrupts](/pr-cms-5317/docs/user-guide/sdk/interrupts/index.md) (3 shared tags)
- [Steering](/pr-cms-5317/docs/user-guide/sdk/agents/interventions/steering/index.md) (3 shared tags)
- [Interventions](/pr-cms-5317/docs/user-guide/sdk/agents/interventions/index.md) (3 shared tags)
- [Build a custom plugin](/pr-cms-5317/docs/user-guide/sdk/plugins/custom-plugins/index.md) (2 shared tags)
- [Plugins](/pr-cms-5317/docs/user-guide/sdk/plugins/index.md) (2 shared tags)
- [Middleware](/pr-cms-5317/docs/user-guide/sdk/agents/middleware/index.md) (2 shared tags)
- [Tool Executors](/pr-cms-5317/docs/user-guide/sdk/tools/executors/index.md) (2 shared tags)
- [GoalLoop](/pr-cms-5317/docs/user-guide/sdk/plugins/goal-loop/index.md) (2 shared tags)


## Implementation

### Python

- [harness-sdk/strands-py/src/strands/hooks/events.py](https://github.com/strands-agents/harness-sdk/blob/main/strands-py/src/strands/hooks/events.py)

### TypeScript

- [harness-sdk/strands-ts/src/hooks/events.ts](https://github.com/strands-agents/harness-sdk/blob/main/strands-ts/src/hooks/events.ts)
