Closed
Description
Describe the bug
Agent hooks do not seem to run consistently. If you run the code below, you will sometimes receive the print statements and sometimes not; note the tools: ['make_haiku_about_haikus', 'get_instructions']
lines below. I have had variations of printing it once, twice and none at all.
Debug information
- Agents SDK version: (e.g.
v0.0.15
) - Python version (e.g. Python 3.12.4)
Repro steps
import asyncio, random
from agents import Agent, Runner, function_tool, handoff, ModelSettings, AgentHooks, RunContextWrapper, Handoff
from typing import List
class IntroHaikuistHooks(AgentHooks):
def __init__(self):
self._saved_handoffs: List[Handoff] | None = None
async def on_start(self, ctx, agent):
if self._saved_handoffs is None:
self._saved_handoffs = list(agent.handoffs)
agent.tools = [t for t in agent.tools if t.name != "transfer_to_word_picker"]
async def on_tool_end(self, ctx, agent, tool, result):
print(f"tools: {[t.name for t in agent.tools]}")
if tool.name != "make_haiku_about_haikus":
return
agent.handoffs = self._saved_handoffs
agent.model_settings = ModelSettings(tool_choice="transfer_to_word_picker")
agent.reset_tool_choice = False
async def on_handoff(self, context: RunContextWrapper, agent: Agent, source: Agent) -> None:
agent.model_settings = ModelSettings(tool_choice="auto")
agent.reset_tool_choice = False
# ── tools ────────────────────────────────────────────────────────────────────
@function_tool
def make_haiku_about_haikus() -> str:
return "\n".join([
"Seventeen small breaths,",
"A world folded into three,",
"Haiku makes haiku."
])
@function_tool
def choose_random_word(words: list[str]) -> str:
return random.choice(words)
@function_tool
def get_instructions() -> str:
return "transfer to the word picker immediately"
# ── agent 1 ──────────────────────────────────────────────────────────────────
intro_haiku_agent = Agent(
name="Intro‑Haikuist",
model="gpt-4o",
instructions=(""),
tools=[make_haiku_about_haikus, get_instructions],
# filter strips reasoning, fn‑call, result bundle just before the hand‑off
model_settings=ModelSettings(tool_choice="auto", truncation="auto"),
hooks=IntroHaikuistHooks(),
)
# ── agent 2 (general model) ─────────────────────────────────────────────────
word_picker_agent = Agent(
name="Word‑Picker",
model="gpt-4o",
instructions=(""),
tools=[choose_random_word],
model_settings=ModelSettings(tool_choice="auto", truncation="auto"),
)
intro_haiku_agent.handoffs = [handoff(word_picker_agent)]
# ── driver ───────────────────────────────────────────────────────────────────
WORDS = ["moon", "blossom", "mountain", "breeze", "river"]
async def main() -> None:
run = await Runner.run(intro_haiku_agent,
f"The candidate words are: {WORDS}",
max_turns=15)
print(run)
if __name__ == "__main__":
asyncio.run(main())
Expected behavior
For the print statements to happen equal to the number of tool calls, signaling hooks running correctly