docs: split hooks page into focused explanation, usage, and cookbook #717
docs: split hooks page into focused explanation, usage, and cookbook #717ryanycoleman wants to merge 2 commits intostrands-agents:mainfrom
Conversation
Documentation Preview ReadyYour documentation preview has been successfully deployed! Preview URL: https://d3ehv1nix5p99z.cloudfront.net/pr-cms-717/docs/user-guide/quickstart/overview/ Updated at: 2026-03-30T20:12:11.367Z |
…pages The single hooks page mixed four content types (reference, how-to, explanation, cookbook) making it hard to find answers. Split into three pages following Diataxis content typing: - index.mdx: explanation (what hooks are, lifecycle, events, when NOT to use them) - usage.mdx: how-to (register callbacks, plugins, invocation state, multi-agent) - cookbook.mdx: recipes (fixed args, rate limiting, retry, resume, interrupts) Also fixes 20 terminology violations, adds correct TS event names for 1.0-rc, and consolidates TypeScript availability notes at section level instead of 9 inline stubs.
68d0c89 to
43653e9
Compare
| |---|---|---|---| | ||
| | `BeforeToolCallEvent` | `cancel_tool` | Cancels tool calling with a message returned to the model | [Limit tool counts](./cookbook#limit-tool-counts) | | ||
| | `BeforeToolCallEvent` | `selected_tool` | Replaces the tool to be called | [Tool interception](./cookbook#tool-interception) | | ||
| | `BeforeToolCallEvent` | `tool_use` | Modifies tool parameters before calling | [Fixed tool arguments](./cookbook#fixed-tool-arguments) | |
There was a problem hiding this comment.
Issue: Broken anchor link - #fixed-tool-arguments doesn't match cookbook section
Suggestion: The cookbook section is "## Fix tool arguments" which generates anchor #fix-tool-arguments. Update to:
[Fixed tool arguments](./cookbook#fix-tool-arguments)|
|
||
| | Event | Writable property | Effect | Cookbook recipe | | ||
| |---|---|---|---| | ||
| | `BeforeToolCallEvent` | `cancel_tool` | Cancels tool calling with a message returned to the model | [Limit tool counts](./cookbook#limit-tool-counts) | |
There was a problem hiding this comment.
Issue: Broken anchor link - #limit-tool-counts doesn't exist in cookbook.mdx
Suggestion: The cookbook section is "## Limit tool call counts" which generates anchor #limit-tool-call-counts. Update to:
[Limit tool counts](./cookbook#limit-tool-call-counts)| | `BeforeToolCallEvent` | `cancel_tool` | Cancels tool calling with a message returned to the model | [Limit tool counts](./cookbook#limit-tool-counts) | | ||
| | `BeforeToolCallEvent` | `selected_tool` | Replaces the tool to be called | [Tool interception](./cookbook#tool-interception) | | ||
| | `BeforeToolCallEvent` | `tool_use` | Modifies tool parameters before calling | [Fixed tool arguments](./cookbook#fixed-tool-arguments) | | ||
| | `AfterModelCallEvent` | `retry` | Retries the model call | [Model call retry](./cookbook#model-call-retry) | |
There was a problem hiding this comment.
Issue: Broken anchor link - #model-call-retry doesn't match cookbook section
Suggestion: The cookbook section is "## Retry model calls" which generates anchor #retry-model-calls. Update to:
[Model call retry](./cookbook#retry-model-calls)| | `BeforeToolCallEvent` | `selected_tool` | Replaces the tool to be called | [Tool interception](./cookbook#tool-interception) | | ||
| | `BeforeToolCallEvent` | `tool_use` | Modifies tool parameters before calling | [Fixed tool arguments](./cookbook#fixed-tool-arguments) | | ||
| | `AfterModelCallEvent` | `retry` | Retries the model call | [Model call retry](./cookbook#model-call-retry) | | ||
| | `AfterToolCallEvent` | `result` | Rewrites the tool result | [Result modification](./cookbook#result-modification) | |
There was a problem hiding this comment.
Issue: Missing cookbook section - #result-modification anchor doesn't exist
Suggestion: Either:
- Add a "## Result modification" section to cookbook.mdx demonstrating
AfterToolCallEvent.resultusage, or - Remove this row since the cookbook doesn't cover this pattern yet
| | Event | Writable property | Effect | Cookbook recipe | | ||
| |---|---|---|---| | ||
| | `BeforeToolCallEvent` | `cancel_tool` | Cancels tool calling with a message returned to the model | [Limit tool counts](./cookbook#limit-tool-counts) | | ||
| | `BeforeToolCallEvent` | `selected_tool` | Replaces the tool to be called | [Tool interception](./cookbook#tool-interception) | |
There was a problem hiding this comment.
Issue: Missing cookbook section - #tool-interception anchor doesn't exist
Suggestion: Either:
- Add a "## Tool interception" section to cookbook.mdx demonstrating
selected_toolreplacement, or - Remove this row since the cookbook doesn't cover this pattern yet
|
Assessment: This is a well-structured documentation refactor that properly splits the hooks documentation following the Diataxis framework. However, there are several broken anchor links in the modifiable event properties table that need to be fixed before merging. Review SummaryCritical Issues (5 broken links in index.mdx lines 303-307):
What's working well:
The anchor fixes are straightforward - 3 need correction to match existing headings, and 2 either need new cookbook sections or the rows should be removed from the table. Great work on the refactoring structure! 🎉 |
Fix 5 anchor links in the modifiable properties table to match actual cookbook heading slugs. Remove links for tool interception and result modification (no cookbook sections for those yet).
|
Assessment: ✅ Approve All previously identified issues have been addressed:
Review SummaryStructure: Excellent Diataxis-compliant split
Quality:
Great documentation refactoring work! 🎉 |
| title: Hooks cookbook | ||
| description: "Copy-paste hook patterns for common agent behaviors: fixed arguments, rate limiting, retries, and autonomous looping." | ||
| sidebar: | ||
| order: 2 |
| title: Using hooks | ||
| description: "Register hook callbacks on agents and orchestrators to observe and modify behavior during the agent loop." | ||
| sidebar: | ||
| order: 1 |
| title: Hooks | ||
| description: "Observe and modify agent behavior at runtime with lifecycle hooks that fire before and after key events in the agent loop." | ||
| sidebar: | ||
| order: 0 |
There was a problem hiding this comment.
Sidebar title "Overview" (to match our other similar pages0
| order: 0 | ||
| --- | ||
|
|
||
| You use hooks to observe and modify agent behavior at runtime. Hooks fire at defined points in the agent loop: before and after model calls, tool calls, and full agent invocations. They are code, not prompt instructions, so they enforce behavior reliably. |
There was a problem hiding this comment.
Given that this is the entrypoint, I'd start out explaining hooks rather than starting with "You"
"Hooks are a way to observe and modify agent behavior at runtime; you add callbacks that are invoked at specific points in the agent loop: before and after model calls, tool calls, and full agent invocations. They are code, not prompt instructions, so they enforce behavior reliably."
|
|
||
| ## How hooks work | ||
|
|
||
| Hooks subscribe to lifecycle events. Each event type has a before/after pair (for example, `BeforeToolCallEvent` and `AfterToolCallEvent`). When the agent reaches that point in the loop, it fires the event and passes an event object to every registered callback. |
There was a problem hiding this comment.
Not true for some hooks; MessageAdded for instance is not a lifecycle nor has a pair
|
|
||
| ## When hooks are the wrong choice | ||
|
|
||
| Hooks run synchronously in the agent loop. Every millisecond a hook spends is a millisecond added to the agent's response time. Keep this in mind when deciding where to put logic. |
There was a problem hiding this comment.
I'm not sure there's really a wrong choice. Hooks are the extensibility mechanism and there's not really the wrong choice; even guardrails can be implemented (and should be) done via hooks.
I think it'd be better to pitch as "Hook Anti-Patterns" where you're trying to build state-machines. We still want to rely on the model for driving the overall behavior, but sprinkle on hooks to add more determinism where you need it
| **Long-running checks add latency.** If your hook makes a database lookup or API call, that latency applies to every model call or tool call (depending on the event). For expensive validation, consider these alternatives: | ||
|
|
||
| - Cache results in the hook's instance state and refresh periodically | ||
| - Move the check into the tool itself, where it runs only when that tool is called | ||
| - Use async patterns (Python hooks support `async def` callbacks) |
There was a problem hiding this comment.
| **Long-running checks add latency.** If your hook makes a database lookup or API call, that latency applies to every model call or tool call (depending on the event). For expensive validation, consider these alternatives: | |
| - Cache results in the hook's instance state and refresh periodically | |
| - Move the check into the tool itself, where it runs only when that tool is called | |
| - Use async patterns (Python hooks support `async def` callbacks) |
This specifically I think we should remove; we can add a callout about it, but latency isn't a big concern overall IMHO
|
|
||
| | Event | Description | | ||
| |---|---| | ||
| | `AgentInitializedEvent` | Fired when the agent finishes construction at the end of its constructor | |
There was a problem hiding this comment.
I can tell if this belongs on Usage or Overview; I'm leaning towards Usage because it seems weird that this overview page lists every event and the various properties included (below) when that's really more important once you one to start operating on them?
The distinction between the two is a little unclear to me
Description
The single hooks page mixed four content types (reference, how-to, explanation, cookbook) making it hard to find answers. Split into three pages following Diataxis content typing:
Also addresses terminology inconsistencies, adds correct TS event names for 1.0-rc, and consolidates TypeScript availability notes at section level instead of 9 inline stubs.
Checklist
npm run devPreview
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.