Skip to content

docs: split hooks page into focused explanation, usage, and cookbook #717

Draft
ryanycoleman wants to merge 2 commits intostrands-agents:mainfrom
ryanycoleman:docs/hooks-rewrite
Draft

docs: split hooks page into focused explanation, usage, and cookbook #717
ryanycoleman wants to merge 2 commits intostrands-agents:mainfrom
ryanycoleman:docs/hooks-rewrite

Conversation

@ryanycoleman
Copy link
Copy Markdown
Member

@ryanycoleman ryanycoleman commented Mar 30, 2026

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:

  • 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 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.

  • Content update/revision

Checklist

  • [ X] I have read the CONTRIBUTING document
  • [ X] My changes follow the project's documentation style
  • [ X] I have tested the documentation locally using npm run dev
  • [ X] Links in the documentation are valid and working

Preview


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 30, 2026

Documentation Preview Ready

Your 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.
|---|---|---|---|
| `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) |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Missing cookbook section - #result-modification anchor doesn't exist

Suggestion: Either:

  1. Add a "## Result modification" section to cookbook.mdx demonstrating AfterToolCallEvent.result usage, or
  2. 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) |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Missing cookbook section - #tool-interception anchor doesn't exist

Suggestion: Either:

  1. Add a "## Tool interception" section to cookbook.mdx demonstrating selected_tool replacement, or
  2. Remove this row since the cookbook doesn't cover this pattern yet

@github-actions
Copy link
Copy Markdown
Contributor

Assessment: ⚠️ Request Changes

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 Summary

Critical Issues (5 broken links in index.mdx lines 303-307):

  • #limit-tool-counts → should be #limit-tool-call-counts
  • #tool-interception → missing cookbook section
  • #fixed-tool-arguments → should be #fix-tool-arguments
  • #model-call-retry → should be #retry-model-calls
  • #result-modification → missing cookbook section

What's working well:

  • Clean separation: explanation (index.mdx), how-to (usage.mdx), cookbook (cookbook.mdx)
  • Good dual-SDK support with appropriate TypeScript availability notes
  • Navigation structure properly updated
  • Cross-linking between pages follows patterns
  • Terminology consolidation addressed

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).
@github-actions
Copy link
Copy Markdown
Contributor

Assessment: ✅ Approve

All previously identified issues have been addressed:

  • ✅ Fixed 3 incorrect anchor links (#limit-tool-call-counts, #fix-tool-arguments, #retry-model-calls)
  • ✅ Removed cookbook links for features without recipes (selected_tool, result)
Review Summary

Structure: Excellent Diataxis-compliant split

  • index.mdx: Explanation (mental model, lifecycle, events)
  • usage.mdx: How-to (registration, plugins, multi-agent)
  • cookbook.mdx: Recipes (copy-paste patterns)

Quality:

  • Good dual-SDK support with Python/TypeScript tabs
  • TypeScript availability notes consolidated appropriately
  • Clear cross-linking between pages
  • Navigation properly updated

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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

side bar title: "Cookbook"

title: Using hooks
description: "Register hook callbacks on agents and orchestrators to observe and modify behavior during the agent loop."
sidebar:
order: 1
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sidebar title: "Usage"

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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment on lines +334 to +338
**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)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
**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 |
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants