11from dataclasses import dataclass , field
2- from typing import Any , Generic
2+ from typing import Any , Awaitable , Callable , Generic , Mapping , Optional
33
44from typing_extensions import TypeVar
55
@@ -24,3 +24,25 @@ class RunContextWrapper(Generic[TContext]):
2424 """The usage of the agent run so far. For streamed responses, the usage will be stale until the
2525 last chunk of the stream is processed.
2626 """
27+
28+ # Internal emitter for streaming custom tool events; set by the Runner in streaming mode.
29+ _emit_fn : Optional [Callable [[Any ], Awaitable [None ]]] = field (default = None , repr = False )
30+ # Current agent reference for constructing RunItem wrappers; set by the Runner.
31+ _current_agent : Any = field (default = None , repr = False )
32+
33+ async def emit_event (self , event : Mapping [str , Any ]) -> None :
34+ """
35+ Emit a developer-defined event dict via the run's main stream.
36+ The dict should include at least a 'type' key. The event will be forwarded
37+ as a RunItemStreamEvent(name='tool_event', item.raw_item=event).
38+
39+ No-op if not in streaming mode.
40+ """
41+ if not self ._emit_fn or not isinstance (event , Mapping ) or not event .get ("type" ):
42+ return
43+ # Lazy import to avoid circular dependencies at module import time
44+ from .items import ToolCallItem
45+ from .stream_events import RunItemStreamEvent
46+
47+ item = ToolCallItem (raw_item = dict (event ), agent = self ._current_agent )
48+ await self ._emit_fn (RunItemStreamEvent (name = "tool_event" , item = item ))
0 commit comments