feat: set tools in State so its available to before_run hooks (#12376)

Co-authored-by: Stefano Fiorucci <[email protected]>
This commit is contained in:
Sebastian Husch Lee
2026-08-17 12:53:22 +02:00
committed by GitHub
co-authored by Stefano Fiorucci
parent d9d70c04cb
commit 66c3fd870c
3 changed files with 18 additions and 0 deletions
+1
View File
@@ -743,6 +743,7 @@ class Agent:
state.set("tool_call_counts", {tool.name: 0 for tool in flat_tools})
state.set("exit_reason", None)
state.set("continue_run", False)
state.set("tools", flat_tools)
state.set("hook_context", hook_context or {})
streaming_callback = select_streaming_callback( # type: ignore[call-overload]
@@ -0,0 +1,7 @@
---
enhancements:
- |
``before_run`` hooks can now read ``state.data["tools"]``. The key was previously written only once the first step
had started, so a ``before_run`` hook hit a ``KeyError``. It holds a snapshot of the tools available at that point,
refreshed before every LLM call, so with a dynamic toolset such as ``SearchableToolset`` a ``before_run`` hook sees
only the tools discovered so far.
@@ -196,6 +196,16 @@ class TestAgentHooksValidation:
class TestBeforeRunHook:
def test_tools_are_available_before_the_first_step(self):
available_tool_names: list[str] = []
def record_tools(state: State) -> None:
available_tool_names.extend(tool.name for tool in state.data["tools"])
agent = _agent(MockChatGenerator(), tools=[save], hooks={"before_run": [hook(record_tools)]})
agent.run(messages=[ChatMessage.from_user("hi")])
assert available_tool_names == ["save"]
def test_runs_once_across_multi_step_run(self):
agent = _agent(
MockChatGenerator(),