Skip to content

Commit 0997f72

Browse files
authored
Update documentation for production-ready hooks (#267)
In strands-agents/sdk-python/pull/926 we've released these hooks (and done a rename) so update the docs to account for it Part of strands-agents/sdk-python#667 Co-authored-by: Mackenzie Zastrow <zastrowm@users.noreply.github.com>
1 parent d8b83ab commit 0997f72

File tree

1 file changed

+24
-34
lines changed

1 file changed

+24
-34
lines changed

docs/user-guide/concepts/agents/hooks.md

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Hooks enable use cases such as:
1616

1717
## Basic Usage
1818

19-
Hook callbacks are registered against specific event types and receive strongly-typed event objects when those events occur during agent execution. Each event carries relevant data for that stage of the agent lifecycle - for example, `BeforeInvocationEvent` includes agent and request details, while `BeforeToolInvocationEvent` provides tool information and parameters.
19+
Hook callbacks are registered against specific event types and receive strongly-typed event objects when those events occur during agent execution. Each event carries relevant data for that stage of the agent lifecycle - for example, `BeforeInvocationEvent` includes agent and request details, while `BeforeToolCallEvent` provides tool information and parameters.
2020

2121
### Registering Individual Hook Callbacks
2222

@@ -69,19 +69,19 @@ flowchart LR
6969
end
7070
subgraph Model["Model Events"]
7171
direction TB
72-
AfterModelInvocationEvent["AfterModelInvocationEvent"]
73-
BeforeModelInvocationEvent["BeforeModelInvocationEvent"]
72+
AfterModelCallEvent["AfterModelCallEvent"]
73+
BeforeModelCallEvent["BeforeModelCallEvent"]
7474
ModelMessage["MessageAddedEvent"]
75-
BeforeModelInvocationEvent --> AfterModelInvocationEvent
76-
AfterModelInvocationEvent --> ModelMessage
75+
BeforeModelCallEvent --> AfterModelCallEvent
76+
AfterModelCallEvent --> ModelMessage
7777
end
7878
subgraph Tool["Tool Events"]
7979
direction TB
80-
AfterToolInvocationEvent["AfterToolInvocationEvent"]
81-
BeforeToolInvocationEvent["BeforeToolInvocationEvent"]
80+
AfterToolCallEvent["AfterToolCallEvent"]
81+
BeforeToolCallEvent["BeforeToolCallEvent"]
8282
ToolMessage["MessageAddedEvent"]
83-
BeforeToolInvocationEvent --> AfterToolInvocationEvent
84-
AfterToolInvocationEvent --> ToolMessage
83+
BeforeToolCallEvent --> AfterToolCallEvent
84+
AfterToolCallEvent --> ToolMessage
8585
end
8686
subgraph End["Request End Events"]
8787
direction TB
@@ -103,25 +103,16 @@ The hooks system provides events for different stages of agent execution:
103103
| `BeforeInvocationEvent` | Triggered at the beginning of a new agent request (`__call__`, `stream_async`, or `structured_output`) |
104104
| `AfterInvocationEvent` | Triggered at the end of an agent request, regardless of success or failure. Uses reverse callback ordering |
105105
| `MessageAddedEvent` | Triggered when a message is added to the agent's conversation history |
106-
107-
Additional *experimental events* are also available:
108-
109-
!!! note "Experimental events are subject to change"
110-
111-
These events are exposed experimentally in order to gather feedback and refine the public contract. Because they are experimental, they are subject to change between releases.
112-
113-
| Experimental Event | Description |
114-
|------------------------------|-------------|
115-
| `BeforeModelInvocationEvent` | Triggered before the model is invoked for inference |
116-
| `AfterModelInvocationEvent` | Triggered after model invocation completes. Uses reverse callback ordering |
117-
| `BeforeToolInvocationEvent` | Triggered before a tool is invoked. |
118-
| `AfterToolInvocationEvent` | Triggered after tool invocation completes. Uses reverse callback ordering |
106+
| `BeforeModelCallEvent` | Triggered before the model is invoked for inference |
107+
| `AfterModelCallEvent` | Triggered after model invocation completes. Uses reverse callback ordering |
108+
| `BeforeToolCallEvent` | Triggered before a tool is invoked. |
109+
| `AfterToolCallEvent` | Triggered after tool invocation completes. Uses reverse callback ordering |
119110

120111
## Hook Behaviors
121112

122113
### Event Properties
123114

124-
Most event properties are read-only to prevent unintended modifications. However, certain properties can be modified to influence agent behavior. For example, `BeforeToolInvocationEvent.selected_tool` allows you to change which tool gets executed, while `AfterToolInvocationEvent.result` enables modification of tool results.
115+
Most event properties are read-only to prevent unintended modifications. However, certain properties can be modified to influence agent behavior. For example, `BeforeToolCallEvent.selected_tool` allows you to change which tool gets executed, while `AfterToolCallEvent.result` enables modification of tool results.
125116

126117
### Callback Ordering
127118

@@ -136,8 +127,7 @@ Enforce specific arguments for tools, ensuring they always use particular values
136127

137128
```python
138129
from typing import Any
139-
from strands.hooks import HookProvider, HookRegistry
140-
from strands.experimental.hooks import BeforeToolInvocationEvent
130+
from strands.hooks import HookProvider, HookRegistry, BeforeToolCallEvent
141131

142132
class ConstantToolArguments(HookProvider):
143133
"""Use constant argument values for specific parameters of a tool."""
@@ -154,9 +144,9 @@ class ConstantToolArguments(HookProvider):
154144
self._tools_to_fix = fixed_tool_arguments
155145

156146
def register_hooks(self, registry: HookRegistry, **kwargs: Any) -> None:
157-
registry.add_callback(BeforeToolInvocationEvent, self._fix_tool_arguments)
147+
registry.add_callback(BeforeToolCallEvent, self._fix_tool_arguments)
158148

159-
def _fix_tool_arguments(self, event: BeforeToolInvocationEvent):
149+
def _fix_tool_arguments(self, event: BeforeToolCallEvent):
160150
# If the tool is in our list of parameters, then use those parameters
161151
if parameters_to_fix := self._tools_to_fix.get(event.tool_use["name"]):
162152
tool_input: dict[str, Any] = event.tool_use["input"]
@@ -183,9 +173,9 @@ Modify or replace tools before execution:
183173
```python
184174
class ToolInterceptor(HookProvider):
185175
def register_hooks(self, registry: HookRegistry) -> None:
186-
registry.add_callback(BeforeToolInvocationEvent, self.intercept_tool)
176+
registry.add_callback(BeforeToolCallEvent, self.intercept_tool)
187177

188-
def intercept_tool(self, event: BeforeToolInvocationEvent) -> None:
178+
def intercept_tool(self, event: BeforeToolCallEvent) -> None:
189179
if event.tool_use.name == "sensitive_tool":
190180
# Replace with a safer alternative
191181
event.selected_tool = self.safe_alternative_tool
@@ -199,9 +189,9 @@ Modify tool results after execution:
199189
```python
200190
class ResultProcessor(HookProvider):
201191
def register_hooks(self, registry: HookRegistry) -> None:
202-
registry.add_callback(AfterToolInvocationEvent, self.process_result)
192+
registry.add_callback(AfterToolCallEvent, self.process_result)
203193

204-
def process_result(self, event: AfterToolInvocationEvent) -> None:
194+
def process_result(self, event: AfterToolCallEvent) -> None:
205195
if event.tool_use.name == "calculator":
206196
# Add formatting to calculator results
207197
original_content = event.result["content"][0]["text"]
@@ -233,7 +223,7 @@ class RequestLoggingHook(HookProvider):
233223
def register_hooks(self, registry: HookRegistry) -> None:
234224
registry.add_callback(BeforeInvocationEvent, self.log_request)
235225
registry.add_callback(AfterInvocationEvent, self.log_response)
236-
registry.add_callback(BeforeToolInvocationEvent, self.log_tool_use)
226+
registry.add_callback(BeforeToolCallEvent, self.log_tool_use)
237227

238228
...
239229
```
@@ -245,9 +235,9 @@ When modifying event properties, log the changes for debugging and audit purpose
245235
```python
246236
class ResultProcessor(HookProvider):
247237
def register_hooks(self, registry: HookRegistry) -> None:
248-
registry.add_callback(AfterToolInvocationEvent, self.process_result)
238+
registry.add_callback(AfterToolCallEvent, self.process_result)
249239

250-
def process_result(self, event: AfterToolInvocationEvent) -> None:
240+
def process_result(self, event: AfterToolCallEvent) -> None:
251241
if event.tool_use.name == "calculator":
252242
original_content = event.result["content"][0]["text"]
253243
logger.info(f"Modifying calculator result: {original_content}")

0 commit comments

Comments
 (0)