
    qio                        d Z ddlZddlZddlZddlZddlZddlmZ ddl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mZmZ ddlmZ dd	lmZmZ dd
lmZmZ ddlmZ ddl m!Z! ddl"m#Z# 	 ddl$m%Z% ddl&m'Z' ddl(m)Z* ddl+m,Z, dZ1 G d de      Z2 G d de      Z3 G d d      Z4y# e-$ r7Z. ej^                  de.         ej^                  d        e0de.       dZ.[.ww xY w)a  HeyGen implementation for Pipecat.

This module provides integration with the HeyGen platform for creating conversational
AI applications with avatars. It manages conversation sessions and provides real-time
audio/video streaming capabilities through the HeyGen API.
    N)Enum)	AwaitableCallableOptionalUnion)logger)	BaseModel)AudioRawFrameImageRawFrame
StartFrame)FrameProcessorSetup)	HeyGenApiNewSessionRequest)LiveAvatarApiLiveAvatarNewSessionRequest)StandardSessionResponse)TransportParams)BaseTaskManager)rtc)VideoBufferType)connect)ConnectionClosedOKzException: zEIn order to use HeyGen, you need to `pip install pipecat-ai[heygen]`.zMissing module: i]  c                       e Zd ZdZdZdZy)ServiceTypezEnum for HeyGen service types.INTERACTIVE_AVATARLIVE_AVATARN)__name__
__module____qualname____doc__r   r        P/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/services/heygen/client.pyr   r   6   s    (-Kr"   r   c                   d    e Zd ZU dZeg ed   f   ed<   eeged   f   ed<   eeged   f   ed<   y)HeyGenCallbacksa  Callback handlers for HeyGen events.

    Parameters:
        on_connected: Called when the bot connects to the LiveKit room.
        on_participant_connected: Called when a participant connects.
        on_participant_disconnected: Called when a participant disconnects.
    Non_connectedon_participant_connectedon_participant_disconnected)r   r   r   r    r   r   __annotations__strr!   r"   r#   r%   r%   =   sI     2y.//&uio'=>>!)3%4*@!AAr"   r%   c                      e Zd ZdZdddddedej                  dedee	e
ef      d	ee   d
ededdfdZd ZdeddfdZd4dZdededdfdZd4dZd Zd ZdeddfdZd4dZdeddfdZdeddfdZd4dZd4d Z d4d!Z!e"defd"       Z#e"defd#       Z$d$e%deddfd%Z&d& Z'd' Z(deddfd(Z)d)eddfd*Z*d)eddfd+Z+d,e,jZ                  fd-Z.d,e,j^                  fd.Z0d/ Z1d0 Z2d1 Z3d2e4jj                  fd3Z6y)5HeyGenClienta  A client for interacting with HeyGen's Interactive Avatar Realtime API.

    This client manages both WebSocket and LiveKit connections for real-time avatar streaming,
    handling bi-directional audio/video communication and avatar control. It implements the API defined in
    https://docs.heygen.com/docs/interactive-avatar-realtime-api

    The client manages the following connections:
    1. WebSocket connection for avatar control and audio streaming
    2. LiveKit connection for receiving avatar video and audio

    Attributes:
        HEY_GEN_SAMPLE_RATE (int): The required sample rate for HeyGen's audio processing (24000 Hz)
    NF)session_requestservice_typeconnect_as_userapi_keysessionparamsr-   r.   	callbacksr/   returnc                6   ||nt         j                  | _        |w|u|t         j                  k(  r(t	        |t
              st        j                  d       d}n:|t         j                  k(  r't	        |t              st        j                  d       d}|7| j                  t         j                  k(  rt        dd      }nt        d      }| j                  t         j                  k(  rt        ||	      | _
        nt        ||	      | _
        d| _        d| _        d| _        || _        d
| _        d
| _        d| _        || _        || _        d| _        d| _        d| _        d| _        d| _        d| _        d
| _        d
| _        d| _        d| _        || _        y)a  Initialize the HeyGen client.

        Args:
            api_key: HeyGen API key for authentication
            session: HTTP client session for API requests
            params: Transport configuration parameters
            session_request: Configuration for the HeyGen session (optional)
            service_type: Type of service to use
            callbacks: Callback handlers for HeyGen events
            connect_as_user: Whether to connect using the user token or not (default: False)
        NzeService type is LIVE_AVATAR but session_request is not SessionTokenRequest. Ignoring session_request.zjService type is INTERACTIVE_AVATAR but session_request is not NewSessionRequest. Ignoring session_request.Shawn_Therapist_publicv2)	avatar_idversionz$1c690fe7-23e0-49f9-bfba-14344450285b)r8   )r1   r   F        ) r   r   _service_typer   
isinstancer   r   warningr   r   _apir   _heyGen_session
_websocket_task_manager_params_in_sample_rate_out_sample_rate
_connected_session_request
_callbacks_event_queue_event_task_video_task_audio_task_video_frame_callback_audio_frame_callback_send_interval_next_send_time_audio_seconds_sent_transport_ready_connect_as_user)selfr0   r1   r2   r-   r.   r3   r/   s           r#   __init__zHeyGenClient.__init__Z   s   0 )4L+:X:X 	
 &<+C{666z!<@ { #'!?!??
!2I  A #' "!![%C%CC"36 #
 #>D#
 !?!??!'7;DI%gw?DIBF8<  ! /#59%)"%)"   #&  %
 !0r"   c                   K   | j                   j                  | j                         d {   | _        t	        j
                  d| j                  j                          t	        j
                  d| j                  j                          t	        j
                  d| j                  j                          t	        j
                  d| j                  j                          t	        j                  d| j                  j                   d| j                  j                          t	        j                  d       y 7 w)NzHeyGen sessionId: zHeyGen realtime_endpoint: zHeyGen livekit URL: zHeyGen livekit token: z5Full Link: https://meet.livekit.io/custom?liveKitUrl=z&token=zHeyGen session started)r>   new_sessionrF   r?   r   debug
session_idws_urllivekit_urlaccess_tokeninforS   s    r#   _initializezHeyGenClient._initialize   s    %)YY%:%:4;P;P%QQ)$*>*>*I*I)JKL1$2F2F2M2M1NOP+D,@,@,L,L+MNO-d.B.B.O.O-PQRCDDXDXDdDdCeelmq  nB  nB  nO  nO  mP  Q	
 	,-  Rs   )ED>DEsetupc                   K   | j                   t        j                  d       y|j                  | _        	 | j                          d{    t        j                         | _        | j                  j                  | j                  | j                        |  d      | _        y7 [# t        $ r;}t        j                  d|        | j                          d{  7   Y d}~yd}~ww xY ww)zSetup the client and initialize the conversation.

        Establishes a new session with HeyGen's API if one doesn't exist.

        Args:
            setup: The frame processor setup configuration.
        Nz"heygen_session already initializedz::event_callback_taskzFailed to setup HeyGenClient: )r?   r   rW   task_managerrA   r^   asyncioQueuerH   create_task_callback_task_handlerrI   	Exceptionerrorcleanup)rS   r_   es      r#   r_   zHeyGenClient.setup   s      +LL=>"//
	!""$$$ 'D#11==++D,=,=>&-. D %  	!LL9!=>,,.  	!sM   4C/B( 
B&AB( %C/&B( (	C,1+C'CC'"C/'C,,C/c                   K   	 | j                   E| j                  j                  | j                   j                         d{    d| _         d| _        | j
                  rB| j                  r5| j                  j                  | j
                         d{    d| _        yyy7 a7 # t        $ r"}t        j                  d|        Y d}~yd}~ww xY ww)zgCleanup client resources.

        Closes the active HeyGen session and resets internal state.
        NFzException during cleanup: )r?   r>   close_sessionrX   rE   rI   rA   cancel_taskrf   r   rg   rS   ri   s     r#   rh   zHeyGenClient.cleanup   s     

	;##/ii--d.B.B.M.MNNN'+$"'D$6$6((44T5E5EFFF#'  %7	 O
 G 	;LL5aS9::	;sS   C>B( B$AB( B&B( !C$B( &B( (	C1C	CCCframeaudio_chunk_sizec                 B  K   | j                   rt        j                  d       yt        j                  d       | j                  j                  xs |j                  | _        | j                  j                  xs |j                  | _        || j                  z  dz  | _        t        j                  d| j                          | j                          d{    | j                          d{    | j                  | j                  j                         y7 B7 ,w)a|  Start the client and establish all necessary connections.

        Initializes WebSocket and LiveKit connections using the provided configuration.
        Sets up audio processing with the specified sample rates.

        Args:
            frame: Initial configuration frame containing audio parameters
            audio_chunk_size: Audio chunk size for output processing
        zheygen client already startedNzHeyGenClient starting   zHeyGenClient send_interval: )r@   r   rW   rB   audio_in_sample_raterC   audio_out_sample_raterD   rN   _ws_connect_livekit_connect_call_event_callbackrG   r&   )rS   rn   ro   s      r#   startzHeyGenClient.start   s      ??LL89,.#||@@^ED^D^ $ B B aeFaFa/$2G2GG1L3D4G4G3HIJ   ##%%%!!$//">">? 	!%s$   CDDD0D1+DDc                    K   t        j                  d       | j                          d{    | j                          d{    | j	                          d{    y7 57 7 	w)zStop the client and terminate all connections.

        Disconnects from WebSocket and LiveKit endpoints, and performs cleanup.
        zHeyGenVideoService stoppingN)r   rW   _ws_disconnect_livekit_disconnectrh   r]   s    r#   stopzHeyGenClient.stop  sU     
 	24!!###&&(((lln 	$(s3   )A'A!A'A#A'A%A'#A'%A'c                   K   	 | j                   rt        j                  d       yt        j                  d       t        | j                  j
                         d{   | _         d| _        | j                  j                  | j                         d      | _
        y7 A# t        $ r+}t        j                  |  d|        d| _         Y d}~yd}~ww xY ww)	z%Connect to HeyGen websocket endpoint.z"HeyGenClient ws already connected!NzHeyGenClient ws connecting)uriTHeyGenClient_Websocketnamez initialization error: )r@   r   rW   websocket_connectr?   rY   rE   rA   rd   _ws_receive_task_handler_receive_taskrf   rg   rm   s     r#   rt   zHeyGenClient._ws_connect  s     	#ACLL57$5((//% DO #DO!%!3!3!?!?--/6N "@ "D	  	#LLD6!8<="DOO	#sK   C!B" C8B" B A B" C B" "	C+!CCCCc                 Z  K   | j                   r_	 | j                  j                          d{   }t        j                  |      }| j                  |       d{    | j                   r^yy7 A7 # t        $ r Y yt        $ r"}t        j                  d|        Y d}~yd}~ww xY ww)z#Handle incoming WebSocket messages.Nz$Error processing WebSocket message: )
rE   r@   recvjsonloads_handle_ws_server_eventr   rf   r   rg   )rS   messageparsed_messageri   s       r#   r   z%HeyGenClient._ws_receive_task_handler  s     oo $ 4 4 66!%G!422>BBB	 oo6B%  CA3GHsb   B+A3 A/-A3 A1A3  B+-B+/A3 1A3 3	B(<B+>B(B#B+#B((B+eventc                    K   |j                  d      }|dk(  rt        j                  d|        yt        j                  d|        yw)z&Handle an event from HeyGen websocket.typezagent.statez'HeyGenClient ws received agent status: z(HeyGenClient ws received unknown event: N)getr   rW   trace)rS   r   
event_types      r#   r   z$HeyGenClient._handle_ws_server_event,  sD     YYv&
&LLB5'JKLLCJ<PQs   A	Ac                   K   	 d| _         | j                  r"| j                  j                          d{    d| _        y7 # t        $ r$}t	        j
                  |  d|        Y d}~2d}~ww xY w# d| _        w xY ww)z*Disconnect from HeyGen websocket endpoint.FNz disconnect error: )rE   r@   closerf   r   rg   rm   s     r#   ry   zHeyGenClient._ws_disconnect4  sq     	##DOoo++--- #DO	 . 	:LLD6!4QC899	: #DOsI   A?0A AA A?A 	A0A+&A3 +A00A3 3	A<<A?r   c                 8  K   | j                   st        j                  |  d       y	 | j                  r7| j                  j	                  t        j                  |             d{    yy7 # t        $ r}t        j                  d|        |d}~ww xY ww)z#Send a message to HeyGen websocket.z$ websocket is not connected anymore.Nz+Error sending message to HeyGen websocket: )	rE   r   rW   r@   sendr   dumpsrf   rg   )rS   r   ri   s      r#   _ws_sendzHeyGenClient._ws_send?  s     LLD6!EFG	oo**4::g+>??? ? 	LLFqcJKG	s:   &B=A/ &A-'A/ +B-A/ /	B8BBBevent_idc                    K   t        j                  d       | j                          | j                  d|d       d{    y7 w)zInterrupt the avatar's current action.

        Stops the current animation/speech and returns the avatar to idle state.
        Useful for handling user interruptions during avatar speech.
        zHeyGenClient interruptzagent.interruptr   r   N)r   rW   _reset_audio_timingr   rS   r   s     r#   	interruptzHeyGenClient.interruptK  sB      	-.  "mm)$
 	
 	
s   =AA Ac                    K   t        j                  d       | j                  dt        t	        j
                               d       d{    y7 w)zStart the avatar's listening animation.

        Triggers visual cues indicating the avatar is listening to user input.
        z"HeyGenClient start_agent_listeningzagent.start_listeningr   N)r   rW   r   r*   uuiduuid4r]   s    r#   start_agent_listeningz"HeyGenClient.start_agent_listeningZ  sA     
 	9:mm/

-
 	
 	
s   AA
AAc                 ~   K   | j                  dt        t        j                               d       d{    y7 w)zoStop the avatar's listening animation.

        Returns the avatar to idle state from listening state.
        zagent.stop_listeningr   N)r   r*   r   r   r]   s    r#   stop_agent_listeningz!HeyGenClient.stop_agent_listeningg  s4     
 mm.

-
 	
 	
s   3=;=c                     d| _         y)zHIndicates that the output transport is ready and able to receive frames.TN)rQ   r]   s    r#   transport_readyzHeyGenClient.transport_readys  s
     $r"   c                     | j                   S )z`Get the output sample rate.

        Returns:
            The output sample rate in Hz.
        )rD   r]   s    r#   out_sample_ratezHeyGenClient.out_sample_ratew  s     $$$r"   c                     | j                   S )z^Get the input sample rate.

        Returns:
            The input sample rate in Hz.
        )rC   r]   s    r#   in_sample_ratezHeyGenClient.in_sample_rate  s     ###r"   audioc                    K   t        j                  |      j                  d      }| j                  d||d       d{    | j	                          d{    y7 7 w)zSend audio data to the agent speak.

        Args:
            audio: Audio data in base64 encoded format
            event_id: Unique identifier for the event
        zutf-8zagent.speak)r   r   r   N)base64	b64encodedecoder   _write_audio_sleep)rS   r   r   audio_base64s       r#   agent_speakzHeyGenClient.agent_speak  sf      ''.55g>mm%%$
 	
 	
 %%'''	
 	(s"   =A!A A!AA!A!c                      d| _         d| _        y)z%Reset audio timing control variables.r:   r   N)rP   rO   r]   s    r#   r   z HeyGenClient._reset_audio_timing  s    #&  r"   c                   K   | j                   dk  rF| xj                   | j                  z  c_         t        j                         | j                  z   | _        yt        j                         }t        d| j                  |z
        }|dkD  r=t        j                  |       d{    | xj                  | j                  z  c_        yt        j                         | j                  z   | _        y7 Kw)z7Simulate audio playback timing with appropriate delays.g      @Nr   )rP   rN   time	monotonicrO   maxrb   sleep)rS   current_timesleep_durations      r#   r   zHeyGenClient._write_audio_sleep  s      ##c)$$(;(;;$#'>>#3d6I6I#ID  ~~'Q 4 4| CDA--///  D$7$77 #'>>#3d6I6I#ID  0s   B C0"C.#AC0c                 h   K   | j                          | j                  d|d       d{    y7 w)zSend signaling that the agent has finished speaking.

        Args:
            event_id: Unique identifier for the event
        zagent.speak_endr   N)r   r   r   s     r#   agent_speak_endzHeyGenClient.agent_speak_end  s5      	  "mm)$
 	
 	
s   (202participant_idc                   K   t        j                  d| d| j                          || _        | j                  t        j
                  d       y| j                  r|| j                  j                  v r| j                  j                  |   }|j                  j                         D ]  }|j                  t        j                  j                  k(  s+|j                  8t        j                  d|j                          t        j                   |j                  | j                        }| j"                  j%                  | j'                  |      d      | _         y yyyw)	zCapture audio frames from the HeyGen avatar.

        Args:
            participant_id: Identifier of the participant to capture audio from
            callback: Async function to handle received audio frames
        zcapture_participant_audio: z, sample_rate: NLTrying to capture more than one audio stream. It is currently not supported.z+Starting audio capture for existing track: tracksample_rateHeyGenClient_Receive_Audior   )r   rW   rC   rM   rK   r=   _livekit_roomremote_participantstrack_publicationsvalueskindr   	TrackKind
KIND_AUDIOr   sidAudioStreamrA   rd   _process_audio_frames)rS   r   callbackparticipant	track_pubaudio_streams         r#   capture_participant_audioz&HeyGenClient.capture_participant_audio  s<     	).)9I]I]H^_	
 &."'NN^  .D4F4F4Z4Z"Z,,@@PK(;;BBD 		>>S]]%=%==)//B]LL#Ny}}o!^_#&??'oo4;O;O$L (,'9'9'E'E22<@Gc (F (D$ 	 #[s   CE%E%!BE%c                   K   t        j                  d|        || _        | j                  t        j                  d       y| j
                  r|| j
                  j                  v r| j
                  j                  |   }|j                  j                         D ]  }|j                  t        j                  j                  k(  s+|j                  8t        j                  d|j                          t        j                  |j                        }| j                   j#                  | j%                  |      d      | _         y yyyw)zCapture video frames from the HeyGen avatar.

        Args:
            participant_id: Identifier of the participant to capture video from
            callback: Async function to handle received video frames
        zcapture_participant_video: Nr   z+Starting video capture for existing track: HeyGenClient_Receive_Videor   )r   rW   rL   rJ   r=   r   r   r   r   r   r   r   
KIND_VIDEOr   r   VideoStreamrA   rd   _process_video_frames)rS   r   r   r   r   video_streams         r#   capture_participant_videoz&HeyGenClient.capture_participant_video  s     	2>2BCD%-"'NN^  .D4F4F4Z4Z"Z,,@@PK(;;BBD 	>>S]]%=%==)//B]LL#Ny}}o!^_#&??9??#CL'+'9'9'E'E22<@Gc (F (D$  #[s   CEEA8Estreamc                 H  K   	 t        j                  d       |2 3 d{   }	 |j                  }t        |j                        }t        ||j                  d      }| j                  r%| j                  r| j                  |       d{    u7 p7 # t        $ r"}t        j                  d|        Y d}~d}~ww xY w6 n.# t        $ r"}t        j                  d|        Y d}~nd}~ww xY wt        j                  d       y# t        j                  d       w xY ww)z)Process audio frames from LiveKit stream.z"Starting audio frame processing...N   )r   r   num_channelszError processing audio frame: zError processing audio frames: zAudio frame processing ended.)r   rW   rn   bytesdatar
   r   rQ   rM   rf   rg   )rS   r   frame_eventaudio_frame
audio_datari   s         r#   r   z"HeyGenClient._process_audio_frames  s    	;LL=>%+ G GkG"-"3"3K!&{'7'7!8J"/($/$;$;%&#K
 ,,1K1K"88EEEG F  GLL#A!!EFFG &,   	@LL:1#>??	@ LL8:FLL8:s   D"C CBCC A%B
BBC CB	B?B:5C :B??C D 	C/C*%D *C//D 2D"DD"c                   K   	 t        j                  d       |2 3 d{   }	 |j                  }|j                  t        j
                  k7  r|j                  t        j
                        }t        t        |j                        |j                  |j                  fd      }|j                  dz  |_        | j                  r%| j                  r| j                  |       d{    7 7 # t         $ r"}t        j"                  d|        Y d}~d}~ww xY w6 n.# t         $ r"}t        j"                  d|        Y d}~nd}~ww xY wt        j                  d       y# t        j                  d       w xY ww)	z)Process video frames from LiveKit stream.z"Starting video frame processing...NRGB)imagesizeformati  z)Error processing individual video frame: zError processing video frames: zVideo frame processing ended.)r   rW   rn   r   r   RGB24convertr   r   r   widthheighttimestamp_usptsrQ   rL   rf   rg   )rS   r   r   video_frameimage_frameri   s         r#   r   z"HeyGenClient._process_video_frames  sS    	;LL=>%+ R RkR"-"3"3K #''?+@+@@&1&9&9/:O:O&P #0#K$4$45)//1C1CD$#K
 '2&>&>$&FKO,,1K1K"88EEE#R" F  RLL#LQC!PQQR% &,(  	@LL:1#>??	@ LL8:FLL8:s   E<D DC*DD B?C.$C,%C.)D *D,C..	D7DD DD E" 	E	'E?E" E		E" E<"E99E<c           
         K   	 t        j                  d j                  j                          t	        j
                          _         j                  j                  d      dt        j                  f fd       } j                  j                  d      dt        j                  dt        j                  dt        j                  f fd       } j                  j                  d	      dt        j                  dt        j                  dt        j                  fd
       } j                  j                  d      dt        j                  f fd       } j                  s j                  j                  n j                  j                  } j                  j                   j                  j                  |       d{    t        j                  d j                  j                          t        j                  d j                  j                   j"                          t        j                  dt%         j                  j&                                 j                  j&                  j)                         D ]  }t        j                  d|j"                   d|j*                           j-                   j.                  j0                  |j*                         |j2                  j)                         D ]>  }t        j                  d|j"                   d|j4                   d|j                          @  y7 # t6        $ r)}t        j8                  d|        d _        Y d}~yd}~ww xY ww)zConnect to LiveKit room.z-HeyGenClient livekit connecting to room URL: participant_connectedr   c           	      z   t        j                  d| j                   d| j                          | j                  j                         D ]>  }t        j                  d|j                   d|j                   d|j                          @ j                  j                  j                  | j                         y )NzParticipant connected - SID: , Identity: zAvailable track - SID: , Kind: , Name: )r   rW   r   identityr   r   r   r   rv   rG   r'   )r   r   rS   s     r#   r'   z?HeyGenClient._livekit_connect.<locals>.on_participant_connected9  s    3KOO3DLQ\QeQePfg "-!?!?!F!F!H ILL1)--HXX`ajaoao`pq ))OO<<k>R>Rr"   track_subscribedr   publicationc                    | j                   t        j                  j                  k(  rj                  uj
                  it        j                  d|j                          t        j                  |       }j                  j                  j                  |      d      _        y | j                   t        j                  j                  k(  rj                  j                  ut        j                  d|j                          t        j                   | j"                        }j                  j                  j%                  |      d      _        y y y y )Nz+Creating video stream processor for track: r   r   z+Creating audio stream processor for track: r   r   )r   r   r   r   rL   rJ   r   rW   r   r   rA   rd   r   r   rM   rK   r   rC   r   )r   r   r   r   r   rS   s        r#   on_track_subscribedz:HeyGenClient._livekit_connect.<locals>.on_track_subscribedF  s(    JJ#--":"::22>((0LL#N{N_!`a#&??5#9L'+'9'9'E'E22<@Gc (F (D$ JJ#--":"::22>((0LL#N{N_!`a#&??DL`L`#aL'+'9'9'E'E22<@Gc (F (D$	 1 ? ;r"   track_unsubscribedc                 b    t        j                  d|j                   d| j                          y )NzTrack unsubscribed - SID: r   )r   rW   r   r   )r   r   r   s      r#   on_track_unsubscribedz<HeyGenClient._livekit_connect.<locals>.on_track_unsubscribeda  s+     9+//9J(SXS]S]R^_`r"   participant_disconnectedc                     t        j                  d| j                   d| j                          j	                  j
                  j                  | j                         y )Nz Participant disconnected - SID: r   )r   rW   r   r   rv   rG   r(   )r   rS   s    r#   r(   zBHeyGenClient._livekit_connect.<locals>.on_participant_disconnectedi  sQ    6{6G|T_ThThSij ))OO??AUAUr"   Nz(Successfully connected to LiveKit room: zLocal participant SID: zNumber of remote participants: zExisting participant - SID: r   zExisting track - SID: r   r   zLiveKit initialization error: )r   rW   r?   rZ   r   Roomr   onRemoteParticipantTrackRemoteTrackPublicationrR   livekit_agent_tokenr[   r   r   local_participantr   lenr   r   r   rv   rG   r'   r   r   rf   rg   )	rS   r'   r   r   r(   r[   r   r   ri   s	   `        r#   ru   zHeyGenClient._livekit_connect1  s    [	&LL?@T@T@`@`?ab "%D""#:;
c6K6K 
 <
 ""#56yy 77 !22 74 ""#78ayya 77a !22a 9a ""#=>9N9N  ? ,, $$88))66  $$,,T-A-A-M-M|\\\LLCDDVDVD[D[C\]^LL243E3E3W3W3[3[2\]^LL1#d6H6H6\6\2]1^_
  $11EELLN 
2;??2C<P[PdPdOef ))OO<<k>R>R "-!?!?!F!F!H ILL0x	GWW_`i`n`n_op
 ](  	&LL9!=>!%D	&sB   M;F>M ME>M M;M 	M8M3.M;3M88M;c                 `  K   	 t        j                  d       | j                  r4| j                  j	                  | j                         d{    d| _        | j
                  r4| j                  j	                  | j
                         d{    d| _        | j                  rTt        j                  d       | j                  j                          d{    d| _        t        j                  d       yy7 7 n7 &# t        $ r"}t        j                  d|        Y d}~yd}~ww xY ww)zDisconnect from LiveKit room.zStarting LiveKit disconnect...NzDisconnecting from LiveKit roomz+Successfully disconnected from LiveKit roomzLiveKit disconnect error: )
r   rW   rJ   rA   rl   rK   r   
disconnectrf   rg   rm   s     r#   rz   z HeyGenClient._livekit_disconnect  s     	;LL9:((44T5E5EFFF#' ((44T5E5EFFF#' !!>?((33555%)"JK	 " G G
 6  	;LL5aS9::	;sf   D.A	D  C:?D  C<A	D  C> D  8D.:D  <D  >D   	D+	D&!D.&D++D.c                 B    | j                   j                  |g|       y)z,Queue an event callback for async execution.N)rH   
put_nowait)rS   r   argss      r#   rv   z!HeyGenClient._call_event_callback  s    $$h%6%67r"   queuec                    K   	 |j                          d{   ^}} ||  d{    |j                          87 $7 w)z1Handle queued callbacks from the specified queue.N)r   	task_done)rS   r  r   r
  s       r#   re   z#HeyGenClient._callback_task_handler  s?     &+iik 1XD/!!OO  1!s   A <A >A A )r4   N)7r   r   r   r    r*   aiohttpClientSessionr   r   r   r   r   r   r%   boolrT   r^   r   r_   rh   r   intrw   r{   rt   r   dictr   ry   r   r   r   r   r   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   ru   rz   rv   rb   rc   re   r!   r"   r#   r,   r,   K   s   ( \`.2 %[0 [0 &&	[0
  [0 "%(CEV(V"WX[0 {+[0 #[0 [0 
[0z	.!!4 ! !0;"@ @s @t @.#$R4 RD R	#
d 
t 

 
 



% % % % $ $ $(u ( ( ($!
J$
c 
d 
c PT >c PT 8;#// ;2;#// ;:]&~;08'-- r"   r,   )5r    rb   r   r   r   r   enumr   typingr   r   r   r   r  logurur   pydanticr	   pipecat.frames.framesr
   r   r   "pipecat.processors.frame_processorr   .pipecat.services.heygen.api_interactive_avatarr   r   &pipecat.services.heygen.api_liveavatarr   r    pipecat.services.heygen.base_apir   !pipecat.transports.base_transportr   "pipecat.utils.asyncio.task_managerr   livekitr   "livekit.rtc._proto.video_frame_pb2r   websockets.asyncio.clientr   r   websockets.exceptionsr   ModuleNotFoundErrorri   rg   rf   HEY_GEN_SAMPLE_RATEr   r%   r,   r!   r"   r#   <module>r%     s          7 7    
 C W E = >,BF8   $  Bi Bf	 f	;  ,FLL;qc"#FLLXY
&qc*
++,s   ,B' 'C#,2CC#