1414
1515from .._resource import AsyncAPIResource , SyncAPIResource
1616from .._types import NOT_GIVEN , NotGiven , Timeout
17- from ..types import (
18- AgentID ,
19- ModelRef ,
20- PromptInputFileAttachment ,
21- SessionID ,
22- SessionInfo ,
23- SessionMessageAssistant ,
24- SessionMessageAssistantText ,
25- SessionMessageIdle ,
26- SessionMessageInfo ,
27- SessionMessageUser ,
28- SessionStructuredError ,
29- TokenUsageInfo ,
30- TokenUsageInfoCache ,
31- )
3217
3318if TYPE_CHECKING :
3419 from collections .abc import Sequence
3520
3621 from ..resources .session import AsyncSessionResource , SessionResource
22+ from ..types import (
23+ AgentID ,
24+ ModelRef ,
25+ PromptInputFileAttachment ,
26+ SessionID ,
27+ SessionInfo ,
28+ SessionMessageAssistant ,
29+ SessionMessageInfo ,
30+ SessionStructuredError ,
31+ TokenUsageInfo ,
32+ )
3733
3834__all__ = ["AsyncSessionHelpers" , "RunResult" , "SessionHelpers" ]
3935
@@ -44,17 +40,21 @@ class RunResult:
4440
4541 session : SessionInfo
4642 """The session as it was after the run. ``session.cost`` and ``session.tokens`` cover the whole session."""
47- messages : list [SessionMessageInfo ] = field (default_factory = list [ SessionMessageInfo ])
43+ messages : list [SessionMessageInfo ] = field (default_factory = list ) # pyright: ignore[reportUnknownVariableType]
4844 """Messages this run added, oldest first, starting with the prompt."""
4945
5046 @property
5147 def assistant_messages (self ) -> list [SessionMessageAssistant ]:
5248 """The assistant messages of this run, oldest first."""
49+ from ..types import SessionMessageAssistant
50+
5351 return [message for message in self .messages if isinstance (message , SessionMessageAssistant )]
5452
5553 @property
5654 def text (self ) -> str :
5755 """Text of the last assistant message, or ``""`` when the agent produced none."""
56+ from ..types import SessionMessageAssistantText
57+
5858 for message in reversed (self .assistant_messages ):
5959 parts = [item .text for item in message .content if isinstance (item , SessionMessageAssistantText )]
6060 if parts :
@@ -64,6 +64,8 @@ def text(self) -> str:
6464 @property
6565 def outcome (self ) -> str | None :
6666 """``succeeded``, ``failed`` or ``interrupted``, from the run's idle marker or the session."""
67+ from ..types import SessionMessageIdle
68+
6769 for message in reversed (self .messages ):
6870 if isinstance (message , SessionMessageIdle ):
6971 return message .outcome
@@ -72,6 +74,8 @@ def outcome(self) -> str | None:
7274 @property
7375 def error (self ) -> SessionStructuredError | None :
7476 """Why the run failed, from its idle marker or last assistant message, or ``None``."""
77+ from ..types import SessionMessageAssistant , SessionMessageIdle
78+
7579 for message in reversed (self .messages ):
7680 if isinstance (message , (SessionMessageIdle , SessionMessageAssistant )) and message .error is not None :
7781 return message .error
@@ -85,6 +89,8 @@ def cost(self) -> float:
8589 @property
8690 def tokens (self ) -> TokenUsageInfo :
8791 """Token usage of this run, summed over its assistant messages."""
92+ from ..types import TokenUsageInfo , TokenUsageInfoCache
93+
8894 total = TokenUsageInfo (input = 0 , output = 0 , reasoning = 0 , cache = TokenUsageInfoCache (read = 0 , write = 0 ))
8995 for message in self .assistant_messages :
9096 usage = message .tokens
@@ -99,6 +105,8 @@ def tokens(self) -> TokenUsageInfo:
99105
100106
101107def _new_messages (newest_first : list [SessionMessageInfo ], marker : str | None ) -> list [SessionMessageInfo ]:
108+ from ..types import SessionMessageUser
109+
102110 collected : list [SessionMessageInfo ] = []
103111 for message in newest_first :
104112 if marker is not None and message .id == marker :
0 commit comments