1111from ._run_impl import QueueCompleteSentinel
1212from .agent import Agent
1313from .agent_output import AgentOutputSchemaBase
14- from .exceptions import InputGuardrailTripwireTriggered , MaxTurnsExceeded
14+ from .exceptions import (
15+ AgentsException ,
16+ InputGuardrailTripwireTriggered ,
17+ MaxTurnsExceeded ,
18+ RunErrorDetails ,
19+ )
1520from .guardrail import InputGuardrailResult , OutputGuardrailResult
1621from .items import ItemHelpers , ModelResponse , RunItem , TResponseInputItem
1722from .logger import logger
2025from .tracing import Trace
2126from .util ._pretty_print import (
2227 pretty_print_result ,
23- pretty_print_run_error_details ,
2428 pretty_print_run_result_streaming ,
2529)
2630
@@ -212,29 +216,79 @@ async def stream_events(self) -> AsyncIterator[StreamEvent]:
212216
213217 def _check_errors (self ):
214218 if self .current_turn > self .max_turns :
215- self ._stored_exception = MaxTurnsExceeded (f"Max turns ({ self .max_turns } ) exceeded" )
219+ max_turns_exc = MaxTurnsExceeded (f"Max turns ({ self .max_turns } ) exceeded" )
220+ max_turns_exc .run_data = RunErrorDetails (
221+ input = self .input ,
222+ new_items = self .new_items ,
223+ raw_responses = self .raw_responses ,
224+ last_agent = self .current_agent ,
225+ context_wrapper = self .context_wrapper ,
226+ input_guardrail_results = self .input_guardrail_results ,
227+ output_guardrail_results = self .output_guardrail_results ,
228+ )
229+ self ._stored_exception = max_turns_exc
216230
217231 # Fetch all the completed guardrail results from the queue and raise if needed
218232 while not self ._input_guardrail_queue .empty ():
219233 guardrail_result = self ._input_guardrail_queue .get_nowait ()
220234 if guardrail_result .output .tripwire_triggered :
221- self ._stored_exception = InputGuardrailTripwireTriggered (guardrail_result )
235+ tripwire_exc = InputGuardrailTripwireTriggered (guardrail_result )
236+ tripwire_exc .run_data = RunErrorDetails (
237+ input = self .input ,
238+ new_items = self .new_items ,
239+ raw_responses = self .raw_responses ,
240+ last_agent = self .current_agent ,
241+ context_wrapper = self .context_wrapper ,
242+ input_guardrail_results = self .input_guardrail_results ,
243+ output_guardrail_results = self .output_guardrail_results ,
244+ )
245+ self ._stored_exception = tripwire_exc
222246
223247 # Check the tasks for any exceptions
224248 if self ._run_impl_task and self ._run_impl_task .done ():
225- exc = self ._run_impl_task .exception ()
226- if exc and isinstance (exc , Exception ):
227- self ._stored_exception = exc
249+ run_impl_exc = self ._run_impl_task .exception ()
250+ if run_impl_exc and isinstance (run_impl_exc , Exception ):
251+ if isinstance (run_impl_exc , AgentsException ) and run_impl_exc .run_data is None :
252+ run_impl_exc .run_data = RunErrorDetails (
253+ input = self .input ,
254+ new_items = self .new_items ,
255+ raw_responses = self .raw_responses ,
256+ last_agent = self .current_agent ,
257+ context_wrapper = self .context_wrapper ,
258+ input_guardrail_results = self .input_guardrail_results ,
259+ output_guardrail_results = self .output_guardrail_results ,
260+ )
261+ self ._stored_exception = run_impl_exc
228262
229263 if self ._input_guardrails_task and self ._input_guardrails_task .done ():
230- exc = self ._input_guardrails_task .exception ()
231- if exc and isinstance (exc , Exception ):
232- self ._stored_exception = exc
264+ in_guard_exc = self ._input_guardrails_task .exception ()
265+ if in_guard_exc and isinstance (in_guard_exc , Exception ):
266+ if isinstance (in_guard_exc , AgentsException ) and in_guard_exc .run_data is None :
267+ in_guard_exc .run_data = RunErrorDetails (
268+ input = self .input ,
269+ new_items = self .new_items ,
270+ raw_responses = self .raw_responses ,
271+ last_agent = self .current_agent ,
272+ context_wrapper = self .context_wrapper ,
273+ input_guardrail_results = self .input_guardrail_results ,
274+ output_guardrail_results = self .output_guardrail_results ,
275+ )
276+ self ._stored_exception = in_guard_exc
233277
234278 if self ._output_guardrails_task and self ._output_guardrails_task .done ():
235- exc = self ._output_guardrails_task .exception ()
236- if exc and isinstance (exc , Exception ):
237- self ._stored_exception = exc
279+ out_guard_exc = self ._output_guardrails_task .exception ()
280+ if out_guard_exc and isinstance (out_guard_exc , Exception ):
281+ if isinstance (out_guard_exc , AgentsException ) and out_guard_exc .run_data is None :
282+ out_guard_exc .run_data = RunErrorDetails (
283+ input = self .input ,
284+ new_items = self .new_items ,
285+ raw_responses = self .raw_responses ,
286+ last_agent = self .current_agent ,
287+ context_wrapper = self .context_wrapper ,
288+ input_guardrail_results = self .input_guardrail_results ,
289+ output_guardrail_results = self .output_guardrail_results ,
290+ )
291+ self ._stored_exception = out_guard_exc
238292
239293 def _cleanup_tasks (self ):
240294 if self ._run_impl_task and not self ._run_impl_task .done ():
@@ -249,34 +303,3 @@ def _cleanup_tasks(self):
249303 def __str__ (self ) -> str :
250304 return pretty_print_run_result_streaming (self )
251305
252-
253- @dataclass
254- class RunErrorDetails :
255- input : str | list [TResponseInputItem ]
256- """The original input items i.e. the items before run() was called. This may be a mutated
257- version of the input, if there are handoff input filters that mutate the input.
258- """
259-
260- new_items : list [RunItem ]
261- """The new items generated during the agent run. These include things like new messages, tool
262- calls and their outputs, etc.
263- """
264-
265- raw_responses : list [ModelResponse ]
266- """The raw LLM responses generated by the model during the agent run."""
267-
268- input_guardrail_results : list [InputGuardrailResult ]
269- """Guardrail results for the input messages."""
270-
271- context_wrapper : RunContextWrapper [Any ]
272- """The context wrapper for the agent run."""
273-
274- _last_agent : Agent [Any ]
275-
276- @property
277- def last_agent (self ) -> Agent [Any ]:
278- """The last agent that was run."""
279- return self ._last_agent
280-
281- def __str__ (self ) -> str :
282- return pretty_print_run_error_details (self )
0 commit comments