
    qi5                         d Z ddlZddl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mZmZmZmZmZ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 ddlm Z  e G d de             Z! G d de      Z"y)a/  Deepgram text-to-speech service for AWS SageMaker.

This module provides a Pipecat TTS service that connects to Deepgram models
deployed on AWS SageMaker endpoints. Uses HTTP/2 bidirectional streaming for
low-latency real-time speech synthesis with support for interruptions and
streaming audio output.
    N)	dataclass)AnyAsyncGeneratorOptional)logger)
BotStoppedSpeakingFrameCancelFrameEndFrame
ErrorFrameFrameInterruptionFrameLLMFullResponseEndFrame
StartFrameTTSAudioRawFrameTTSStartedFrame)FrameDirection)SageMakerBidiClient)TTSSettings_warn_deprecated_param)
TTSService)
traced_ttsc                       e Zd ZdZy)DeepgramSageMakerTTSSettingsz)Settings for DeepgramSageMakerTTSService.N)__name__
__module____qualname____doc__     Y/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/services/deepgram/sagemaker/tts.pyr   r   )   s    3r   r   c                   :    e Zd ZU dZeZeed<   ddddddededee   d	ee	   d
edee   f fdZ
defdZdef fdZdef fdZdef fdZdedef fdZd Zd Zdedeeef   f fdZd Zdedef fdZddee   fdZe dedede!edf   fd       Z" xZ#S ) DeepgramSageMakerTTSServicea  Deepgram text-to-speech service for AWS SageMaker.

    Provides real-time speech synthesis using Deepgram models deployed on
    AWS SageMaker endpoints. Uses HTTP/2 bidirectional streaming for low-latency
    audio generation with support for interruptions via the Clear message.

    Requirements:

    - AWS credentials configured (via environment variables, AWS CLI, or instance metadata)
    - A deployed SageMaker endpoint with Deepgram TTS model: https://developers.deepgram.com/docs/deploy-amazon-sagemaker
    - ``pipecat-ai[sagemaker]`` installed

    Example::

        tts = DeepgramSageMakerTTSService(
            endpoint_name="my-deepgram-tts-endpoint",
            region="us-east-2",
            voice="aura-2-helena-en",
        )
    	_settingsNlinear16)voicesample_rateencodingsettingsendpoint_nameregionr%   r&   r'   r(   c          	         |t        dt        d       |xs d}t        d|d      }||j                  |       t        	|   d|ddd|d| || _        || _        || _        d| _        d| _	        d| _
        d| _        y)	a  Initialize the Deepgram SageMaker TTS service.

        Args:
            endpoint_name: Name of the SageMaker endpoint with Deepgram TTS model
                deployed (e.g., "my-deepgram-tts-endpoint").
            region: AWS region where the endpoint is deployed (e.g., "us-east-2").
            voice: Voice model to use for synthesis. Defaults to "aura-2-helena-en".

                .. deprecated:: 0.0.105
                    Use ``settings=DeepgramSageMakerTTSSettings(voice=...)`` instead.

            sample_rate: Audio sample rate in Hz. If None, uses the value from StartFrame.
            encoding: Audio encoding format. Defaults to "linear16".
            settings: Runtime-updatable settings. When provided alongside deprecated
                parameters, ``settings`` values take precedence.
            **kwargs: Additional arguments passed to the parent TTSService.
        Nr%   zaura-2-helena-en)modelr%   languageT)r&   push_stop_framespause_frame_processingappend_trailing_spacer(   Fr   )r   r   apply_updatesuper__init___endpoint_name_region	_encoding_client_response_task_context_id_ttfb_started)
selfr)   r*   r%   r&   r'   r(   kwargsdefault_settings	__class__s
            r    r3   z$DeepgramSageMakerTTSService.__init__I   s    8 "7,H'R++7

 ))(3 	
#!#'"&%	
 	
 ,!6:6:*.#(r   returnc                      y)zCheck if this service can generate processing metrics.

        Returns:
            True, as Deepgram SageMaker TTS service supports metrics generation.
        Tr   )r;   s    r    can_generate_metricsz0DeepgramSageMakerTTSService.can_generate_metrics   s     r   framec                 t   K   t         |   |       d{    | j                          d{    y7 7 w)zStart the Deepgram SageMaker TTS service.

        Args:
            frame: The start frame containing initialization parameters.
        N)r2   start_connectr;   rB   r>   s     r    rD   z!DeepgramSageMakerTTSService.start   s3      gmE"""mmo 	#   848688c                 t   K   t         |   |       d{    | j                          d{    y7 7 w)zbStop the Deepgram SageMaker TTS service.

        Args:
            frame: The end frame.
        N)r2   stop_disconnectrF   s     r    rI   z DeepgramSageMakerTTSService.stop   s6      gl5!!!    	" rG   c                 t   K   t         |   |       d{    | j                          d{    y7 7 w)zgCancel the Deepgram SageMaker TTS service.

        Args:
            frame: The cancel frame.
        N)r2   cancelrJ   rF   s     r    rL   z"DeepgramSageMakerTTSService.cancel   s6      gnU###    	$ rG   	directionc                    K   t         |   ||       d{    t        |t        t        f      r| j                          d{    yt        |t              rd| _        yy7 L7  w)zProcess frames with special handling for LLM response end.

        Args:
            frame: The frame to process.
            direction: The direction of frame processing.
        NF)r2   process_frame
isinstancer   r
   flush_audior   r:   )r;   rB   rM   r>   s      r    rO   z)DeepgramSageMakerTTSService.process_frame   sc      g#E9555e5x@A""$$$67!&D 8	 	6 %s!   A(A$-A(A&A(&A(c                   K   t        j                  d       d| j                  j                   d| j                   d| j
                   }t        | j                  | j                  d|      | _	        	 | j                  j                          d{    | j                  | j                               | _        t        j                  d       | j                  d	       d{    y7 W7 # t        $ rM}| j!                  d
| |       d{  7   | j                  dt#        |             d{  7   Y d}~yd}~ww xY ww)zConnect to the SageMaker endpoint and start the BiDi session.

        Builds the Deepgram TTS query string, creates the BiDi client,
        starts the streaming session, and launches a background task for processing
        responses.
        z*Connecting to Deepgram TTS on SageMaker...zmodel=z
&encoding=z&sample_rate=zv1/speak)r)   r*   model_invocation_pathmodel_query_stringNz&Connected to Deepgram TTS on SageMakeron_connectedUnknown error occurred: 	error_msg	exceptionon_connection_error)r   debugr#   r%   r6   r&   r   r4   r5   r7   start_sessioncreate_task_process_responsesr8   _call_event_handler	Exception
push_errorstr)r;   query_stringes      r    rE   z$DeepgramSageMakerTTSService._connect   s     	AB T^^))**T^^4DMRVRbRbQcd 	 +--<<",+	

	J,,,,..."&"2"243J3J3L"MDLLAB**>::: /
 ; 	J//.Fqc,JVW/XXX**+@#a&III	Jsm   A1E4C- C)AC- #C+$C- (E)C- +C- -	E6D>D#D>3D64D>9E>EEc                 h  K   | j                   r| j                   j                  rt        j                  d       	 | j                   j	                  ddi       d{    | j                  r=| j                  j                         s#| j                  | j                         d{    | j                   j                          d{    t        j                  d       | j                  d       d{    yyy7 # t
        $ r"}t        j                  d|        Y d}~d}~ww xY w7 7 g7 ;w)zDisconnect from the SageMaker endpoint.

        Sends a Close message to Deepgram, cancels the response processing task,
        and closes the BiDi session. Safe to call multiple times.
        z/Disconnecting from Deepgram TTS on SageMaker...typeCloseNzFailed to send Close message: z+Disconnected from Deepgram TTS on SageMakeron_disconnected)r7   	is_activer   r[   	send_jsonr`   warningr8   donecancel_taskclose_sessionr_   )r;   rd   s     r    rJ   z'DeepgramSageMakerTTSService._disconnect   s      <<DLL22LLJKEll,,fg->??? ""4+>+>+C+C+E&&t':':;;;,,,,...LLFG**+<=== 3< @ E!?sCDDE <. >sq   8D2 C> C<C>  AD2$D,%!D2D.-D24D05D2<C> >	D)D$D2$D))D2.D20D2deltac                    K   t         |   |       d{   }|s|S d|v r5| j                  j                  | j                  _        | j                          | j                  |       |S 7 Tw)zApply a settings delta and reconnect if necessary.

        Since all settings are part of the SageMaker session query string,
        any setting change requires reconnecting to apply the new values.
        Nr%   )r2   _update_settingsr#   r%   r,   _sync_model_name_to_metrics _warn_unhandled_updated_settings)r;   ro   changedr>   s      r    rq   z,DeepgramSageMakerTTSService._update_settings   si      077N g#'>>#7#7DNN ,,. 	--g6# 8s   A-A+AA-c                 H  K   	 | j                   r| j                   j                  rt| j                   j                          d{   }|nNt        |d      rt        |j                  d      r|j                  j
                  r|j                  j
                  }	 |j                  d      }t        j                  |      }|j                  d      }|dk(  rt        j                  d|        n|dk(  rt        j                  d	|        nf|d
k(  rt        j                  d|        nH|dk(  r+t        j                  |  d|j                  dd              nt        j                  d|        | j                   r| j                   j                  rtt        j                  d       y7 m# t        t        j                  f$ rY | j!                          d{  7   t#        || j$                  d| j&                        }| j)                  |       d{  7   Y w xY w# t*        j,                  $ r t        j                  d       Y t.        $ r)}| j1                  d| |       d{  7   Y d}~d}~ww xY w# t        j                  d       w xY ww)ah  Process streaming responses from Deepgram TTS on SageMaker.

        Continuously receives responses from the BiDi stream. Attempts to decode
        each payload as UTF-8 JSON for control messages (Flushed, Cleared, Metadata,
        Warning). If decoding fails, treats the payload as raw audio bytes and pushes
        a TTSAudioRawFrame downstream.
        Nvaluebytes_zutf-8rf   MetadatazReceived metadata: FlushedzReceived Flushed: ClearedzReceived Cleared: Warningz
 warning: descriptionzUnknown warningzReceived unknown message type:    
context_idz TTS response processor cancelledrV   rW   zTTS response processor stopped)r7   ri   receive_responsehasattrrv   rw   decodejsonloadsgetr   tracerk   r[   UnicodeDecodeErrorJSONDecodeErrorstop_ttfb_metricsr   r&   r9   
push_frameasyncioCancelledErrorr`   ra   )r;   resultpayloadresponse_dataparsedmsg_typerB   rd   s           r    r^   z.DeepgramSageMakerTTSService._process_responses  s%    /	;,,4<<#9#9#||<<>>>67+h0O||**"(,,"5"59,3NN7,CM%)ZZ%>F'-zz&'9H':5 &/B6(-K L!)Y!6 &/A&-J K!)Y!6 &/A&-J K!)Y!6 &'+fJ'-zz-AR'S&T%V!"
 !'/Nvh-W X9 ,,4<<#9#9\ LL9:[ ?: !3D4H4HI 	9"&"8"8":::$4 ' $ 0 0 !+/+;+;	%E #'//%"888	9 %% 	=LL;< 	Y//.Fqc,JVW/XXX	Y LL9:s   J"AH* F2AH* CF5 8"H* J"2H* 5,H'!G$"<H'H!H'$H* &H''H* *(JJ JJ 5I86J ;J  JJ JJ"c                 H  K   t         |   ||       d{    d| _        | j                  r>| j                  j                  r'	 | j                  j                  ddi       d{    yyy7 V7 	# t        $ r$}t        j                  |  d|        Y d}~yd}~ww xY ww)zHandle interruption by sending Clear message to Deepgram.

        The Clear message will clear Deepgram's internal text buffer and stop
        sending audio, allowing for a new response to be generated.
        NFrf   Clearz error sending Clear message: )	r2   _handle_interruptionr:   r7   ri   rj   r`   r   error)r;   rB   rM   rd   r>   s       r    r   z0DeepgramSageMakerTTSService._handle_interruption=  s      g*5)<<<"<<DLL22Ill,,fg->??? 3< 	=
 @ Iv%CA3GHHIsK   B"A.-B" A2 &A0'A2 +B"0A2 2	B;BB"BB"r   c                   K   | j                   r>| j                   j                  r'	 | j                   j                  ddi       d{    yyy7 # t        $ r$}t	        j
                  |  d|        Y d}~yd}~ww xY ww)zFlush any pending audio synthesis by sending Flush command.

        This should be called when the LLM finishes a complete response to force
        generation of audio from Deepgram's internal text buffer.
        rf   FlushNz error sending Flush message: )r7   ri   rj   r`   r   r   )r;   r   rd   s      r    rQ   z'DeepgramSageMakerTTSService.flush_audioL  st      <<DLL22Ill,,fg->??? 3<? Iv%CA3GHHIs@   #B  A AA B A 	A=A83B 8A==B textc                  K   t        j                  |  d| d       	 | j                  |      sS| j                  |       d{    | j                  s| j                          d{    d| _        t        |       || _        | j                  j                  d|d       d{    d y7 q7 O7 # t        $ r}t        d| 	       Y d}~yd}~ww xY ww)
aN  Generate speech from text using Deepgram TTS on SageMaker.

        Args:
            text: The text to synthesize into speech.
            context_id: The context ID for tracking audio frames.

        Yields:
            Frame: TTSStartedFrame, then None (audio comes asynchronously via
            the response processor).
        z: Generating TTS []NTr~   Speak)rf   r   rV   )r   )r   r[   audio_context_availablecreate_audio_contextr:   start_ttfb_metricsr   r9   r7   rj   r`   r   )r;   r   r   rd   s       r    run_ttsz#DeepgramSageMakerTTSService.run_ttsX  s      	v/vQ78	C//
;//
;;;))11333)-D&%<<)D,,(('4)HIIIJ <3
 J  	C%=aS#ABBB	Cse   C$%B< B6#B< (B8)AB< +B:,	B< 5C$6B< 8B< :B< <	C!CC$C!!C$)N)$r   r   r   r   r   Settings__annotations__rb   r   intr3   boolrA   r   rD   r
   rI   r	   rL   r   r   rO   rE   rJ   r   dictr   rq   r^   r   r   rQ   r   r   r   __classcell__)r>   s   @r    r"   r"   0   sD   * ,H++  $%)";?9) 9) 	9)
 }9) c]9) 9) 789)vd  ! !!+ !' '> 'J@>,K DcN 27;rI0A In I
IHSM 
I C# C3 C>%QU+;V C Cr   r"   )#r   r   r   dataclassesr   typingr   r   r   logurur   pipecat.frames.framesr   r	   r
   r   r   r   r   r   r   r   "pipecat.processors.frame_processorr   *pipecat.services.aws.sagemaker.bidi_clientr   pipecat.services.settingsr   r   pipecat.services.tts_servicer   (pipecat.utils.tracing.service_decoratorsr   r   r"   r   r   r    <module>r      si      ! 0 0    > J I 3 ? 	; 	 	DC* DCr   