
    qis                     ~   d Z ddlZddlmZ ddlmZmZmZmZm	Z	 ddl
Z
ddlmZ ddlmZ ddlmZ ddlmZmZmZmZmZmZmZmZmZmZmZ dd	lmZmZm Z  dd
l!m"Z" ddl#m$Z$ ddl%m&Z&m'Z' ddl(m)Z)m*Z*m+Z+  G d d      Z, G d de      Z- G d de*      Z. G d d      Z/ G d de"      Z0 G d de$      Z1 G d de&      Z2y)a  Tavus transport implementation for Pipecat.

This module provides integration with the Tavus platform for creating conversational
AI applications with avatars. It manages conversation sessions and provides real-time
audio/video streaming capabilities through the Tavus API.
    N)partial)Any	AwaitableCallableMappingOptional)	AudioData)logger)	BaseModel)BotConnectedFrameCancelFrameClientConnectedFrameEndFrameFrameInputAudioRawFrameInterruptionFrameOutputAudioRawFrameOutputTransportMessageFrame!OutputTransportMessageUrgentFrame
StartFrame)FrameDirectionFrameProcessorFrameProcessorSetup)BaseInputTransport)BaseOutputTransport)BaseTransportTransportParams)DailyCallbacksDailyParamsDailyTransportClientc                   p    e Zd ZdZdZdZdZdedej                  fdZ
ded	ed
efdZdefdZd	ed
efdZy)TavusApizHelper class for interacting with the Tavus API (v2).

    Provides methods for creating and managing conversations with Tavus avatars,
    including conversation lifecycle management and persona information retrieval.
    zhttps://tavusapi.com/v2zdev-conversationTestTavusTransportapi_keysessionc                 |    || _         || _        d| j                   d| _        t        j                  d      | _        y)zInitialize the TavusApi client.

        Args:
            api_key: Tavus API key for authentication.
            session: An aiohttp session for making HTTP requests.
        zapplication/json)zContent-Typez	x-api-keyTAVUS_SAMPLE_ROOM_URLN)_api_key_session_headersosgetenv_dev_room_url)selfr$   r%   s      T/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/transports/tavus/transport.py__init__zTavusApi.__init__:   s4      );$--XYY'>?    
replica_id
persona_idreturnc                   K   | j                   r| j                  | j                   dS t        j                  d| d|        | j                   d}||d}| j
                  j                  || j                  |      4 d{   }|j                          |j                          d{   }t        j                  d|        |cddd      d{    S 7 W7 17 	# 1 d{  7  sw Y   yxY ww)	a?  Create a new conversation with the specified replica and persona.

        Args:
            replica_id: ID of the replica to use in the conversation.
            persona_id: ID of the persona to use in the conversation.

        Returns:
            Dictionary containing conversation_id and conversation_url.
        )conversation_idconversation_urlz%Creating Tavus conversation: replica=z
, persona=z/conversations)r2   r3   )headersjsonNzCreated Tavus conversation: )
r-   MOCK_CONVERSATION_IDr
   debugBASE_URLr)   postr*   raise_for_statusr9   )r.   r2   r3   urlpayloadrresponses          r/   create_conversationzTavusApi.create_conversationG   s      #'#<#<$($6$6 
 	<ZL
S]R^_`~.$$
 ==%%c4==w%O 	 	ST VVX~HLL7zBC		 	 	%	 	 	 	sZ   BC6CC6$C!+C,C!	C6CC6C!C6!C3'C*(C3/C6r6   c                 V  K   ||| j                   k(  ry| j                   d| d}| j                  j                  || j                        4 d{   }|j                          t        j                  d|        ddd      d{    y7 =7 # 1 d{  7  sw Y   yxY ww)zqEnd an existing conversation.

        Args:
            conversation_id: ID of the conversation to end.
        Nz/conversations/z/endr8   zEnded Tavus conversation )r:   r<   r)   r=   r*   r>   r
   r;   )r.   r6   r?   rA   s       r/   end_conversationzTavusApi.end_conversationc   s      "o9R9R&R.?tD==%%c4==%A 	H 	HQ LL4_4EFG	H 	H 	H 	H 	H 	H 	HsH   AB)BB))B?B)
BB)B)B&BB&"B)c                   K   | j                   | j                  S | j                   d| }| j                  j	                  || j
                        4 d{   }|j                          |j                          d{   }t        j                  d|        |d   cddd      d{    S 7 Z7 47 	# 1 d{  7  sw Y   yxY ww)zGet the name of a persona by ID.

        Args:
            persona_id: ID of the persona to retrieve.

        Returns:
            The name of the persona.
        Nz
/personas/rE   zFetched Tavus persona: persona_name)
r-   MOCK_PERSONA_NAMEr<   r)   getr*   r>   r9   r
   r;   )r.   r3   r?   rA   rB   s        r/   get_persona_namezTavusApi.get_persona_nameq   s      ))))z*6==$$S$--$@ 	, 	,A VVX~HLL28*=>N+		, 	, 	,%	, 	, 	, 	,sZ   ACB2C$B8?B4  B8 C,B6-C4B86C8C
>C?C
CN)__name__
__module____qualname____doc__r<   r:   rI   straiohttpClientSessionr0   dictrC   rF   rK    r1   r/   r"   r"   /   sq     )H-,@ @g.C.C @C S T 8Hc H, , ,r1   r"   c                       e Zd ZU dZeeeef   ged   f   e	d<   eeeef   ged   f   e	d<   eeeef   eged   f   e	d<   y)TavusCallbacksa  Callback handlers for Tavus events.

    Parameters:
        on_joined: Called when the bot joins the Daily room.
        on_participant_joined: Called when a participant joins the conversation.
        on_participant_left: Called when a participant leaves the conversation.
    N	on_joinedon_participant_joinedon_participant_left)
rL   rM   rN   rO   r   r   rP   r   r   __annotations__rT   r1   r/   rV   rV      sk     c*+Yt_<==#WS#X%6$74$HII!738#4c":IdO"KLLr1   rV   c                   <    e Zd ZU dZdZeed<   dZeed<   dZeed<   y)TavusParamsa(  Configuration parameters for the Tavus transport.

    Parameters:
        audio_in_enabled: Whether to enable audio input from participants.
        audio_out_enabled: Whether to enable audio output to participants.
        microphone_out_enabled: Whether to enable microphone output track.
    Taudio_in_enabledaudio_out_enabledFmicrophone_out_enabledN)	rL   rM   rN   rO   r]   boolrZ   r^   r_   rT   r1   r/   r\   r\      s*     "d!"t"#(D(r1   r\   c                   ^   e Zd ZdZ e       dddededededed	ed
ej                  ddfdZ	defdZ
defdZd Zd Zd Zd ZdefdZdefdZd Z	 	 	 d+dededededef
dZ	 	 	 d,dededed ed!ef
d"Zdeez  fd#Zedefd$       Zedefd%       Zd-d&Zd.d'Z de!de"fd(Z#d)efd*Z$y)/TavusTransportClienta  Transport client that integrates Pipecat with the Tavus platform.

    A transport client that integrates a Pipecat Bot with the Tavus platform by managing
    conversation sessions using the Tavus API.

    This client uses `TavusApi` to interact with the Tavus backend services. When a conversation
    is started via `TavusApi`, Tavus provides a `roomURL` that can be used to connect the Pipecat Bot
    into the same virtual room where the TavusBot is operating.
    pipecat-stream)paramsr3   bot_namerd   	callbacksr$   r2   r3   r%   r4   Nc                    || _         t        ||      | _        || _        || _        d| _        d| _        || _        || _        y)a  Initialize the Tavus transport client.

        Args:
            bot_name: The name of the Pipecat bot instance.
            params: Optional parameters for Tavus operation.
            callbacks: Callback handlers for Tavus-related events.
            api_key: API key for authenticating with Tavus API.
            replica_id: ID of the replica to use in the Tavus conversation.
            persona_id: ID of the Tavus persona. Defaults to "pipecat-stream",
                which signals Tavus to use the TTS voice of the Pipecat bot
                instead of a Tavus persona voice.
            session: The aiohttp session for making async HTTP requests.
        N)		_bot_namer"   _api_replica_id_persona_id_conversation_id_client
_callbacks_params)r.   re   rd   rf   r$   r2   r3   r%   s           r/   r0   zTavusTransportClient.__init__   sF    0 "Wg.	%%/37;#r1   c                    K   | j                   j                  | j                  | j                         d{   }|d   | _        |d   S 7 w)z4Initialize the conversation and return the room URL.Nr6   r7   )ri   rC   rj   rk   rl   )r.   rB   s     r/   _initializez TavusTransportClient._initialize   sK     66t7G7GIYIYZZ (): ;*++ [s   4AA
Asetupc           	        K   | j                   #t        j                  d| j                           y	 | j                          d{   }t	        d!i dt        | j                  d      d| j                  d| j                  dt        | j                  d      dt        | j                  d      dt        | j                  d      d	t        | j                  d	      d
t        | j                  d
      dt        | j                  d      dt        | j                  d      dt        | j                  d      dt        | j                  d      dt        | j                  d      dt        | j                  d      dt        | j                  d      dt        | j                  d      dt        | j                  d      dt        | j                  d      dt        | j                  d      d| j                  j                  d| j                  j                  dt        | j                  d      dt        | j                  d      dt        | j                  d      dt        | j                  d      dt        | j                  d      dt        | j                  d      dt        | j                  d      }t        |dd| j                  || j                        | _        | j                  j!                  |       d{    y7 7 # t"        $ rW}t        j$                  d |        | j&                  j)                  | j                          d{  7   d| _         Y d}~yd}~ww xY ww)"zSetup the client and initialize the conversation.

        Args:
            setup: The frame processor setup configuration.
        Nz!Conversation ID already defined: on_active_speaker_changedrW   on_lefton_before_leaveon_erroron_app_messageon_call_state_updatedon_client_connectedon_client_disconnectedon_dialin_connectedon_dialin_readyon_dialin_stoppedon_dialin_erroron_dialin_warningon_dialout_answeredon_dialout_connectedon_dialout_stoppedon_dialout_erroron_dialout_warningrX   rY   on_participant_updatedon_transcription_messageon_recording_startedon_recording_stoppedon_recording_erroron_transcription_stoppedon_transcription_errorPipecatz&Failed to setup TavusTransportClient: rT   )rl   r
   r;   rq   r   r   _on_handle_callback
_on_joined_on_leftrn   rX   rY   r    ro   rh   rm   rr   	Exceptionerrorri   rF   )r.   rr   room_urldaily_callbackses        r/   rr   zTavusTransportClient.setup   su       ,LL<T=R=R<STU-	)!--//H, #*1,,.I+# //	#
 # !((@(@BS T# !!9!9:F#  't'?'?AQR# '.d.F.FH_&`# %,D,D,DF[$\# (/t/G/GIa'b# %,D,D,DF[$\# !((@(@BS T# #*$*B*BDW"X# !((@(@BS T#  #*$*B*BDW"X!#" %,D,D,DF[$\##$ &-T-E-EG]%^%#& $+4+C+CEY#Z'#( "))A)ACU!V)#* $+4+C+CEY#Z+#, '+oo&K&K-#. %)OO$G$G/#0 (/t/G/GIa'b1#2 *1,,.H*3#8 &-T-E-EG]%^9#: &-T-E-EG]%^;#< $+4+C+CEY#Z=#> *1,,.H*?#D (/t/G/GIa'bE#OH 0$	4<<$..DL ,,$$U+++Q 0P , 	)LLA!EF)),,T-B-BCCC$(D!!	)s`   0M9L LKL LL M9L L 	M6A M1M" M1,M91M66M9c                    K   	 | j                   j                          d{    y7 # t        $ r"}t        j                  d|        Y d}~yd}~ww xY ww)zCleanup client resources.NzException during cleanup: )rm   cleanupr   r
   r   )r.   r   s     r/   r   zTavusTransportClient.cleanup  sG     	;,,&&((( 	;LL5aS9::	;s6   A) ') A) 	AA
AAAc                    K   t        j                  d       | j                  j                  |       d{    y7 w)zHandle joined event.zTavusTransportClient joined!N)r
   r;   rn   rW   r.   datas     r/   r   zTavusTransportClient._on_joined  s+     34oo''---s   4><>c                 6   K   t        j                  d       yw)zHandle left event.zTavusTransportClient left!N)r
   r;   r.   s    r/   r   zTavusTransportClient._on_left  s     12s   c                 H   K   t        j                  d| d| d|        yw)zHandle generic callback events.z[Callback] z called with args=z	, kwargs=N)r
   trace)r.   
event_nameargskwargss       r/   r   z(TavusTransportClient._on_handle_callback  s'     {:,.@iPVxXYs    "c                 h   K   | j                   j                  | j                         d{   S 7 w)zjGet the persona name from the API.

        Returns:
            The name of the current persona.
        N)ri   rK   rk   r   s    r/   rK   z%TavusTransportClient.get_persona_name  s)      YY//0@0@AAAAs   )202framec                    K   t        j                  d       | j                  j                  |       d{    | j                  j	                          d{    y7 '7 w)zStart the client and join the room.

        Args:
            frame: The start frame containing initialization parameters.
        z#TavusTransportClient start invoked!N)r
   r;   rm   startjoinr.   r   s     r/   r   zTavusTransportClient.start'  sL      	:;ll  '''ll!!! 	(!s!   4A"A!A"A A" A"c                    K   | j                   j                          d{    | j                  j                  | j                         d{    d| _        y7 97 w)z)Stop the client and end the conversation.N)rm   leaveri   rF   rl   r   s    r/   stopzTavusTransportClient.stop1  sK     ll  """ii(()>)>??? $ 	#?s!   AA,AAAAparticipant_idcallback	frameratevideo_sourcecolor_formatc                 ^   K   | j                   j                  |||||       d{    y7 w)ao  Capture video from a participant.

        Args:
            participant_id: ID of the participant to capture video from.
            callback: Callback function to handle video frames.
            framerate: Desired framerate for video capture.
            video_source: Video source to capture from.
            color_format: Color format for video frames.
        N)rm   capture_participant_video)r.   r   r   r   r   r   s         r/   r   z.TavusTransportClient.capture_participant_video7  s/     " ll44Hi|
 	
 	
   #-+-audio_sourcesample_ratecallback_interval_msc                 ^   K   | j                   j                  |||||       d{    y7 w)a  Capture audio from a participant.

        Args:
            participant_id: ID of the participant to capture audio from.
            callback: Callback function to handle audio data.
            audio_source: Audio source to capture from.
            sample_rate: Desired sample rate for audio capture.
            callback_interval_ms: Interval between audio callbacks in milliseconds.
        N)rm   capture_participant_audio)r.   r   r   r   r   r   s         r/   r   z.TavusTransportClient.capture_participant_audioL  s0     " ll44HlKAU
 	
 	
r   c                 V   K   | j                   j                  |       d{    y7 w)eSend a message to participants.

        Args:
            frame: The message frame to send.
        N)rm   send_messager   s     r/   r   z!TavusTransportClient.send_messagea  s       ll''...   )')c                 .    | j                   j                  S )z`Get the output sample rate.

        Returns:
            The output sample rate in Hz.
        )rm   out_sample_rater   s    r/   r   z$TavusTransportClient.out_sample_ratek  s     ||+++r1   c                 .    | j                   j                  S )z^Get the input sample rate.

        Returns:
            The input sample rate in Hz.
        )rm   in_sample_rater   s    r/   r   z#TavusTransportClient.in_sample_ratet  s     ||***r1   c                 v   K   t        dd| j                  d      }| j                  |       d{    y7 w)z.Send an interrupt message to the conversation.conversationzconversation.interrupt)message_type
event_typer6   )messageN)r   rl   r   )r.   transport_frames     r/   send_interrupt_messagez+TavusTransportClient.send_interrupt_message}  s:     ; .6#'#8#8
 000s   /979c                 t   K   | j                   sy| j                   j                  ||       d{    y7 w)Update subscription settings for participants.

        Args:
            participant_settings: Per-participant subscription settings.
            profile_settings: Global subscription profile settings.
        Nparticipant_settingsprofile_settingsrm   update_subscriptionsr.   r   r   s      r/   r   z)TavusTransportClient.update_subscriptions  s9      ||ll//!5HX 0 
 	
 	
s   .868c                 n   K   | j                   sy| j                   j                  |       d{   S 7 w)zWrite an audio frame to the transport.

        Args:
            frame: The audio frame to write.

        Returns:
            True if the audio frame was written successfully, False otherwise.
        FN)rm   write_audio_framer   s     r/   r   z&TavusTransportClient.write_audio_frame  s-      ||\\33E::::s   ,535destinationc                 p   K   | j                   sy| j                   j                  |       d{    y7 w)zRegister an audio destination for output.

        Args:
            destination: The destination identifier to register.
        Nrm   register_audio_destinationr.   r   s     r/   r   z/TavusTransportClient.register_audio_destination  s*      ||ll55kBBBs   ,646)   cameraRGB)
microphonei>     )r4   NNN)%rL   rM   rN   rO   r\   rP   rV   rQ   rR   r0   rq   r   rr   r   r   r   r   rK   r   r   r   r   intr   r   r   r   r   propertyr   r   r   r   r   r`   r   r   rT   r1   r/   rb   rb      s    *m +  	
 "    && 
B,3 ,6)!4 6)p;.
3ZB B" "% $!

 
 	

 
 
2 ) $&

 
 	

 
 "
*/03TT/ , , , + + +	1
;-@ ;T ;	CC 	Cr1   rb   c                        e Zd ZdZdedef fdZdef fdZ fdZ	de
f fd	Zdef fd
Zdef fdZd ZdededefdZ xZS )TavusInputTransportzInput transport for receiving audio and events from Tavus conversations.

    Handles incoming audio streams from participants and manages audio capture
    from the Daily room connected to the Tavus conversation.
    clientrd   c                 P    t        |   |fi | || _        || _        d| _        y)zInitialize the Tavus input transport.

        Args:
            client: The Tavus transport client instance.
            params: Transport configuration parameters.
            **kwargs: Additional arguments passed to parent class.
        FN)superr0   rm   ro   _initializedr.   r   rd   r   	__class__s       r/   r0   zTavusInputTransport.__init__  s-     	*6*!r1   rr   c                    K   t         |   |       d{    | j                  j                  |       d{    y7 (7 w)znSetup the input transport.

        Args:
            setup: The frame processor setup configuration.
        Nr   rr   rm   r.   rr   r   s     r/   rr   zTavusInputTransport.setup  <      gmE"""ll  ''' 	#'   A?"AAAAc                    K   t         |           d{    | j                  j                          d{    y7 '7 w)z"Cleanup input transport resources.Nr   r   rm   r.   r   s    r/   r   zTavusInputTransport.cleanup  6     goll""$$$ 	 $   A=!A?AAr   c                    K   t         |   |       d{    | j                  ryd| _        | j                  j                  |       d{    | j	                  |       d{    y7 U7  7 	w)z{Start the input transport.

        Args:
            frame: The start frame containing initialization parameters.
        NT)r   r   r   rm   set_transport_readyr.   r   r   s     r/   r   zTavusInputTransport.start  sj      gmE""" ll  '''&&u--- 	# 	(-s3   A2A,6A2A.A2&A0'A2.A20A2c                    K   t         |   |       d{    | j                  j                          d{    y7 '7 w)zpStop the input transport.

        Args:
            frame: The end frame signaling transport shutdown.
        Nr   r   rm   r   s     r/   r   zTavusInputTransport.stop  :      gl5!!!ll!!! 	"!   A>!AA A Ac                    K   t         |   |       d{    | j                  j                          d{    y7 '7 w)zyCancel the input transport.

        Args:
            frame: The cancel frame signaling immediate cancellation.
        Nr   cancelrm   r   r   s     r/   r   zTavusInputTransport.cancel  :      gnU###ll!!! 	$!r   c                   K   | j                   j                  rct        j                  d|d           | j                  j                  |d   | j                  | j                  j                         d{    yy7 w)zStart capturing audio from a participant.

        Args:
            participant: The participant to capture audio from.
        z;TavusTransportClient start capturing audio for participant id)r   r   r   N)ro   r]   r
   inform   r   _on_participant_audio_datar   r.   participants     r/   start_capturing_audioz)TavusInputTransport.start_capturing_audio  s}      <<((KKMkZ^N_M`a ,,88*4088 LL77 9   	 )s   A4A?6A=7A?r   audior   c                    K   t        |j                  |j                  |j                        }||_        | j                  |       d{    y7 w)z'Handle received participant audio data.)r  r   num_channelsN)r   audio_framesr   r  transport_sourcepush_audio_frame)r.   r   r  r   r   s        r/   r   z.TavusInputTransport._on_participant_audio_data	  sK      #$$))++

 ".##E***s   AA
AA)rL   rM   rN   rO   rb   r   r0   r   rr   r   r   r   r   r   r   r   r  rP   r	   r   __classcell__r   s   @r/   r   r     sw    "$"  "&(!4 (%
. . " ""+ " 
+!
+*3
+CF
+r1   r   c                        e Zd ZdZdedef fdZdef fdZ fdZ	de
f fd	Zdef fd
Zdef fdZdeez  fdZdedef fdZd ZdedefdZdefdZ xZS )TavusOutputTransportzOutput transport for sending audio and events to Tavus conversations.

    Handles outgoing audio streams to participants and manages the custom
    audio track expected by the Tavus platform.
    r   rd   c                 ^    t        |   |fi | || _        || _        d| _        d| _        y)zInitialize the Tavus output transport.

        Args:
            client: The Tavus transport client instance.
            params: Transport configuration parameters.
            **kwargs: Additional arguments passed to parent class.
        FstreamN)r   r0   rm   ro   r   _transport_destinationr   s       r/   r0   zTavusOutputTransport.__init__  s7     	*6* "5=#r1   rr   c                    K   t         |   |       d{    | j                  j                  |       d{    y7 (7 w)zoSetup the output transport.

        Args:
            setup: The frame processor setup configuration.
        Nr   r   s     r/   rr   zTavusOutputTransport.setup3  r   r   c                    K   t         |           d{    | j                  j                          d{    y7 '7 w)z#Cleanup output transport resources.Nr   r   s    r/   r   zTavusOutputTransport.cleanup<  r   r   r   c                 ^  K   t         |   |       d{    | j                  ryd| _        | j                  j                  |       d{    | j                  r-| j                  j                  | j                         d{    | j                  |       d{    y7 7 Y7 "7 w)z|Start the output transport.

        Args:
            frame: The start frame containing initialization parameters.
        NT)r   r   r   rm   r  r   r   r   s     r/   r   zTavusOutputTransport.startA  s      gmE""" ll  '''&&,,99$:U:UVVV&&u--- 	# 	( W-sE   B-B%6B-B'8B-B)B-B+ B-'B-)B-+B-c                    K   t         |   |       d{    | j                  j                          d{    y7 '7 w)zqStop the output transport.

        Args:
            frame: The end frame signaling transport shutdown.
        Nr   r   s     r/   r   zTavusOutputTransport.stopU  r   r   c                    K   t         |   |       d{    | j                  j                          d{    y7 '7 w)zzCancel the output transport.

        Args:
            frame: The cancel frame signaling immediate cancellation.
        Nr   r   s     r/   r   zTavusOutputTransport.cancel^  r   r   c                    K   t        j                  d|        | j                  j                  |       d{    y7 w)r   z%TavusOutputTransport sending message N)r
   r   rm   r   r   s     r/   r   z!TavusOutputTransport.send_messageg  s4      	;E7CDll''...s   7A?A	directionc                    K   t         |   ||       d{    t        |t              r| j	                          d{    yy7 .7 w)zProcess frames and handle interruptions.

        Args:
            frame: The frame to process.
            direction: The direction of frame flow in the pipeline.
        N)r   process_frame
isinstancer   _handle_interruptions)r.   r   r  r   s      r/   r  z"TavusOutputTransport.process_framer  sI      g#E9555e./,,... 0 	6.s    A
A'A
A A
A
c                 T   K   | j                   j                          d{    y7 w)z8Handle interruption events by sending interrupt message.N)rm   r   r   s    r/   r  z*TavusOutputTransport._handle_interruptions}  s     ll11333s   (&(r4   c                 v   K   | j                   |_        | j                  j                  |       d{   S 7 w)zWrite an audio frame to the Tavus transport.

        Args:
            frame: The audio frame to write.

        Returns:
            True if the audio frame was written successfully, False otherwise.
        N)r  transport_destinationrm   r   r   s     r/   r   z&TavusOutputTransport.write_audio_frame  s1      '+&A&A#\\33E::::s   0979r   c                 V   K   | j                   j                  |       d{    y7 w)zwRegister an audio destination.

        Args:
            destination: The destination identifier to register.
        Nr   r   s     r/   r   z/TavusOutputTransport.register_audio_destination  s       ll55kBBBr   )rL   rM   rN   rO   rb   r   r0   r   rr   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r`   r   rP   r   r  r	  s   @r/   r  r    s    >$>  >,(!4 (%
. .(" ""+ "	/03TT	/	/ 	/> 	/4;-@ ;T ;CC Cr1   r  c                        e Zd ZdZd e       ddfdedej                  dededed	ed
ee   dee   f fdZ	d Z
d Zd ZddZdefdZdefdZdefdZdefdZ xZS )TavusTransporta  Transport implementation for Tavus video calls.

    When used, the Pipecat bot joins the same virtual room as the Tavus Avatar and the user.
    This is achieved by using `TavusTransportClient`, which initiates the conversation via
    `TavusApi` and obtains a room URL that all participants connect to.

    Event handlers available:

    - on_connected(transport, data): Bot connected to the room
    - on_client_connected(transport, participant): Participant connected to the session
    - on_client_disconnected(transport, participant): Participant disconnected from the session

    Example::

        @transport.event_handler("on_client_connected")
        async def on_client_connected(transport, participant):
            ...
    rc   Nre   r%   r$   r2   r3   rd   
input_nameoutput_namec	           	      L   t         
|   ||       || _        t        | j                  | j
                  | j                        }	t        d|	|||||      | _        d| _	        d| _
        d| _        | j                  d       | j                  d       | j                  d       y)	aq  Initialize the Tavus transport.

        Args:
            bot_name: The name of the Pipecat bot.
            session: aiohttp session used for async HTTP requests.
            api_key: Tavus API key for authentication.
            replica_id: ID of the replica model used for voice generation.
            persona_id: ID of the Tavus persona. Defaults to "pipecat-stream"
                to use the Pipecat TTS voice.
            params: Optional Tavus-specific configuration parameters.
            input_name: Optional name for the input transport.
            output_name: Optional name for the output transport.
        )r   r!  )rW   rX   rY   r   )re   rf   r$   r2   r3   r%   rd   Non_connectedrz   r{   )r   r0   ro   rV   r   _on_participant_joined_on_participant_leftrb   rm   _input_output_tavus_participant_id_register_event_handler)r.   re   r%   r$   r2   r3   rd   r   r!  rf   r   s             r/   r0   zTavusTransport.__init__  s    0 	JKH"oo"&"="= $ 9 9
	
 ,!!
 6:7;%)" 	$$^4$$%:;$$%=>r1   c                    K   | j                  d|       d{    | j                  r,| j                  j                  t                      d{    yy7 =7 w)zHandle bot joined room event.r#  N)_call_event_handlerr&  
push_framer   r   s     r/   r   zTavusTransport._on_joined  sM     &&~t<<<;;++(():)<===  	==!   AA6AAAAc                    K   | j                   j                          d{   }|j                  di       j                  dd      |k7  r| j                  |       d{    yy7 D7 w)zHandle participant left events.Nr   userName )rm   rK   rJ   _on_client_disconnected)r.   r   reasonrH   s       r/   r%  z#TavusTransport._on_participant_left  s^     !\\::<<??62&**:r:lJ..{;;; K =;s!   A)A%=A)A'A)'A)c                   K   | j                   j                          d{   }|j                  di       j                  dd      |k(  r|d   | _        y| j	                  |       d{    | j                  rMt        j                  d| j                   d       | j                  | j                  dd	d
iii       d{    | j                  r$| j                  j                  |       d{    yy7 7 7 97 w)z!Handle participant joined events.Nr   r/  r0  r   z	Ignoring z's microphonemediar   unsubscribed)r   )
rm   rK   rJ   r(  _on_client_connectedr
   r;   r   r&  r  )r.   r   rH   s      r/   r$  z%TavusTransport._on_participant_joined  s      "\\::<< ??62&**:r:lJ)4T):D&++K888))y)C)C(DMRS//22#lN%C5* 0    {{kk77DDD ! = 9 EsG   D C8AD )C:*AD C<.D 1C>2D :D <D >D c                 Z   K   | j                   j                  ||       d{    y7 w)r   r   Nr   r   s      r/   r   z#TavusTransport.update_subscriptions   s/      ll//!5- 0 
 	
 	
s   !+)+r4   c                 ~    | j                   s&t        | j                  | j                        | _         | j                   S )zGet the input transport for receiving media and events.

        Returns:
            The Tavus input transport instance.
        r   rd   )r&  r   rm   ro   r   s    r/   inputzTavusTransport.input  s+     {{-T\\$,,WDK{{r1   c                 ~    | j                   s&t        | j                  | j                        | _         | j                   S )zGet the output transport for sending media and events.

        Returns:
            The Tavus output transport instance.
        r9  )r'  r  rm   ro   r   s    r/   outputzTavusTransport.output  s+     ||/t||DLLYDL||r1   r   c                    K   | j                  d|       d{    | j                  r,| j                  j                  t                      d{    yy7 =7 w)zHandle client connected events.rz   N)r+  r&  r,  r   r   s     r/   r6  z#TavusTransport._on_client_connected   sO     &&'<kJJJ;;++(()=)?@@@  	K@r-  c                 D   K   | j                  d|       d{    y7 w)z"Handle client disconnected events.r{   N)r+  r   s     r/   r1  z&TavusTransport._on_client_disconnected&  s     &&'?MMMs     r   )rL   rM   rN   rO   r\   rP   rQ   rR   r   r0   r   r%  r$  r   r   r:  r<  r   r6  r1  r  r	  s   @r/   r  r    s    2 +)m$(%)1?1? &&1? 	1?
 1? 1? 1? SM1? c]1?f><E,

~  Ac AN Nr1   r  )3rO   r+   	functoolsr   typingr   r   r   r   r   rQ   daily.dailyr	   logurur
   pydanticr   pipecat.frames.framesr   r   r   r   r   r   r   r   r   r   r   "pipecat.processors.frame_processorr   r   r   pipecat.transports.base_inputr   pipecat.transports.base_outputr   !pipecat.transports.base_transportr   r   "pipecat.transports.daily.transportr   r   r    r"   rV   r\   rb   r   r  r  rT   r1   r/   <module>rJ     s    
  > >  !      c b < > L S, S,lMY M)+ )KC KC\d+, d+N~C. ~CBQN] QNr1   