Skip to content

feat(strands-py): add optional hook order#2559

Merged
lizradway merged 6 commits into
strands-agents:mainfrom
lizradway:py-hookorder
Jun 2, 2026
Merged

feat(strands-py): add optional hook order#2559
lizradway merged 6 commits into
strands-agents:mainfrom
lizradway:py-hookorder

Conversation

@lizradway
Copy link
Copy Markdown
Member

@lizradway lizradway commented Jun 2, 2026

Description

Adds an optional order parameter to add_callback and add_hook methods that controls hook execution priority. Lower values execute first, with named constants: HookOrder.SDK_FIRST (-100), HookOrder.DEFAULT (0), HookOrder.SDK_LAST (100).

Hooks with the same order preserve registration order. For After* events (reversed), lower order still runs first across groups, with registration order reversed within same group.

Port of strands-agents/sdk-typescript#1005.

Usage

from strands import Agent
from strands.hooks import BeforeModelCallEvent, HookOrder

agent = Agent()

def early_hook(event: BeforeModelCallEvent) -> None:
    print("I run first")

def late_hook(event: BeforeModelCallEvent) -> None:
    print("I run last")

agent.add_hook(early_hook, order=HookOrder.SDK_FIRST)
agent.add_hook(late_hook, order=HookOrder.SDK_LAST)

# Arbitrary numeric values work too
agent.add_hook(my_hook, order=-50)

# float('-inf') / float('inf') for guaranteed absolute ordering
agent.add_hook(always_first, order=float('-inf'))

Related Issues

strands-agents/sdk-typescript#1005

Documentation PR

Documentation included in this PR — updated the Python tab under "Callback Ordering" in site/src/content/docs/user-guide/concepts/agents/hooks.mdx.

Type of Change

New feature

Testing

  • New unit tests for ordering behavior (lower order first, same order FIFO, negative order, After event semantics)
  • All existing hook registry tests pass
  • Plugin and steering tests updated for internal storage change
  • I ran hatch run prepare

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

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

Add an optional `order` parameter to `add_callback` and `add_hook` methods
that controls hook execution priority. Lower values execute first, with
named constants: HookOrder.FIRST (-100), HookOrder.DEFAULT (0),
HookOrder.LAST (100).

Port of strands-agents/sdk-typescript#1005.
Comment thread site/src/content/docs/user-guide/concepts/agents/hooks.mdx
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

Documentation Preview Ready

Your documentation preview has been successfully deployed!

Preview URL: https://d3ehv1nix5p99z.cloudfront.net/pr-cms-2559/docs/user-guide/quickstart/overview/

Updated at: 2026-06-02T16:15:29.260Z

Comment thread strands-py/src/strands/hooks/registry.py
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

Issue: The PR description says "named constants: HookOrder.FIRST (-100), HookOrder.DEFAULT (0), HookOrder.LAST (100)" but the actual constants are HookOrder.SDK_FIRST, HookOrder.DEFAULT, HookOrder.SDK_LAST. This may confuse reviewers and those reading PR history later.

Suggestion: Update the PR description to match the actual constant names.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

Issue: This PR modifies a public API (add_hook) and introduces a new public symbol (HookOrder). Per the API Bar Raising guidelines, PRs that add new public classes or primitives should have the needs-api-review label.

Suggestion: Consider adding needs-api-review label. This is a "moderate change" (new class that customers use), so an informal discussion with an API reviewer followed by standard PR review should suffice. The API design itself looks solid — keyword-only order param, backward-compatible default, matches TS SDK.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

Assessment: Comment

Clean, well-structured feature port that aligns with the TS SDK and maintains backward compatibility. The implementation is correct and the API design follows the project's tenets (extensible by design, pay-for-play). A few items to address around documentation accuracy and API review process.

Review Categories
  • Documentation: The docs suggest float('-inf')/float('inf') but the type annotation is int — this will cause mypy errors for users. PR description also has stale constant names.
  • API Review: Introduces a new public symbol (HookOrder) — should go through the needs-api-review label process per API Bar Raising guidelines.
  • Testing: Missing async path coverage for the new ordering behavior.
  • Naming: SDK_FIRST/SDK_LAST naming implies SDK hooks use these positions, but currently none do — worth clarifying in docs or a follow-up.

The implementation itself (bisect.insort, groupby for reversed events, keyword-only param) is well done.

Comment thread strands-py/src/strands/agent/agent.py
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@lizradway lizradway marked this pull request as ready for review June 2, 2026 16:10
Comment thread site/src/content/docs/user-guide/concepts/agents/hooks.mdx
Comment thread strands-py/src/strands/hooks/registry.py
@lizradway lizradway enabled auto-merge (squash) June 2, 2026 20:32
@lizradway lizradway merged commit 6dd249d into strands-agents:main Jun 2, 2026
104 of 126 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants