o
    i5                     @   s   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 dd
lmZ ddlmZ eG dd deZ G dd deZ!dS )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)
TTSService)
traced_ttsc                   @   s   e Zd ZdZdS )DeepgramSageMakerTTSSettingsz)Settings for DeepgramSageMakerTTSService.N)__name__
__module____qualname____doc__ r   r   [/home/ubuntu/.local/lib/python3.10/site-packages/pipecat/services/deepgram/sagemaker/tts.pyr   )   s    r   c                       s<  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dZ
defddZdef fddZdef fddZdef fddZdedef fddZdd Zdd Zdedeeef f fd d!Zd"d# Zdedef fd$d%Zd,d&ee fd'd(Ze d)ed&ede!edf fd*d+Z"  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",
            settings=DeepgramSageMakerTTSService.Settings(
                voice="aura-2-helena-en",
            )
        )
    	_settingsNlinear16)voicesample_rateencodingsettingsendpoint_nameregionr    r!   r"   r#   c          	         s   |dur
|  dd |pd}| jd|dd}|dur|| t jd|ddd|d| || _|| _|| _d| _d| _	d| _
d| _dS )	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=DeepgramSageMakerTTSService.Settings(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   )"_warn_init_param_moved_to_settingsSettings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__r   r   r/   K   s4   
	
z$DeepgramSageMakerTTSService.__init__returnc                 C   s   dS )zCheck if this service can generate processing metrics.

        Returns:
            True, as Deepgram SageMaker TTS service supports metrics generation.
        Tr   )r7   r   r   r   can_generate_metrics   s   z0DeepgramSageMakerTTSService.can_generate_metricsframec                    &   t  |I dH  |  I dH  dS )zStart the Deepgram SageMaker TTS service.

        Args:
            frame: The start frame containing initialization parameters.
        N)r.   start_connectr7   r>   r:   r   r   r@         z!DeepgramSageMakerTTSService.startc                    r?   )zbStop the Deepgram SageMaker TTS service.

        Args:
            frame: The end frame.
        N)r.   stop_disconnectrB   r:   r   r   rD      rC   z DeepgramSageMakerTTSService.stopc                    r?   )zgCancel the Deepgram SageMaker TTS service.

        Args:
            frame: The cancel frame.
        N)r.   cancelrE   rB   r:   r   r   rF      rC   z"DeepgramSageMakerTTSService.cancel	directionc                    sN   t  ||I dH  t|ttfr|  I dH  dS t|tr%d| _dS dS )zProcess frames with special handling for LLM response end.

        Args:
            frame: The frame to process.
            direction: The direction of frame processing.
        NF)r.   process_frame
isinstancer   r	   flush_audior   r6   )r7   r>   rG   r:   r   r   rH      s   

z)DeepgramSageMakerTTSService.process_framec              
      s   t d d| jj d| j d| j }t| j| jd|d| _	z | j	
 I dH  | |  | _t d | d	I dH  W dS  tyk } z| jd
| |dI dH  | dt|I dH  W Y d}~dS d}~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    r2   r!   r   r0   r1   r3   start_sessioncreate_task_process_responsesr4   _call_event_handler	Exception
push_errorstr)r7   query_stringer   r   r   rA      s(   

$z$DeepgramSageMakerTTSService._connectc              
      s   | j r]| j jr_td z| j ddiI dH  W n ty4 } ztd|  W Y d}~nd}~ww | jrF| j sF| 	| jI dH  | j 
 I dH  td | dI dH  dS dS dS )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)r3   	is_activer   rS   	send_jsonrX   warningr4   donecancel_taskclose_sessionrW   )r7   r\   r   r   r   rE      s   

z'DeepgramSageMakerTTSService._disconnectdeltac                    sF   t  |I dH }|s|S d|v r| jj| j_|   | | |S )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    )r.   _update_settingsr   r    r&   _sync_model_name_to_metrics _warn_unhandled_updated_settings)r7   rf   changedr:   r   r   rg      s   
z,DeepgramSageMakerTTSService._update_settingsc              
      s  zz| j r| j jr| j  I dH }|du rnt|drt|jdr|jjr|jj}zS|d}t|}|	d}|dkrGt
d|  n5|dkrTt
d	|  n(|d
krat
d|  n|dkrtt
|  d|	dd  nt
d|  W n% ttjfy   |  I dH  t|| jd| jd}| |I dH  Y nw | j r| j js
W n- tjy   t
d Y n' ty } z| jd| |dI dH  W Y d}~nd}~ww W t
d dS W t
d dS W t
d dS t
d 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-8r]   MetadatazReceived metadata: FlushedzReceived Flushed: ClearedzReceived Cleared: Warningz
 warning: descriptionzUnknown warningzReceived unknown message type:    
context_idz TTS response processor cancelledrN   rO   zTTS response processor stopped)r3   r`   receive_responsehasattrrk   rl   decodejsonloadsgetr   tracerb   rS   UnicodeDecodeErrorJSONDecodeErrorstop_ttfb_metricsr   r!   r5   
push_frameasyncioCancelledErrorrX   rY   )r7   resultpayloadresponse_dataparsedmsg_typer>   r\   r   r   r   rV     sf   



)&z.DeepgramSageMakerTTSService._process_responsesc              
      s   t  ||I dH  d| _| jrA| jjrCz| jddiI dH  W dS  ty@ } zt|  d|  W Y d}~dS d}~ww dS dS )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.
        NFr]   Clearz error sending Clear message: )	r.   _handle_interruptionr6   r3   r`   ra   rX   r   error)r7   r>   rG   r\   r:   r   r   r   ?  s   "z0DeepgramSageMakerTTSService._handle_interruptionrt   c              
      sp   | j r4| j jr6z| j ddiI dH  W dS  ty3 } zt|  d|  W Y d}~dS d}~ww dS dS )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.
        r]   FlushNz error sending Flush message: )r3   r`   ra   rX   r   r   )r7   rt   r\   r   r   r   rJ   N  s   "z'DeepgramSageMakerTTSService.flush_audiotextc              
   C  s   t |  d| d z5| |s-| |I dH  | js'|  I dH  d| _t|dV  || _| j	d|dI dH  dV  W dS  t
y] } ztd| d	V  W Y d}~dS d}~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 []NTrs   Speak)r]   r   rN   )r   )r   rS   audio_context_availablecreate_audio_contextr6   start_ttfb_metricsr   r5   r3   ra   rX   r
   )r7   r   rt   r\   r   r   r   run_ttsZ  s    
 z#DeepgramSageMakerTTSService.run_tts)N)$r   r   r   r   r   r,   __annotations__rZ   r   intr/   boolr=   r   r@   r	   rD   r   rF   r   r   rH   rA   rE   r   dictr   rg   rV   r   r   rJ   r   r   r   __classcell__r   r   r:   r   r   0   sD   
 ;			 9(r   )"r   r   rx   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   pipecat.services.tts_servicer   (pipecat.utils.tracing.service_decoratorsr   r   r   r   r   r   r   <module>   s   0