@@ -136,6 +136,7 @@ class _InputAudioBufferTimeoutTriggeredEvent(BaseModel):
136
136
audio_end_ms : int
137
137
item_id : str
138
138
139
+
139
140
AllRealtimeServerEvents = Annotated [
140
141
Union [
141
142
OpenAIRealtimeServerEvent ,
@@ -144,6 +145,15 @@ class _InputAudioBufferTimeoutTriggeredEvent(BaseModel):
144
145
Field (discriminator = "type" ),
145
146
]
146
147
148
+ ServerEventTypeAdapter : TypeAdapter [AllRealtimeServerEvents ] | None = None
149
+
150
+
151
+ def get_server_event_type_adapter ():
152
+ global ServerEventTypeAdapter
153
+ if not ServerEventTypeAdapter :
154
+ ServerEventTypeAdapter = TypeAdapter (AllRealtimeServerEvents )
155
+ return ServerEventTypeAdapter
156
+
147
157
148
158
class OpenAIRealtimeWebSocketModel (RealtimeModel ):
149
159
"""A model that uses OpenAI's WebSocket API."""
@@ -159,6 +169,7 @@ def __init__(self) -> None:
159
169
self ._tracing_config : RealtimeModelTracingConfig | Literal ["auto" ] | None = None
160
170
self ._playback_tracker : RealtimePlaybackTracker | None = None
161
171
self ._created_session : OpenAISessionObject | None = None
172
+ self ._server_event_type_adapter = get_server_event_type_adapter ()
162
173
163
174
async def connect (self , options : RealtimeModelConfig ) -> None :
164
175
"""Establish a connection to the model and keep it alive."""
@@ -479,9 +490,9 @@ async def _handle_ws_event(self, event: dict[str, Any]):
479
490
try :
480
491
if "previous_item_id" in event and event ["previous_item_id" ] is None :
481
492
event ["previous_item_id" ] = "" # TODO (rm) remove
482
- parsed : AllRealtimeServerEvents = TypeAdapter (
483
- AllRealtimeServerEvents
484
- ). validate_python ( event )
493
+ parsed : OpenAIRealtimeServerEvent = self . _server_event_type_adapter . validate_python (
494
+ event
495
+ )
485
496
except pydantic .ValidationError as e :
486
497
logger .error (f"Failed to validate server event: { event } " , exc_info = True )
487
498
await self ._emit_event (
0 commit comments