o
    lWi                     @   s  d dl mZmZ d dlZd dlZd dlmZ d dlmZ d dl	Z	d dl
Z
d dlZd dlmZmZmZmZmZmZmZmZmZ d dlZd dlZd dlmZ d dlmZmZ dd	lmZ dd
l m!Z! e
"e#Z$G dd de%eZ&G dd de%eZ'G dd dZ(G dd dZ)G dd dZ*G dd deZ+G dd deZ,G dd dZ-G dd dZ.G dd dZ/G dd  d Z0G d!d" d"e0Z1G d#d$ d$e0Z2dS )%    )ABCabstractmethodN)ThreadPoolExecutor)Enum)	Any	AwaitableCallableDictListLiteralOptionalTupleUnion)ConnectionClosedOK)
Connectionconnect   )BaseElevenLabs)__version__c                   @   s,   e Zd ZdZdZdZdZdZdZdZ	dZ
d	S )
ClientToOrchestratorEventz9Event types that can be sent from client to orchestrator.pongclient_tool_result#conversation_initiation_client_datafeedbackcontextual_updateuser_messageuser_activityN)__name__
__module____qualname____doc__PONGCLIENT_TOOL_RESULT#CONVERSATION_INITIATION_CLIENT_DATAFEEDBACKCONTEXTUAL_UPDATEUSER_MESSAGEUSER_ACTIVITY r(   r(   m/var/www/html/asistente-voz-ia/venv/lib/python3.10/site-packages/elevenlabs/conversational_ai/conversation.pyr      s    r   c                   @   s   e Zd ZdZdZdZdS )AgentChatResponsePartTypestartdeltastopN)r   r   r   STARTDELTASTOPr(   r(   r(   r)   r*   &   s    r*   c                   @   s2   e Zd ZdZd	dee fddZdefddZdS )
$UserMessageClientToOrchestratorEventz%Event for sending user text messages.Ntextc                 C      t j| _|| _d S N)r   r&   typer2   selfr2   r(   r(   r)   __init__/      
z-UserMessageClientToOrchestratorEvent.__init__returnc                 C      | j | jdS Nr5   r2   r=   r7   r(   r(   r)   to_dict3      z,UserMessageClientToOrchestratorEvent.to_dictr4   )	r   r   r   r    r   strr8   dictr?   r(   r(   r(   r)   r1   ,   s    r1   c                   @   s(   e Zd ZdZdddZdefddZdS )	%UserActivityClientToOrchestratorEventz>Event for registering user activity (ping to prevent timeout).r:   Nc                 C   s   t j| _d S r4   )r   r'   r5   r>   r(   r(   r)   r8   :   s   z.UserActivityClientToOrchestratorEvent.__init__c                 C   s
   d| j iS )Nr5   )r5   r>   r(   r(   r)   r?   =   s   
z-UserActivityClientToOrchestratorEvent.to_dict)r:   N)r   r   r   r    r8   rB   r?   r(   r(   r(   r)   rC   7   s    
rC   c                   @   s,   e Zd ZdZdefddZdefddZdS )	)ContextualUpdateClientToOrchestratorEventzPEvent for sending non-interrupting contextual updates to the conversation state.r2   c                 C   r3   r4   )r   r%   r5   r2   r6   r(   r(   r)   r8   D   r9   z2ContextualUpdateClientToOrchestratorEvent.__init__r:   c                 C   r;   r<   r=   r>   r(   r(   r)   r?   H   r@   z1ContextualUpdateClientToOrchestratorEvent.to_dictN)r   r   r   r    rA   r8   rB   r?   r(   r(   r(   r)   rD   A   s    rD   c                   @   sV   e Zd ZdZedeegdf fddZedd Zedefd	d
Z	edd Z
dS )AudioInterfacezKAudioInterface provides an abstraction for handling audio input and output.input_callbackNc                 C      dS a?  Starts the audio interface.

        Called one time before the conversation starts.
        The `input_callback` should be called regularly with input audio chunks from
        the user. The audio should be in 16-bit PCM mono format at 16kHz. Recommended
        chunk size is 4000 samples (250 milliseconds).
        Nr(   r7   rF   r(   r(   r)   r+   O   s   	zAudioInterface.startc                 C   rG   a
  Stops the audio interface.

        Called one time after the conversation ends. Should clean up any resources
        used by the audio interface and stop any audio streams. Do not call the
        `input_callback` from `start` after this method is called.
        Nr(   r>   r(   r(   r)   r-   Z      zAudioInterface.stopaudioc                 C   rG   zOutput audio to the user.

        The `audio` input is in 16-bit PCM mono format at 16kHz. Implementations can
        choose to do additional buffering. This method should return quickly and not
        block the calling thread.
        Nr(   r7   rL   r(   r(   r)   outputd   rK   zAudioInterface.outputc                 C   rG   zInterruption signal to stop any audio output.

        User has interrupted the agent and all previosly buffered audio output should
        be stopped.
        Nr(   r>   r(   r(   r)   	interruptn   s   zAudioInterface.interrupt)r   r   r   r    r   r   bytesr+   r-   rO   rQ   r(   r(   r(   r)   rE   L   s    

		rE   c                   @   sZ   e Zd ZdZedeeged f fddZedd Z	edefd	d
Z
edd ZdS )AsyncAudioInterfacezVAsyncAudioInterface provides an async abstraction for handling audio input and output.rF   Nc                       dS rH   r(   rI   r(   r(   r)   r+   {   s   	zAsyncAudioInterface.startc                    rT   rJ   r(   r>   r(   r(   r)   r-         zAsyncAudioInterface.stoprL   c                    rT   rM   r(   rN   r(   r(   r)   rO      rU   zAsyncAudioInterface.outputc                    rT   rP   r(   r>   r(   r(   r)   rQ      s   zAsyncAudioInterface.interrupt)r   r   r   r    r   r   rR   r   r+   r-   rO   rQ   r(   r(   r(   r)   rS   x   s    

		rS   c                
   @   s   e Zd ZdZddeej ddfddZdd Zd	d
 Z		dde
deeegef eegee f f deddfddZde
dedefddZde
dedeegdf fddZdd ZdS )ClientToolsaR  Handles registration and execution of client-side tools that can be called by the agent.

    Supports both synchronous and asynchronous tools running in a dedicated event loop,
    ensuring non-blocking operation of the main conversation thread.

    Args:
        loop: Optional custom asyncio event loop to use for tool execution. If not provided,
              a new event loop will be created and run in a separate thread. Using a custom
              loop prevents "different event loop" runtime errors and allows for better
              context propagation and resource management.
    Nloopr:   c                 C   s8   i | _ t | _|| _d | _d | _t | _t	 | _
d S r4   )tools	threadingLocklock_custom_loop_loop_threadEvent_runningr   thread_pool)r7   rW   r(   r(   r)   r8      s   

zClientTools.__init__c                    sd    j  rdS  jdur j _ j   dS  fdd}tj|ddd _ j   j 	  dS )zHStart the event loop in a separate thread for handling async operations.Nc                      sh   t   _t  j  j  z j  W  j   j  d  _d S  j   j  d  _w r4   )	asyncionew_event_loopr]   set_event_loopr`   setrun_foreverclearcloser(   r>   r(   r)   run_event_loop   s   






z)ClientTools.start.<locals>.run_event_loopTzClientTools-EventLoop)targetdaemonname)
r`   is_setr\   r]   re   rY   Threadr^   r+   wait)r7   ri   r(   r>   r)   r+      s   


zClientTools.startc                 C   s`   | j r,| j r.| jdur| j  n| j | j j | jr#| j  | j	j
dd dS dS dS )z6Gracefully stop the event loop and clean up resources.NF)ro   )r]   r`   rm   r\   rg   call_soon_threadsafer-   r^   joinra   shutdownr>   r(   r(   r)   r-      s   

zClientTools.stopF	tool_namehandleris_asyncc                 C   sd   | j % t|std|| jv rtd| d||f| j|< W d   dS 1 s+w   Y  dS )a  Register a new tool that can be called by the AI agent.

        Args:
            tool_name: Unique identifier for the tool
            handler: Function that implements the tool's logic
            is_async: Whether the handler is an async function
        zHandler must be callableTool 'z' is already registeredN)r[   callable
ValueErrorrX   )r7   rs   rt   ru   r(   r(   r)   register   s   
"zClientTools.register
parametersc                    s|   | j  || jvrtd| d| j| \}}W d   n1 s#w   Y  |r1||I dH S t | j||I dH S )zpExecute a registered tool with the given parameters.

        Returns the result of the tool execution.
        rv   z' is not registeredN)r[   rX   rx   rb   get_event_looprun_in_executorra   )r7   rs   rz   rt   ru   r(   r(   r)   handle   s   
zClientTools.handlecallbackc                    sF   j  s	tdjdu rtd fdd}|  dS )zExecute a tool and send its result via the provided callback.

        This method is non-blocking and handles both sync and async tools.
        z%ClientTools event loop is not runningNzEvent loop is not availablec               
      s   z I d H } dd| pd ddd}W n ty: } zddt|dd}W Y d }~nd }~ww  | d S )Nr   tool_call_idzClient tool: z called successfully.F)r5   r   resultis_errorT)r}   get	ExceptionrA   )r   responseer~   rz   r7   rs   r(   r)   _execute_and_callback  s"   
z7ClientTools.execute_tool.<locals>._execute_and_callback)r`   rm   RuntimeErrorr]   _schedule_coroutine)r7   rs   rz   r~   r   r(   r   r)   execute_tool  s   

zClientTools.execute_toolc                 C   s$   | j dur| j|S t|| jS )z3Schedule a coroutine on the appropriate event loop.N)r\   r]   create_taskrb   run_coroutine_threadsafe)r7   coror(   r(   r)   r   $  s   
zClientTools._schedule_coroutiner4   )F)r   r   r   r    r   rb   AbstractEventLoopr8   r+   r-   rA   r   r   rB   r   r   boolry   r}   r   r   r(   r(   r(   r)   rV      s$    	"
 rV   c                
   @   sD   e Zd ZdZ				d	dee dee dee dee fddZdS )
ConversationInitiationDataz+Configuration options for the Conversation.N
extra_bodyconversation_config_overridedynamic_variablesuser_idc                 C   s(   |pi | _ |pi | _|pi | _|| _d S r4   )r   r   r   r   )r7   r   r   r   r   r(   r(   r)   r8   /  s   



z#ConversationInitiationData.__init__)NNNN)r   r   r   r    r   rB   rA   r8   r(   r(   r(   r)   r   ,  s    r   c                   @   sh   e Zd ZdZ						ddedee dee dee deee  deee  d	eee  fd
dZdS )OnPremInitiationDataz;Configuration options for the Conversation in on-prem mode.Non_prem_conversation_url#post_call_transcription_webhook_urlpost_call_audio_webhook_urlagent_config_dictoverride_agent_config_listtools_config_listprompt_knowledge_basec                 C   s.   || _ || _|| _|| _|| _|| _|| _d S r4   )r   r   r   r   r   r   r   )r7   r   r   r   r   r   r   r   r(   r(   r)   r8   ?  s   

zOnPremInitiationData.__init__)NNNNNN)	r   r   r   r    rA   r   rB   r
   r8   r(   r(   r(   r)   r   <  s.    


r   c                   @   s   e Zd ZdZ	ddddddededee dedee d	ee	 d
ee
 fddZdd Zdd Zdd Zdd Zdd Zdd ZdS )BaseConversationzMBase class for conversation implementations with shared parameters and logic.N)configclient_toolson_prem_configclientagent_idr   requires_authr   r   r   c                C   sP   || _ || _|| _|| _|pt | _|pt | _|| _| j	  d | _
d| _d S )Nr   )r   r   r   r   r   r   rV   r   r   r+   _conversation_id_last_interrupt_id)r7   r   r   r   r   r   r   r   r(   r(   r)   r8   T  s   

zBaseConversation.__init__c                 C   sh   | j r| j jS | jj }tj|j|	drdndd
 }|ds)|d7 }| d| j dt S )Nhttpswssws)scheme/z v1/convai/conversation?agent_id=z&source=python_sdk&version=)r   r   r   _client_wrapperget_base_urlurllibparseurlparse_replace
startswithgeturlendswithr   r   )r7   base_http_urlbase_ws_urlr(   r(   r)   _get_wss_urll  s   &
zBaseConversation._get_wss_urlc                 C   s<   | j jjj| jd}|j}d|v rdnd}| | dt S )N)r   ?&zsource=python_sdk&version=)r   conversational_aiconversationsget_signed_urlr   
signed_urlr   )r7   r   r   	separatorr(   r(   r)   _get_signed_urlw  s   z BaseConversation._get_signed_urlc              
   C   s2   t d| jj| jj| jj| jj| jj| jjdS )Nenclave_setup_config)r5   r   r   r   r   r   r   )	jsondumpsr   r   r   r   r   r   r   r>   r(   r(   r)   "_create_on_prem_initiation_message~  s   z3BaseConversation._create_on_prem_initiation_messagec              	   C   sD   t d| jj| jj| jjdtdd| jjrd| jjiS i S )Nr   
python_sdk)sourceversion)r5   custom_llm_extra_bodyr   r   source_infor   )r   r   r   r   r   r   r   r   r>   r(   r(   r)   _create_initiation_message  s   	
z+BaseConversation._create_initiation_messagec                 C   s\  |d dkr|d }| j du sJ |d | _ dS |d dkr;|d }t|d | jkr-dS t|d	 }|| dS |d d
krU|jrS|d }||d
   dS dS |d dkr|j	r|
di }|
dd}|
dd}zt|}W n ty   tj}Y nw ||| dS dS |d dkr|jr|d }||d  |d   dS dS |d dkr|jr|d }||d   dS dS |d dkr|d }t|d | _|  dS |d dkr|d }|| |jr|d r|t|d  dS dS dS |d dkr+|
di }|
d}	d|d i|
di }
||	|
 dS 	 dS ) zCore message handling logic shared between sync and async implementations.

        Args:
            message: The parsed message dictionary
            message_handler: Handler object with methods for different operations
        r5    conversation_initiation_metadata&conversation_initiation_metadata_eventNconversation_idrL   audio_eventevent_idaudio_base_64agent_responseagent_response_eventagent_chat_response_parttext_response_partr2    r,   agent_response_correctionagent_response_correction_eventoriginal_agent_responsecorrected_agent_responseuser_transcriptuser_transcription_eventinterruptioninterruption_eventping
ping_eventping_msclient_tool_callrs   r   rz   r   intr   base64	b64decodehandle_audio_outputcallback_agent_responsehandle_agent_responsestrip!callback_agent_chat_response_partr   r*   rx   r/   handle_agent_chat_response_part"callback_agent_response_correction handle_agent_response_correctioncallback_user_transcripthandle_user_transcripthandle_interruptionhandle_pingcallback_latency_measurementhandle_latency_measurementhandle_client_tool_callr7   messagemessage_handlereventrL   r2   part_type_str	part_type	tool_callrs   rz   r(   r(   r)   _handle_message_core  sp   





z%BaseConversation._handle_message_corec                    s  |d dkr|d }| j du sJ |d | _ dS |d dkr?|d }t|d | jkr.dS t|d	 }||I dH  dS |d d
kr\|jrZ|d }||d
  I dH  dS dS |d dkr|j	r|
di }|
dd}|
dd}zt|}W n ty   tj}Y nw |||I dH  dS dS |d dkr|jr|d }||d  |d  I dH  dS dS |d dkr|jr|d }||d  I dH  dS dS |d dkr|d }t|d | _| I dH  dS |d dkr|d }||I dH  |jr|d r|t|d I dH  dS dS dS |d dkrD|
di }|
d}	d|d i|
di }
||	|
 dS 	 dS ) z.Async wrapper for core message handling logic.r5   r   r   Nr   rL   r   r   r   r   r   r   r   r2   r   r,   r   r   r   r   r   r   r   r   r   r   r   r   rs   r   rz   r   r   r(   r(   r)   _handle_message_core_async  sr   




z+BaseConversation._handle_message_core_asyncr4   )r   r   r   r    r   rA   r   r   r   rV   r   r8   r   r   r   r   r   r   r(   r(   r(   r)   r   Q  s8    	
Cr   c                       s  e Zd ZU eed< eeegdf  ed< eeeegdf  ed< eeeegdf  ed< eeegdf  ed< eee	gdf  ed< ee ed< ee
j ed	< e
jed
< ee ed< 	d)dddddddddd	dededee dededee dee deeegdf  deeeegdf  deeeegdf  deeegdf  deee	gdf  dee dee f fddZdd Zdd Zdee fddZdefddZd d! Zdefd"d#Zd$efd%d&Zd'd( Z  ZS )*Conversationaudio_interfaceNr   r   r   r   r   callback_end_sessionr^   _should_stop_ws	r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   c             	      ^   t  j|||||||d || _|| _|	| _|
| _|| _|| _|| _d| _	d| _
t | _dS )a  Conversational AI session.

        BETA: This API is subject to change without regard to backwards compatibility.

        Args:
            client: The ElevenLabs client to use for the conversation.
            agent_id: The ID of the agent to converse with.
            user_id: The ID of the user conversing with the agent.
            requires_auth: Whether the agent requires authentication.
            audio_interface: The audio interface to use for input and output.
            client_tools: The client tools to use for the conversation.
            callback_agent_response: Callback for agent responses.
            callback_agent_response_correction: Callback for agent response corrections.
                First argument is the original response (previously given to
                callback_agent_response), second argument is the corrected response.
            callback_agent_chat_response_part: Callback for streaming text response chunks.
                First argument is the text chunk, second argument is the type (START, DELTA, STOP).
            callback_user_transcript: Callback for user transcripts.
            callback_latency_measurement: Callback for latency measurements (in milliseconds).
        r   r   r   r   r   r   r   N)superr8   r   r   r   r   r   r   r   r^   r   rY   r_   r   r7   r   r   r   r   r   r   r   r   r   r   r   r   r   r   	__class__r(   r)   r8   )  s&   '
zConversation.__init__c                 C   s8   | j r|  n|  }tj| j|fd| _| j  dS )zoStarts the conversation session.

        Will run in background thread until `end_session` is called.
        )rj   argsN)r   r   r   rY   rn   _runr^   r+   r7   ws_urlr(   r(   r)   start_sessionf  s   zConversation.start_sessionc                 C   s:   | j   | j  d| _| j  | jr|   dS dS z6Ends the conversation session and cleans up resources.Nr   r-   r   r   r   re   r   r>   r(   r(   r)   end_sessiono  s   


zConversation.end_sessionr:   c                 C   s   | j std| j   | jS )Waits for the conversation session to end.

        You must call `end_session` before calling this method, otherwise it will block.

        Returns the conversation ID, if available.
        Session not started.)r^   r   rq   r   r>   r(   r(   r)   wait_for_session_endy  s   
z!Conversation.wait_for_session_endr2   c              
   C   `   | j stdt|d}z| j t|  W dS  ty/ } z	t	d|   d}~ww )Send a text message from the user to the agent.

        Args:
            text: The text message to send to the agent.

        Raises:
            RuntimeError: If the session is not active or websocket is not connected.
        /Session not started or websocket not connected.r2   Error sending user message: N
r   r   r1   sendr   r   r?   r   loggererrorr7   r2   r   r   r(   r(   r)   send_user_message  s   	
zConversation.send_user_messagec              
   C   s\   | j stdt }z| j t|  W dS  ty- } z	t	d|   d}~ww )Register user activity to prevent session timeout.

        This sends a ping to the orchestrator to reset the timeout timer.

        Raises:
            RuntimeError: If the session is not active or websocket is not connected.
        r  !Error registering user activity: N
r   r   rC   r  r   r   r?   r   r  r  r7   r   r   r(   r(   r)   register_user_activity  s   z#Conversation.register_user_activityc              
   C   r  )a  Send a contextual update to the conversation.

        Contextual updates are non-interrupting content that is sent to the server
        to update the conversation state without directly prompting the agent.

        Args:
            content: The contextual information to send to the conversation.

        Raises:
            RuntimeError: If the session is not active or websocket is not connected.
        r  r  !Error sending contextual update: N
r   r   rD   r  r   r   r?   r   r  r  r  r(   r(   r)   send_contextual_update  s   
z#Conversation.send_contextual_updater  c                    sJ  t |dd _ jr       _ fdd} j|  j	 szt
jdd} j	 rHW W d    d S  | W n; tye } z
   W Y d }~n*d }~w tym   Y n ty } ztd|     W Y d }~nd }~ww  j	 r0d  _W d    d S 1 sw   Y  d S )N   max_sizec              
      s~   z tdt|  i W d S  ty       Y d S  ty> } zt	
d|     W Y d }~d S d }~ww Nuser_audio_chunkz Error sending user audio chunk: r  r   r   r   	b64encodedecoder   r  r   r  r  rL   r   r7   r   r(   r)   rF     s   
z)Conversation._run.<locals>.input_callback      ?timeoutError receiving message: )r   r   r   r  r   r   r   r+   r   rm   r   loadsrecv_handle_messager   r  TimeoutErrorr   r  r  )r7   r  rF   r   r   r(   r/  r)   r	    s8   


"zConversation._runc                 C   s(   G dd d}|| |}|  || d S )Nc                   @   \   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd ZdS )z8Conversation._handle_message.<locals>.SyncMessageHandlerc                 S   8   || _ || _|j| _|j| _|j| _|j| _|j| _d S r4   conversationr   r   r   r   r   r   r7   r;  r   r(   r(   r)   r8        zAConversation._handle_message.<locals>.SyncMessageHandler.__init__c                 S   s   | j j| d S r4   r;  r   rO   rN   r(   r(   r)   r        zLConversation._handle_message.<locals>.SyncMessageHandler.handle_audio_outputc                 S      | j | d S r4   r;  r   r7   r   r(   r(   r)   r        zNConversation._handle_message.<locals>.SyncMessageHandler.handle_agent_responsec                 S      | j || d S r4   r;  r   r7   original	correctedr(   r(   r)   r     r?  zYConversation._handle_message.<locals>.SyncMessageHandler.handle_agent_response_correctionc                 S   rD  r4   r;  r   r7   r2   r   r(   r(   r)   r     r?  zXConversation._handle_message.<locals>.SyncMessageHandler.handle_agent_chat_response_partc                 S   r@  r4   r;  r   r7   
transcriptr(   r(   r)   r     rC  zOConversation._handle_message.<locals>.SyncMessageHandler.handle_user_transcriptc                 S   s   | j j  d S r4   r;  r   rQ   r>   r(   r(   r)   r     rC  zLConversation._handle_message.<locals>.SyncMessageHandler.handle_interruptionc                 S   s    | j td|d d d S Nr   r   )r5   r   r   r  r   r   r7   r   r(   r(   r)   r     s   zDConversation._handle_message.<locals>.SyncMessageHandler.handle_pingc                 S   r@  r4   r;  r   r7   latencyr(   r(   r)   r     rC  zSConversation._handle_message.<locals>.SyncMessageHandler.handle_latency_measurementc                    "    fdd} j j||| d S )Nc                    s&    j j s jt|  d S d S r4   )r;  r   rm   r   r  r   r   r   r>   r(   r)   send_response  s   zgConversation._handle_message.<locals>.SyncMessageHandler.handle_client_tool_call.<locals>.send_responser;  r   r   r7   rs   rz   rW  r(   r>   r)   r        zPConversation._handle_message.<locals>.SyncMessageHandler.handle_client_tool_callNr   r   r   r8   r   r   r   r   r   r   r   r   r   r(   r(   r(   r)   SyncMessageHandler      	
r\  )r   )r7   r   r   r\  rt   r(   r(   r)   r6    s   
0zConversation._handle_messager4   )r   r   r   rE   __annotations__r   r   rA   r*   r   rY   rn   r_   r   r   r   r   rV   r   r8   r  r  r  r  r"  r%  r	  r6  __classcell__r(   r(   r  r)   r     sv   
 
	
=	
(r   c                        s  e Zd ZU eed< eeeged f  ed< eeeeged f  ed< eeee	ged f  ed< eeeged f  ed< eee
ged f  ed< eeg ed f  ed< eej ed	< ejed
< eej ed< 	d)dddddddddd	dededee dededee dee deeeged f  deeeeged f  deeee	ged f  deeeged f  deee
ged f  deeg ed f  dee f fddZdd Zdd Zdee fddZdefddZd d! Zdefd"d#Zd$efd%d&Zd'd( Z  ZS )*AsyncConversationr   Nr   r   r   r   r   r   _taskr   r   r  r   r   r   r   r   r   r   c             	      r  )a@  Async Conversational AI session.

        BETA: This API is subject to change without regard to backwards compatibility.

        Args:
            client: The ElevenLabs client to use for the conversation.
            agent_id: The ID of the agent to converse with.
            user_id: The ID of the user conversing with the agent.
            requires_auth: Whether the agent requires authentication.
            audio_interface: The async audio interface to use for input and output.
            client_tools: The client tools to use for the conversation.
            callback_agent_response: Async callback for agent responses.
            callback_agent_response_correction: Async callback for agent response corrections.
                First argument is the original response (previously given to
                callback_agent_response), second argument is the corrected response.
            callback_agent_chat_response_part: Async callback for streaming text response chunks.
                First argument is the text chunk, second argument is the type (START, DELTA, STOP).
            callback_user_transcript: Async callback for user transcripts.
            callback_latency_measurement: Async callback for latency measurements (in milliseconds).
            callback_end_session: Async callback for when session ends.
        r  N)r  r8   r   r   r   r   r   r   r   ra  r   rb   r_   r   r  r  r(   r)   r8   *  s&   (
zAsyncConversation.__init__c                    s.   | j r|  n|  }t| || _dS )zmStarts the conversation session.

        Will run in background task until `end_session` is called.
        N)r   r   r   rb   r   r	  ra  r
  r(   r(   r)   r  h  s   zAsyncConversation.start_sessionc                    sH   | j  I dH  | j  d| _| j  | jr"|  I dH  dS dS r  r  r>   r(   r(   r)   r  p  s   

zAsyncConversation.end_sessionr:   c                    s"   | j std| j I dH  | jS )r  r  N)ra  r   r   r>   r(   r(   r)   r  z  s
   z&AsyncConversation.wait_for_session_endr2   c              
      h   | j stdt|d}z| j t| I dH  W dS  ty3 } z	t	d|   d}~ww )r  r  r  Nr  r  r  r(   r(   r)   r    s   	
"z#AsyncConversation.send_user_messagec              
      sd   | j stdt }z| j t| I dH  W dS  ty1 } z	t	d|   d}~ww )r  r  Nr  r   r!  r(   r(   r)   r"    s   "z(AsyncConversation.register_user_activityc              
      rb  )a  Send a contextual update to the conversation.

        Contextual updates are non-interrupting content that is sent to the server
        to update the conversation state without directly prompting the agent.

        Args:
            text: The contextual information to send to the conversation.

        Raises:
            RuntimeError: If the session is not active or websocket is not connected.
        r  r  Nr#  r$  r  r(   r(   r)   r%    s   
"z(AsyncConversation.send_contextual_updater  c                    s  t j|dd4 I d H  _ jr  I d H    I d H   fdd} j|I d H  zz j	
 sz1tj ddI d H } j	
 r_W W d  _W d   I d H  d S t|} |I d H  W n9 tjyx   Y n0 ty     I d H  Y n& ty } ztd|    I d H  W Y d }~n
d }~ww  j	
 r=W d  _nd  _w W d   I d H  d S 1 I d H sw   Y  d S )Nr&  r'  c              
      s   z tdt|  iI d H  W d S  ty'     I d H  Y d S  tyH } zt	
d|    I d H  W Y d }~d S d }~ww r)  r+  r.  r/  r(   r)   rF     s   z.AsyncConversation._run.<locals>.input_callbackr0  r1  r3  )
websocketsr   r   r   r  r   r   r   r+   r   rm   rb   wait_forr5  r   r4  r6  r7  r   r  r   r  r  )r7   r  rF   message_strr   r   r(   r/  r)   r	    sB   



.zAsyncConversation._runc                    s0   G dd d}|| |}|  ||I d H  d S )Nc                   @   r8  )z>AsyncConversation._handle_message.<locals>.AsyncMessageHandlerc                 S   r9  r4   r:  r<  r(   r(   r)   r8     r=  zGAsyncConversation._handle_message.<locals>.AsyncMessageHandler.__init__c                    s   | j j|I d H  d S r4   r>  rN   r(   r(   r)   r        zRAsyncConversation._handle_message.<locals>.AsyncMessageHandler.handle_audio_outputc                       | j |I d H  d S r4   rA  rB  r(   r(   r)   r        zTAsyncConversation._handle_message.<locals>.AsyncMessageHandler.handle_agent_responsec                       | j ||I d H  d S r4   rE  rF  r(   r(   r)   r     rf  z_AsyncConversation._handle_message.<locals>.AsyncMessageHandler.handle_agent_response_correctionc                    ri  r4   rI  rJ  r(   r(   r)   r     rf  z^AsyncConversation._handle_message.<locals>.AsyncMessageHandler.handle_agent_chat_response_partc                    rg  r4   rK  rL  r(   r(   r)   r     rh  zUAsyncConversation._handle_message.<locals>.AsyncMessageHandler.handle_user_transcriptc                    s   | j j I d H  d S r4   rN  r>   r(   r(   r)   r     rh  zRAsyncConversation._handle_message.<locals>.AsyncMessageHandler.handle_interruptionc                    s(   | j td|d dI d H  d S rO  rP  rQ  r(   r(   r)   r   
  s   zJAsyncConversation._handle_message.<locals>.AsyncMessageHandler.handle_pingc                    rg  r4   rR  rS  r(   r(   r)   r     rh  zYAsyncConversation._handle_message.<locals>.AsyncMessageHandler.handle_latency_measurementc                    rU  )Nc                    s,    j j st jt|  d S d S r4   )	r;  r   rm   rb   r   r   r  r   r   rV  r>   r(   r)   rW    s   zmAsyncConversation._handle_message.<locals>.AsyncMessageHandler.handle_client_tool_call.<locals>.send_responserX  rY  r(   r>   r)   r     rZ  zVAsyncConversation._handle_message.<locals>.AsyncMessageHandler.handle_client_tool_callNr[  r(   r(   r(   r)   AsyncMessageHandler  r]  rj  )r   )r7   r   r   rj  rt   r(   r(   r)   r6    s   
0z!AsyncConversation._handle_messager4   )r   r   r   rS   r^  r   r   rA   r   r*   r   rb   Taskr_   rc  WebSocketClientProtocolr   r   r   rV   r   r8   r  r  r  r  r"  r%  r	  r6  r_  r(   r(   r  r)   r`    sv   
 
	
>
,r`  )3abcr   r   rb   r   concurrent.futuresr   enumr   r   loggingrY   typingr   r   r   r	   r
   r   r   r   r   urllib.parser   rc  websockets.exceptionsr   websockets.sync.clientr   r   base_clientr   r   r   	getLoggerr   r  rA   r   r*   r1   rC   rD   rE   rS   rV   r   r   r   r   r`  r(   r(   r(   r)   <module>   sB    ,

,, 	 L  