Skip to content

Commit c1e43a6

Browse files
Added RunErrorDetails object for MaxTurnsExceeded exception
1 parent 1364f44 commit c1e43a6

File tree

5 files changed

+49
-7
lines changed

5 files changed

+49
-7
lines changed

src/agents/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
from .models.openai_chatcompletions import OpenAIChatCompletionsModel
4545
from .models.openai_provider import OpenAIProvider
4646
from .models.openai_responses import OpenAIResponsesModel
47-
from .result import RunResult, RunResultStreaming
47+
from .result import RunErrorDetails, RunResult, RunResultStreaming
4848
from .run import RunConfig, Runner
4949
from .run_context import RunContextWrapper, TContext
5050
from .stream_events import (
@@ -204,6 +204,7 @@ def enable_verbose_stdout_logging():
204204
"AgentHooks",
205205
"RunContextWrapper",
206206
"TContext",
207+
"RunErrorDetails",
207208
"RunResult",
208209
"RunResultStreaming",
209210
"RunConfig",

src/agents/exceptions.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
from typing import TYPE_CHECKING
1+
from typing import TYPE_CHECKING, Optional
22

33
if TYPE_CHECKING:
44
from .guardrail import InputGuardrailResult, OutputGuardrailResult
5+
from .result import RunErrorDetails
56

67

78
class AgentsException(Exception):
@@ -12,9 +13,11 @@ class MaxTurnsExceeded(AgentsException):
1213
"""Exception raised when the maximum number of turns is exceeded."""
1314

1415
message: str
16+
run_error_details: Optional["RunErrorDetails"]
1517

16-
def __init__(self, message: str):
18+
def __init__(self, message: str, run_error_details: Optional["RunErrorDetails"] = None):
1719
self.message = message
20+
self.run_error_details = run_error_details
1821

1922

2023
class ModelBehaviorError(AgentsException):

src/agents/result.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818
from .run_context import RunContextWrapper
1919
from .stream_events import StreamEvent
2020
from .tracing import Trace
21-
from .util._pretty_print import pretty_print_result, pretty_print_run_result_streaming
21+
from .util._pretty_print import (
22+
pretty_print_result,
23+
pretty_print_run_error_details,
24+
pretty_print_run_result_streaming,
25+
)
2226

2327
if TYPE_CHECKING:
2428
from ._run_impl import QueueCompleteSentinel
@@ -244,3 +248,15 @@ def _cleanup_tasks(self):
244248

245249
def __str__(self) -> str:
246250
return pretty_print_run_result_streaming(self)
251+
252+
@dataclass
253+
class RunErrorDetails(RunResultBase):
254+
_last_agent: Agent[Any]
255+
256+
@property
257+
def last_agent(self) -> Agent[Any]:
258+
"""The last agent that was run."""
259+
return self._last_agent
260+
261+
def __str__(self) -> str:
262+
return pretty_print_run_error_details(self)

src/agents/run.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
from .model_settings import ModelSettings
3636
from .models.interface import Model, ModelProvider
3737
from .models.multi_provider import MultiProvider
38-
from .result import RunResult, RunResultStreaming
38+
from .result import RunErrorDetails, RunResult, RunResultStreaming
3939
from .run_context import RunContextWrapper, TContext
4040
from .stream_events import AgentUpdatedStreamEvent, RawResponsesStreamEvent
4141
from .tool import Tool
@@ -208,7 +208,20 @@ async def run(
208208
data={"max_turns": max_turns},
209209
),
210210
)
211-
raise MaxTurnsExceeded(f"Max turns ({max_turns}) exceeded")
211+
run_error_details = RunErrorDetails(
212+
input=original_input,
213+
new_items=generated_items,
214+
raw_responses=model_responses,
215+
final_output=None,
216+
input_guardrail_results=input_guardrail_results,
217+
output_guardrail_results=[],
218+
context_wrapper=context_wrapper,
219+
_last_agent=current_agent
220+
)
221+
raise MaxTurnsExceeded(
222+
f"Max turns ({max_turns}) exceeded",
223+
run_error_details
224+
)
212225

213226
logger.debug(
214227
f"Running agent {current_agent.name} (turn {current_turn})",

src/agents/util/_pretty_print.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from pydantic import BaseModel
44

55
if TYPE_CHECKING:
6-
from ..result import RunResult, RunResultBase, RunResultStreaming
6+
from ..result import RunErrorDetails, RunResult, RunResultBase, RunResultStreaming
77

88

99
def _indent(text: str, indent_level: int) -> str:
@@ -37,6 +37,15 @@ def pretty_print_result(result: "RunResult") -> str:
3737

3838
return output
3939

40+
def pretty_print_run_error_details(result: "RunErrorDetails") -> str:
41+
output = "RunErrorDetails:"
42+
output += f'\n- Last agent: Agent(name="{result.last_agent.name}", ...)'
43+
output += f"\n- {len(result.new_items)} new item(s)"
44+
output += f"\n- {len(result.raw_responses)} raw response(s)"
45+
output += f"\n- {len(result.input_guardrail_results)} input guardrail result(s)"
46+
output += "\n(See `RunErrorDetails` for more details)"
47+
48+
return output
4049

4150
def pretty_print_run_result_streaming(result: "RunResultStreaming") -> str:
4251
output = "RunResultStreaming:"

0 commit comments

Comments
 (0)