@@ -184,3 +184,43 @@ async def test_openai_agent_graph_runner_run_success():
184184 # Runner accumulates per-node metrics in _node_metrics
185185 assert 'root-agent' in runner ._node_metrics
186186 assert runner ._node_metrics ['root-agent' ].success is True
187+
188+
189+ @pytest .mark .asyncio
190+ async def test_openai_agent_graph_runner_run_resets_node_metrics_between_runs ():
191+ """Successive runs do not leak stale node metrics from a previous run."""
192+ graph = _make_graph ()
193+
194+ mock_result = MagicMock ()
195+ mock_result .final_output = "answer"
196+ mock_result .new_items = []
197+ mock_result .context_wrapper .usage .request_usage_entries = []
198+
199+ mock_agents = MagicMock ()
200+ mock_agents .Runner .run = AsyncMock (
201+ side_effect = [RuntimeError ("boom" ), mock_result ]
202+ )
203+ mock_agents .Agent = MagicMock (return_value = MagicMock ())
204+ mock_agents .Handoff = MagicMock ()
205+ mock_agents .handoff = MagicMock ()
206+
207+ mock_agents_ext = MagicMock ()
208+ mock_agents_ext .RECOMMENDED_PROMPT_PREFIX = '[PREFIX]'
209+
210+ with patch .dict ('sys.modules' , {
211+ 'agents' : mock_agents ,
212+ 'agents.extensions' : MagicMock (),
213+ 'agents.extensions.handoff_prompt' : mock_agents_ext ,
214+ 'agents.tool_context' : MagicMock (),
215+ }):
216+ runner = OpenAIAgentGraphRunner (graph , {})
217+
218+ first = await runner .run ("attempt 1" )
219+ assert first .metrics .success is False
220+ assert first .metrics .node_metrics ['root-agent' ].success is False
221+ failed_metrics = first .metrics .node_metrics ['root-agent' ]
222+
223+ second = await runner .run ("attempt 2" )
224+ assert second .metrics .success is True
225+ assert second .metrics .node_metrics ['root-agent' ].success is True
226+ assert second .metrics .node_metrics ['root-agent' ] is not failed_metrics
0 commit comments