
    qit                        d 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* ddl+m,Z,  G d de      Z- G d de      Z. G d de)      Z/ G d d      Z0 G d de!      Z1 G d de#      Z2 G d de%      Z3y)zLemonSlice transport for Pipecat.

This module adds LemonSlice avatars to Daily rooms, enabling
real-time voice conversations with synchronized avatars.
    )partial)Any	AwaitableCallableMappingOptionalN)	AudioData)logger)	BaseModel)BotStartedSpeakingFrameBotStoppedSpeakingFrameCancelFrameEndFrameFrameInputAudioRawFrameInterruptionFrameOutputAudioRawFrameOutputTransportMessageFrame!OutputTransportMessageUrgentFrame
StartFrame)FrameDirectionFrameProcessorFrameProcessorSetup)BaseInputTransport)BaseOutputTransport)BaseTransportTransportParams)DailyCallbacksDailyParamsDailyTransportClient)LemonSliceApic                       e Zd ZU dZdZee   ed<   dZee   ed<   dZ	ee   ed<   dZ
ee   ed<   dZee   ed<   dZee   ed<   dZee   ed	<   y)
LemonSliceNewSessionRequesta  Request model for creating a new LemonSlice session.

    Parameters:
        agent_image_url: URL to an agent image. Provide either agent_id or agent_image_url.
        agent_id: ID of a LemonSlice agent. Provide either agent_id or agent_image_url.
        agent_prompt: A high-level system prompt that subtly influences the avatar's movements,
            expressions, and emotional demeanor.
        idle_timeout: Idle timeout in seconds.
        daily_room_url: Daily room URL to use for the session.
        daily_token: Daily token for authenticating with the room.
        lemonslice_properties: Additional properties to pass to the session.
    Nagent_image_urlagent_idagent_promptidle_timeoutdaily_room_urldaily_tokenlemonslice_properties)__name__
__module____qualname____doc__r$   r   str__annotations__r%   r&   r'   intr(   r)   r*   dict     Y/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/transports/lemonslice/transport.pyr#   r#   .   sl     &*OXc])"Hhsm""&L(3-&"&L(3-&$(NHSM(!%K#%,08D>0r4   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   eged   f   e	d<   y)LemonSliceCallbackszCallback handlers for LemonSlice events.

    Parameters:
        on_participant_joined: Called when a participant joins the conversation.
        on_participant_left: Called when a participant leaves the conversation.
    Non_participant_joinedon_participant_left)
r+   r,   r-   r.   r   r   r/   r   r   r0   r3   r4   r5   r7   r7   E   sK     $WS#X%6$74$HII!738#4c":IdO"KLLr4   r7   c                   <    e Zd ZU dZdZeed<   dZeed<   dZeed<   y)LemonSliceParamsa-  Configuration parameters for the LemonSlice 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)	r+   r,   r-   r.   r<   boolr0   r=   r>   r3   r4   r5   r;   r;   Q   s*     "d!"t"#(D(r4   r;   c                   p   e Zd ZdZ e       dddedededede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-d&Z#d.d'Z$de%d
e&fd(Z'd)efd*Z(y)/LemonSliceTransportClienta  Transport client that integrates Pipecat with the LemonSlice platform.

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

    This client uses `LemonSliceApi` to interact with the LemonSlice backend. LemonSlice either provides
    a room URL where the avatar is already present, or adds the LemonSlice avatar to a Daily room
    the user supplies.
    N)paramssession_requestbot_namerB   	callbacksapi_keyrC   sessionreturnc                    || _         t        ||      | _        |xs
 t               | _        d| _        d| _        d| _        || _        || _	        y)a  Initialize the LemonSlice transport client.

        Args:
            bot_name: The name of the Pipecat bot instance.
            params: Optional parameters for LemonSlice operation.
            callbacks: Callback handlers for LemonSlice-related events.
            api_key: API key for authenticating with LemonSlice API.
            session_request: Optional session creation parameters. If not provided, a default
                agent will be used.
            session: The aiohttp session for making async HTTP requests.
        N)
	_bot_namer!   _apir#   _session_request_session_id_control_url_daily_transport_client
_callbacks_params)selfrD   rB   rE   rF   rC   rG   s          r5   __init__z"LemonSliceTransportClient.__init__j   sP    * "!'73	 / P3N3P*.+/GK$#r4   c           	        K   | j                   j                  | j                  j                  | j                  j                  | j                  j
                  | j                  j                  | j                  j                  | j                  j                  | j                  j                         d{   }|d   | _
        |d   | _        |d   S 7 w)z4Initialize the conversation and return the room URL.)r$   r%   r&   r'   r(   r)   
propertiesN
session_idcontrol_urlroom_url)rK   create_sessionrL   r$   r%   r&   r'   r(   r)   r*   rM   rN   )rR   responses     r5   _initializez%LemonSliceTransportClient._initialize   s     11 11AA**33..;;..;;00??--99,,BB 2 
 
 $L1$]3
##
s   B2C4C5Csetupc           	      B  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| j                  | j                  |d      | _        | j                  j!                  |       d{    y7 7 # t"        $ r}}t        j$                  d |        | j                   rE| j&                  r9| j(                  j+                  | j                   | j&                         d{  7   d| _         d| _         d}~ww xY ww)"zSetup the client and initialize the conversation.

        Args:
            setup: The frame processor setup configuration.
        NzSession ID already defined: on_active_speaker_changed	on_joined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_warningr8   r9   on_participant_updatedon_transcription_messageon_recording_startedon_recording_stoppedon_recording_erroron_transcription_stoppedon_transcription_errorLemonSlicePipecatz+Failed to setup LemonSliceTransportClient: r3   )rM   r
   debugr[   r   r   _on_handle_callback
_on_joined_on_leftrP   r8   r9   r    rJ   rQ   rO   r\   	ExceptionerrorrN   rK   end_session)rR   r\   rX   daily_callbackses        r5   r\   zLemonSliceTransportClient.setup   s     'LL78H8H7IJK0	!--//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 ,@$oOb,D( ..44U;;;Q 0P < 	LLFqcJKD$5$5ii++D,<,<d>O>OPPP#D $D	sZ   0NL LKL LL NL L 	NA#NNNNNc                    K   	 | j                   r#| j                   j                          d{    y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: )rO   cleanupr}   r
   r~   )rR   r   s     r5   r   z!LemonSliceTransportClient.cleanup   sZ     	;++22::<<< ,< 	;LL5aS9::	;s6   A$)6 46 A$6 	A!AA$A!!A$c                 6   K   t        j                  d       yw)zHandle joined event.z!LemonSliceTransportClient joined!Nr
   ry   )rR   datas     r5   r{   z$LemonSliceTransportClient._on_joined   s     89   c                 6   K   t        j                  d       yw)zHandle left event.zLemonSliceTransportClient left!Nr   rR   s    r5   r|   z"LemonSliceTransportClient._on_left   s     67r   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)rR   
event_nameargskwargss       r5   rz   z-LemonSliceTransportClient._on_handle_callback   s'     {:,.@iPVxXYs    "c                    K   yw)zzGet the name of the LemonSlice participant.

        Returns:
            The name of the LemonSlice participant.
        
LemonSlicer3   r   s    r5   get_bot_namez&LemonSliceTransportClient.get_bot_name   s      s   framec                    K   | 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.
        N)rO   startjoinrR   r   s     r5   r   zLemonSliceTransportClient.start   sC      **00777**//111 	81s!   AA	!AAAAc                   K   | j                   j                          d{    | j                  rD| j                  r8| j                  j                  | j                  | j                         d{    d| _        d| _        y7 c7 w)z)Stop the client and end the conversation.N)rO   leaverM   rN   rK   r   r   s    r5   stopzLemonSliceTransportClient.stop   sn     **00222 1 1))''(8(8$:K:KLLL 	 	3Ls"   BBAB0B1BB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)rO   capture_participant_video)rR   r   r   r   r   r   s         r5   r   z3LemonSliceTransportClient.capture_participant_video   s1     " **DD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)rO   capture_participant_audio)rR   r   r   r   r   r   s         r5   r   z3LemonSliceTransportClient.capture_participant_audio  s2     " **DDHlKAU
 	
 	
r   c                 V   K   | j                   j                  |       d{    y7 w)eSend a message to participants.

        Args:
            frame: The message frame to send.
        N)rO   send_messager   s     r5   r   z&LemonSliceTransportClient.send_message)  s"      **77>>>   )')c                 .    | j                   j                  S )z`Get the output sample rate.

        Returns:
            The output sample rate in Hz.
        )rO   out_sample_rater   s    r5   r   z)LemonSliceTransportClient.out_sample_rate3  s     ++;;;r4   c                 .    | j                   j                  S )z^Get the input sample rate.

        Returns:
            The input sample rate in Hz.
        )rO   in_sample_rater   s    r5   r   z(LemonSliceTransportClient.in_sample_rate<  s     ++:::r4   c                    K   t        j                  d       t        d| j                  d      }| j	                  |       d{    y7 w)z4Send an interrupt message to the LemonSlice session.zSending interrupt message	interrupteventrV   messageN)r
   ry   r   rM   r   rR   transport_frames     r5   send_interrupt_messagez0LemonSliceTransportClient.send_interrupt_messageE  sD     01;$"..
 000   AAAAc                    K   t        j                  d       t        d| j                  d      }| j	                  |       d{    y7 w)z:Send a response_started message to the LemonSlice session.z Sending response_started messageresponse_startedr   r   Nr
   r   r   rM   r   r   s     r5   send_response_started_messagez7LemonSliceTransportClient.send_response_started_messageP  sD     78;+"..
 000r   c                    K   t        j                  d       t        d| j                  d      }| j	                  |       d{    y7 w)z;Send a response_finished message to the LemonSlice session.z!Sending response_finished messageresponse_finishedr   r   Nr   r   s     r5   send_response_finished_messagez8LemonSliceTransportClient.send_response_finished_message[  sD     89;,"..
 000r   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)rO   update_subscriptionsrR   r   r   s      r5   r   z.LemonSliceTransportClient.update_subscriptionsf  s>      ++**??!5HX @ 
 	
 	
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)rO   write_audio_framer   s     r5   r   z+LemonSliceTransportClient.write_audio_framet  s1      ++11CCEJJJJs   ,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)rO   register_audio_destinationrR   r   s     r5   r   z4LemonSliceTransportClient.register_audio_destination  s.      ++**EEkRRRs   ,646)   cameraRGB)
microphonei>     )rH   NNN))r+   r,   r-   r.   r;   r/   r7   r   r#   aiohttpClientSessionrS   r[   r   r\   r   r{   r|   rz   r   r   r   r   r   r1   r   r   r   r   r   propertyr   r   r   r   r   r   r   r?   r   r   r3   r4   r5   rA   rA   _   s    $4#5 BF  !	
 '  ""=> && 
<$3 $9!4 9v;:8ZC 2 2! $!

 
 	

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

 
 "
*?03TT? < < < ; ; ;	1	1	1
K-@ KT K	SC 	Sr4   rA   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 )LemonSliceInputTransportzInput transport for receiving audio and events from LemonSlice.

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

        Args:
            client: The LemonSlice transport client instance.
            params: Transport configuration parameters.
            **kwargs: Additional arguments passed to parent class.
        FN)superrS   _clientrQ   _initializedrR   r   rB   r   	__class__s       r5   rS   z!LemonSliceInputTransport.__init__  s-     	*6*!r4   r\   c                    K   t         |   |       d{    | j                  j                  |       d{    y7 (7 w)znSetup the input transport.

        Args:
            setup: The frame processor setup configuration.
        Nr   r\   r   rR   r\   r   s     r5   r\   zLemonSliceInputTransport.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   r   rR   r   s    r5   r   z LemonSliceInputTransport.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   r   set_transport_readyrR   r   r   s     r5   r   zLemonSliceInputTransport.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   r   r   s     r5   r   zLemonSliceInputTransport.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   cancelr   r   r   s     r5   r   zLemonSliceInputTransport.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@LemonSliceTransportClient start capturing audio for participant id)r   r   r   N)rQ   r<   r
   ry   r   r   _on_participant_audio_datar   rR   participants     r5   start_capturing_audioz.LemonSliceInputTransport.start_capturing_audio  s~      <<((LLRS^_cSdRef ,,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)a  Handle received participant audio data.

        Args:
            participant_id: ID of the participant who sent the audio.
            audio: The audio data from the participant.
            audio_source: The source of the audio (e.g., microphone).
        )r   r   num_channelsN)r   audio_framesr   r   transport_sourcepush_audio_frame)rR   r   r   r   r   s        r5   r   z3LemonSliceInputTransport._on_participant_audio_data  sK      #$$))++

 ".##E***s   AA
AA)r+   r,   r-   r.   rA   r   rS   r   r\   r   r   r   r   r   r   r   r   r/   r	   r   __classcell__r   s   @r5   r   r     sw    ")"  "&(!4 (%
. . " ""+ " +!+*3+CF+r4   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ej(                  fdedef fdZdedef fdZd Zd Zd ZdedefdZdefdZ xZ S )LemonSliceOutputTransportzOutput transport for sending audio and events to LemonSlice.

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

        Args:
            client: The LemonSlice transport client instance.
            params: Transport configuration parameters.
            **kwargs: Additional arguments passed to parent class.
        FstreamN)r   rS   r   rQ   r   _transport_destinationr   s       r5   rS   z"LemonSliceOutputTransport.__init__  s7     	*6* "5=#r4   r\   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     r5   r\   zLemonSliceOutputTransport.setup  r   r   c                    K   t         |           d{    | j                  j                          d{    y7 '7 w)z#Cleanup output transport resources.Nr   r   s    r5   r   z!LemonSliceOutputTransport.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   r   r  r   r   r   s     r5   r   zLemonSliceOutputTransport.start&  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     r5   r   zLemonSliceOutputTransport.stop:  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     r5   r   z LemonSliceOutputTransport.cancelC  r   r   c                    K   t        j                  d|        | j                  j                  |       d{    y7 w)r   z$LemonSliceTransport sending message N)r
   r   r   r   r   s     r5   r   z&LemonSliceOutputTransport.send_messageL  s4      	;E7CDll''...s   7A?A	directionc                   K   |t         j                  k(  rPt        |t              r| j	                          d{    t        |t
              r| j                          d{    t        | !  ||       d{    y7 E7 7 	w)zPush a frame to the next processor in the pipeline.

        Args:
            frame: The frame to push.
            direction: The direction to push the frame.
        N)	r   
DOWNSTREAM
isinstancer   _handle_response_startedr   _handle_response_finishedr   
push_framerR   r   r  r   s      r5   r  z$LemonSliceOutputTransport.push_frameW  ss      111%!8933555%!8944666g 	222 662s3   7BB 'B"B#B:B;BBBc                    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_framer  r   _handle_interruptionsr  s      r5   r  z'LemonSliceOutputTransport.process_frameg  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)r   r   r   s    r5   r  z/LemonSliceOutputTransport._handle_interruptionsr  s     ll11333   (&(c                 T   K   | j                   j                          d{    y7 w)zGHandle bot started speaking events by sending response_started message.N)r   r   r   s    r5   r  z2LemonSliceOutputTransport._handle_response_startedv  s     ll88:::r  c                 T   K   | j                   j                          d{    y7 w)zHHandle tts response stopped events by sending response_finished message.N)r   r   r   s    r5   r  z3LemonSliceOutputTransport._handle_response_finishedz  s     ll99;;;r  rH   c                 v   K   | j                   |_        | j                  j                  |       d{   S 7 w)zWrite an audio frame to the LemonSlice transport.

        Args:
            frame: The audio frame to write.

        Returns:
            True if the audio frame was written successfully, False otherwise.
        N)r  transport_destinationr   r   r   s     r5   r   z+LemonSliceOutputTransport.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.
        N)r   r   r   s     r5   r   z4LemonSliceOutputTransport.register_audio_destination  s       ll55kBBBr   )!r+   r,   r-   r.   rA   r   rS   r   r\   r   r   r   r   r   r   r   r   r   r   r   r  r   r  r  r  r  r  r   r?   r   r/   r   r   r  s   @r5   r  r    s    >)>  >,(!4 (%
. .(" ""+ "	/03TT	/ JXIbIb 3e 3 3 	/ 	/> 	/4;<;-@ ;T ;CC Cr4   r  c                        e Zd ZdZd e       ddfdedej                  dedee	   dedee   d	ee   f f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 )LemonSliceTransporta  Transport implementation to add a LemonSlice avatar to Daily calls.

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

    Event handlers available:

    - 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):
            ...
    NrD   rG   rF   rC   rB   
input_nameoutput_namec                    t         	|   ||       || _        t        | j                  | j
                        }t        ||||||      | _        d| _        d| _	        d| _
        | j                  d       | j                  d       y)a;  Initialize the LemonSlice transport.

        Args:
            bot_name: The name of the Pipecat bot.
            session: aiohttp session used for async HTTP requests.
            api_key: LemonSlice API key for authentication.
            session_request: Optional session creation parameters. If not provided, a default
                agent will be used.
            params: Optional LemonSlice-specific configuration parameters.
            input_name: Optional name for the input transport.
            output_name: Optional name for the output transport.
        )r!  r"  )r8   r9   )rD   rE   rF   rC   rG   rB   Nre   rf   )r   rS   rQ   r7   _on_participant_joined_on_participant_leftrA   r   _input_output_lemonslice_participant_id_register_event_handler)
rR   rD   rG   rF   rC   rB   r!  r"  rE   r   s
            r5   rS   zLemonSliceTransport.__init__  s    , 	JKH'"&"="= $ 9 9
	 1+
 ;?<@*.' 	$$%:;$$%=>r4   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.NinfouserName )r   r   get_on_client_disconnected)rR   r   reasonls_bot_names       r5   r%  z(LemonSliceTransport._on_participant_left  s^      LL5577??62&**:r:kI..{;;; J 8;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,  r-  r   z	Ignoring z's microphonemediar   unsubscribed)r   )
r   r   r.  r(  _on_client_connectedr
   ry   r   r&  r   )rR   r   r1  s      r5   r$  z*LemonSliceTransport._on_participant_joined  s      LL5577 ??62&**:r:kI.9$.?D+++K888..y)H)H(IWX//77#lN%C:* 0    {{kk77DDD ! 8 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   N)r   r   r   s      r5   r   z(LemonSliceTransport.update_subscriptions  s/      ll//!5- 0 
 	
 	
s   !+)+rH   c                 ~    | j                   s&t        | j                  | j                        | _         | j                   S )zGet the input transport for receiving media and events.

        Returns:
            The LemonSlice input transport instance.
        r   rB   )r&  r   r   rQ   r   s    r5   inputzLemonSliceTransport.input  s+     {{2$,,t||\DK{{r4   c                 ~    | j                   s&t        | j                  | j                        | _         | j                   S )zGet the output transport for sending media and events.

        Returns:
            The LemonSlice output transport instance.
        r8  )r'  r  r   rQ   r   s    r5   outputzLemonSliceTransport.output  s.     ||4DLLQUQ]Q]^DL||r4   r   c                 D   K   | j                  d|       d{    y7 w)zHandle client connected events.re   N_call_event_handlerr   s     r5   r5  z(LemonSliceTransport._on_client_connected  s     &&'<kJJJ     c                 D   K   | j                  d|       d{    y7 w)z"Handle client disconnected events.rf   Nr=  r   s     r5   r/  z+LemonSliceTransport._on_client_disconnected  s     &&'?MMMr?  r   )r+   r,   r-   r.   r;   r/   r   r   r   r#   rS   r%  r$  r   r   r9  r;  r   r5  r/  r   r  s   @r5   r   r     s    . BF#3#5$(%),?,? &&,? 	,?
 ""=>,? !,? SM,? c],?\<E*

~  Kc KN Nr4   r   )4r.   	functoolsr   typingr   r   r   r   r   r   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    !pipecat.transports.lemonslice.apir!   r#   r7   r;   rA   r   r  r   r3   r4   r5   <module>rM     s     > >  !      c b < > L 
 <1) 1.	M) 	M){ )lS lS^	j+1 j+ZVC 3 VCrBN- BNr4   