diff --git a/src/agents/result.py b/src/agents/result.py index 5e27634f7..365d00079 100644 --- a/src/agents/result.py +++ b/src/agents/result.py @@ -8,6 +8,9 @@ from dataclasses import InitVar, dataclass, field from typing import Any, Literal, TypeVar, cast +from pydantic import GetCoreSchemaHandler +from pydantic_core import core_schema + from .agent import Agent from .agent_output import AgentOutputSchemaBase from .exceptions import ( @@ -124,6 +127,16 @@ class RunResultBase(abc.ABC): _trace_state: TraceState | None = field(default=None, init=False, repr=False) """Serialized trace metadata captured during the run.""" + @classmethod + def __get_pydantic_core_schema__( + cls, + _source_type: Any, + _handler: GetCoreSchemaHandler, + ) -> core_schema.CoreSchema: + # RunResult objects are runtime values; schema generation should treat them as instances + # instead of recursively traversing internal dataclass annotations. + return core_schema.is_instance_schema(cls) + @property @abc.abstractmethod def last_agent(self) -> Agent[Any]: diff --git a/tests/test_result_cast.py b/tests/test_result_cast.py index 63e4d2e8f..8cbbe038b 100644 --- a/tests/test_result_cast.py +++ b/tests/test_result_cast.py @@ -7,7 +7,7 @@ import pytest from openai.types.responses import ResponseOutputMessage, ResponseOutputText -from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict from agents import ( Agent, @@ -45,6 +45,16 @@ class Foo(BaseModel): bar: int +def test_run_result_streaming_supports_pydantic_model_rebuild() -> None: + class StreamingRunContainer(BaseModel): + query_id: str + run_stream: RunResultStreaming | None + + model_config = ConfigDict(arbitrary_types_allowed=True) + + StreamingRunContainer.model_rebuild() + + def _create_message(text: str) -> ResponseOutputMessage: return ResponseOutputMessage( id="msg",