66import asyncio
77from concurrent .futures import ThreadPoolExecutor
88
9- from websockets .sync .client import connect
9+ from websockets .sync .client import connect , ClientConnection
1010from websockets .exceptions import ConnectionClosedOK
1111
1212from ..base_client import BaseElevenLabs
@@ -240,6 +240,7 @@ def __init__(
240240 self .client_tools .start ()
241241
242242 self ._thread = None
243+ self ._ws : Optional [ClientConnection ] = None
243244 self ._should_stop = threading .Event ()
244245 self ._conversation_id = None
245246 self ._last_interrupt_id = 0
@@ -257,6 +258,7 @@ def end_session(self):
257258 """Ends the conversation session and cleans up resources."""
258259 self .audio_interface .stop ()
259260 self .client_tools .stop ()
261+ self ._ws = None
260262 self ._should_stop .set ()
261263
262264 def wait_for_session_end (self ) -> Optional [str ]:
@@ -283,6 +285,7 @@ def _run(self, ws_url: str):
283285 }
284286 )
285287 )
288+ self ._ws = ws
286289
287290 def input_callback (audio ):
288291 try :
@@ -369,6 +372,16 @@ def send_response(response):
369372 else :
370373 pass # Ignore all other message types.
371374
375+ def send_contextual_update (self , text : str ):
376+ if not self ._ws :
377+ raise RuntimeError ("WebSocket is not connected" )
378+
379+ payload = {
380+ "type" : "contextual_update" ,
381+ "text" : text ,
382+ }
383+ self ._ws .send (json .dumps (payload ))
384+
372385 def _get_wss_url (self ):
373386 base_ws_url = self .client ._client_wrapper .get_environment ().wss
374387 return f"{ base_ws_url } /v1/convai/conversation?agent_id={ self .agent_id } "
0 commit comments