diff --git a/src/agents/run.py b/src/agents/run.py index 85607e7dd..bf433bb35 100644 --- a/src/agents/run.py +++ b/src/agents/run.py @@ -599,26 +599,28 @@ async def run( ) if current_turn == 1: - input_guardrail_results, turn_result = await asyncio.gather( - self._run_input_guardrails( - starting_agent, - starting_agent.input_guardrails - + (run_config.input_guardrails or []), - _copy_str_or_list(prepared_input), - context_wrapper, - ), - self._run_single_turn( - agent=current_agent, - all_tools=all_tools, - original_input=original_input, - generated_items=generated_items, - hooks=hooks, - context_wrapper=context_wrapper, - run_config=run_config, - should_run_agent_start_hooks=should_run_agent_start_hooks, - tool_use_tracker=tool_use_tracker, - server_conversation_tracker=server_conversation_tracker, - ), + # Run input guardrails first, before sending any model requests. + # This ensures that if a guardrail triggers a tripwire, no tools + # (especially hosted tools like FileSearchTool) execute. + # See Issue #889: https://github.com/openai/openai-agents-python/issues/889 + input_guardrail_results = await self._run_input_guardrails( + starting_agent, + starting_agent.input_guardrails + (run_config.input_guardrails or []), + _copy_str_or_list(prepared_input), + context_wrapper, + ) + # Only proceed with agent execution if guardrails passed + turn_result = await self._run_single_turn( + agent=current_agent, + all_tools=all_tools, + original_input=original_input, + generated_items=generated_items, + hooks=hooks, + context_wrapper=context_wrapper, + run_config=run_config, + should_run_agent_start_hooks=should_run_agent_start_hooks, + tool_use_tracker=tool_use_tracker, + server_conversation_tracker=server_conversation_tracker, ) else: turn_result = await self._run_single_turn(