Skip to content

RunResultStreaming type not compatible with Pydantic model_rebuild() #2127

@rsg73626

Description

@rsg73626

Please read this first

  • Have you read the docs? Yes - Agents SDK docs
  • Have you searched for related issues? Yes - No existing issues found for this specific forward reference problem with RunResultStreaming and Agent types.

Describe the bug

When attempting to use RunResultStreaming as a type annotation in a Pydantic model and calling model_rebuild(), Pydantic fails with a NameError: name 'Agent' is not defined error. This occurs because RunResultStreaming contains a field current_agent: Agent[Any], and Pydantic tries to resolve this forward reference during schema generation, but encounters a circular dependency issue.

The root cause is:

  1. result.py imports Agent directly: from .agent import Agent (line 12)
  2. agent.py imports RunResult conditionally: from .result import RunResult (under TYPE_CHECKING, line 36)
  3. This creates a circular dependency that Pydantic cannot resolve when introspecting RunResultStreaming during model_rebuild()

Users are forced to use Any or object type annotations instead of the proper RunResultStreaming type, losing type safety and IDE support.

Debug information

  • Agents SDK version: v0.5.1
  • Python version: Python 3.12
  • Pydantic version: >=2.12.3, <3 (as per SDK dependencies)

Repro steps

Here's a minimal reproduction script:

from __future__ import annotations

import pydantic
from agents import Agent, Runner
from agents.result import RunResultStreaming


class MyModel(pydantic.BaseModel):
    """A Pydantic model that stores RunResultStreaming."""
    
    query_id: str
    run_stream: RunResultStreaming | None
    
    model_config = pydantic.ConfigDict(arbitrary_types_allowed=True)


# This will fail with NameError: name 'Agent' is not defined
MyModel.model_rebuild()

Error output:

Traceback (most recent call last):
  File "/path/to/test.py", line 15, in <module>
    MyModel.model_rebuild()
  File ".../pydantic/main.py", line 660, in model_rebuild
    return _model_construction.complete_model_class(...)
  ...
  File ".../pydantic/_internal/_typing_extra.py", line 500, in _eval_type
    return typing._eval_type(...)
  File ".../typing.py", line 415, in _eval_type
    return t._evaluate(globalns, localns, type_params, recursive_guard=recursive_guard)
  File ".../typing.py", line 947, in _evaluate
    eval(self.__forward_code__, globalns, localns),
  File "<string>", line 1, in <module>
NameError: name 'Agent' is not defined

Workaround (current):

class MyModel(pydantic.BaseModel):
    query_id: str
    run_stream: object | None  # Type: RunResultStreaming | None
    
    model_config = pydantic.ConfigDict(arbitrary_types_allowed=True)

Expected behavior

Users should be able to use RunResultStreaming directly as a type annotation in Pydantic models without encountering forward reference errors. The type should be properly resolvable during model_rebuild().

Suggested fix:

Move the Agent import in result.py to TYPE_CHECKING and use string annotations:

# In src/agents/result.py

if TYPE_CHECKING:
    from .agent import Agent

# ... later in the file ...

@dataclass
class RunResultStreaming(RunResultBase):
    current_agent: "Agent[Any]"  # Use string annotation
    # ... rest of fields

This would:

  1. Break the circular dependency at runtime
  2. Still provide proper type hints for type checkers
  3. Allow Pydantic to properly handle the forward reference
  4. Maintain backward compatibility

Additional context

  • The issue occurs specifically when Pydantic tries to generate a schema for models containing RunResultStreaming
  • SkipValidation wrapper doesn't help because Pydantic still needs to resolve the type during schema generation (not just runtime validation)
  • The workaround of using object | None with arbitrary_types_allowed=True works but loses type safety
  • This affects any user trying to store RunResultStreaming instances in Pydantic models, which is a common pattern for managing agent run state

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions