8000 Apparent race condition on Agent Hooks · Issue #877 · openai/openai-agents-python · GitHub
[go: up one dir, main page]

Skip to content
Apparent race condition on Agent Hooks #877
Closed
@maininformer

Description

@maininformer

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.

Image

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0