
    qi                        d Z ddlZddlZddlZddlmZmZ ddlmZ ddl	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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!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/  G d de4e      Z5 G d de4e      Z6e G d de              Z7 G d de$      Z8y# e0$ r7Z1 ejd                  de1         ejd                  d        e3de1       dZ1[1ww xY w)z4Deepgram Flux speech-to-text service implementation.    N)	dataclassfield)Enum)AnyAsyncGeneratorDictOptional)	urlencode)logger)	BaseModel)	CancelFrameEndFrame
ErrorFrameFrameInterimTranscriptionFrame
StartFrameTranscriptionFrameUserStartedSpeakingFrameUserStoppedSpeakingFrame)	NOT_GIVENSTTSettings	_NotGiven_warn_deprecated_param)WebsocketSTTService)Language)time_now_iso8601)
traced_stt)connect)StatezException: zNIn order to use Deepgram Flux, you need to `pip install pipecat-ai[deepgram]`.zMissing module: c                   $    e Zd ZdZdZdZdZdZdZy)FluxMessageTypezDeepgram Flux WebSocket message types.

    These are the top-level message types that can be received from the
    Deepgram Flux WebSocket connection.
    	ConnectedErrorTurnInfoConfigureSuccessConfigureFailureN)	__name__
__module____qualname____doc__RECEIVE_CONNECTEDRECEIVE_FATAL_ERROR	TURN_INFOCONFIGURE_SUCCESSCONFIGURE_FAILURE     T/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/services/deepgram/flux/stt.pyr!   r!   .   s&     $!I**r1   r!   c                   $    e Zd ZdZdZdZdZdZdZy)FluxEventTypezDeepgram Flux TurnInfo event types.

    These events are contained within TurnInfo messages and indicate
    different stages of speech processing and turn detection.
    StartOfTurnTurnResumed	EndOfTurnEagerEndOfTurnUpdateN)	r'   r(   r)   r*   START_OF_TURNTURN_RESUMEDEND_OF_TURNEAGER_END_OF_TURNUPDATEr0   r1   r2   r4   r4   <   s#     "M LK(Fr1   r4   c                       e Zd ZU dZ ed       Zedz  ez  ed<    ed       Z	edz  ez  ed<    ed       Z
edz  ez  ed	<    ed
       Zeez  ed<    ed       Zedz  ez  ed<   y)DeepgramFluxSTTSettingsa  Settings for DeepgramFluxSTTService.

    Parameters:
        eager_eot_threshold: EagerEndOfTurn/TurnResumed threshold. Off by default.
            Lower values = more aggressive (faster response, more LLM calls).
            Higher values = more conservative (slower response, fewer LLM calls).
        eot_threshold: End-of-turn confidence required to finish a turn (default 0.7).
        eot_timeout_ms: Time in ms after speech to finish a turn regardless of EOT
            confidence (default 5000).
        keyterm: Keyterms to boost recognition accuracy for specialized terminology.
        min_confidence: Minimum confidence required to create a TranscriptionFrame.
    c                      t         S Nr   r0   r1   r2   <lambda>z DeepgramFluxSTTSettings.<lambda>Y   s    R[ r1   )default_factoryNeager_eot_thresholdc                      t         S rB   rC   r0   r1   r2   rD   z DeepgramFluxSTTSettings.<lambda>Z   s    I r1   eot_thresholdc                      t         S rB   rC   r0   r1   r2   rD   z DeepgramFluxSTTSettings.<lambda>[   s    9 r1   eot_timeout_msc                      t         S rB   rC   r0   r1   r2   rD   z DeepgramFluxSTTSettings.<lambda>\   s    i r1   keytermc                      t         S rB   rC   r0   r1   r2   rD   z DeepgramFluxSTTSettings.<lambda>]   s    Y r1   min_confidence)r'   r(   r)   r*   r   rF   floatr   __annotations__rH   rJ   intrL   listrN   r0   r1   r2   r@   r@   J   s     5:J[4\	1\.3DU.VM54<)+V-2CT-UNC$J*U %6G HGTIH/4EV/WNEDL9,Wr1   r@   c                   |    e Zd ZU dZeZeed<   h dZ G d de      Z	dddddddd	dd
	de
de
dee   dee   dee
   de
dee   dee	   dedee   f fdZ fdZ fdZd>defdZd Zd Zd Zd?dZdee
   fd Zdefd!Zd"edee
ef   f 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%e&df   fd)Z'd* Z(e)	 d@d+e
d,ed-ee*   fd.       Z+d/ Z,d0e-e
ef   defd1Z.d2 Z/d0e-e
ef   fd3Z0d4 Z1d0e-e
ef   fd5Z2d0e-e
ef   fd6Z3d+e
fd7Z4d8e
fd9Z5dee   fd:Z6d+e
d0e-e
ef   fd;Z7d+e
d0e-e
ef   fd<Z8d+e
fd=Z9 xZ:S )ADeepgramFluxSTTServicean  Deepgram Flux speech-to-text service.

    Provides real-time speech recognition using Deepgram's WebSocket API with Flux capabilities.
    Supports configurable models, VAD events, and various audio processing options
    including advanced turn detection and EagerEndOfTurn events for improved conversational AI performance.

    Event handlers available (in addition to WebsocketSTTService events):

    - on_speech_started(service): Deepgram detected start of speech
    - on_utterance_end(service): Deepgram detected end of utterance
    - on_end_of_turn(service): Deepgram detected end of turn (EOT)
    - on_eager_end_of_turn(service): Deepgram predicted end of turn (EagerEOT)
    - on_turn_resumed(service): User resumed speaking after EagerEOT

    Example::

        @stt.event_handler("on_end_of_turn")
        async def on_end_of_turn(service):
            ...
    	_settings>   rL   rH   rJ   rF   c                       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<   g Zeed<   dZee   ed<   g Zeed<   dZee   ed	<   y)
"DeepgramFluxSTTService.InputParamsa  Configuration parameters for Deepgram Flux API.

        .. deprecated:: 0.0.105
            Use ``settings=DeepgramFluxSTTSettings(...)`` instead.

        Parameters:
            eager_eot_threshold: Optional. EagerEndOfTurn/TurnResumed are off by default.
                You can turn them on by setting eager_eot_threshold to a valid value.
                Lower values = more aggressive EagerEndOfTurning (faster response, more LLM calls).
                Higher values = more conservative EagerEndOfTurning (slower response, fewer LLM calls).
            eot_threshold: Optional. End-of-turn confidence required to finish a turn (default 0.7).
                Lower values = turns end sooner (more interruptions, faster responses).
                Higher values = turns end later (fewer interruptions, more complete utterances).
            eot_timeout_ms: Optional. Time in milliseconds after speech to finish a turn
                regardless of EOT confidence (default 5000).
            keyterm: List of keyterms to boost recognition accuracy for specialized terminology.
            mip_opt_out: Optional. Opts out requests from the Deepgram Model Improvement Program
                (default False).
            tag: List of tags to label requests for identification during usage reporting.
            min_confidence: Optional. Minimum confidence required confidence to create a TranscriptionFrame
        NrF   rH   rJ   rL   mip_opt_outtagrN   )r'   r(   r)   r*   rF   r	   rO   rP   rH   rJ   rQ   rL   rR   rX   boolrY   rN   r0   r1   r2   InputParamsrW   z   sc    	, 04Xe_3)-x-(,,&*Xd^*T*..r1   r[   z wss://api.deepgram.com/v2/listenNlinear16T)	urlsample_raterX   modelflux_encodingrY   paramsshould_interruptsettingsapi_keyr]   r^   rX   r_   r`   rY   ra   rb   rc   c       
   	         t        dt        j                  dddg d      }|t        dt         d       ||_        |t        dt                |
s|j
                  |_        |j                  |_        |j                  |_        |j                  xs g |_        |j                  r||j                  }|j                  |_
        |j                  |j                  }|
|j                  |
       t        | 8  d|d|d| || _        || _        |	| _        || _        || _        |xs g | _        d| _        d| _        | j/                  d       | j/                  d	       | j/                  d
       | j/                  d       | j/                  d       t1        j2                         | _        d| _        d| _        d| _        y)a  Initialize the Deepgram Flux STT service.

        Args:
            api_key: Deepgram API key for authentication. Required for API access.
            url: WebSocket URL for the Deepgram Flux API. Defaults to the preview endpoint.
            sample_rate: Audio sample rate in Hz. If None, uses the pipeline
                sample rate.
            mip_opt_out: Opt out of the Deepgram Model Improvement Program.
            model: Deepgram Flux model to use for transcription.

                .. deprecated:: 0.0.105
                    Use ``settings=DeepgramFluxSTTSettings(model=...)`` instead.

            flux_encoding: Audio encoding format required by Flux API. Must be "linear16".
                Raw signed little-endian 16-bit PCM encoding.
            tag: Tags to label requests for identification during usage reporting.
            params: InputParams instance containing detailed API configuration options.

                .. deprecated:: 0.0.105
                    Use ``settings=DeepgramFluxSTTSettings(...)`` instead.

            should_interrupt: Determine whether the bot should be interrupted when Flux detects that the user is speaking.
            settings: Runtime-updatable settings. When provided alongside deprecated
                parameters, ``settings`` values take precedence.
            **kwargs: Additional arguments passed to the parent WebsocketSTTService class.

        Examples:
            Basic usage with default parameters::

                stt = DeepgramFluxSTTService(api_key="your-api-key")

            Advanced usage with custom parameters::

                stt = DeepgramFluxSTTService(
                    api_key="your-api-key",
                    settings=DeepgramFluxSTTSettings(
                        model="flux-general-en",
                        eager_eot_threshold=0.5,
                        eot_threshold=0.8,
                        keyterm=["AI", "machine learning", "neural network"],
                        tag=["production", "voice-agent"],
                    ),
                )
        zflux-general-enN)r_   languagerF   rH   rJ   rL   rN   r_   ra   F)r^   reconnect_on_errorrc   on_start_of_turnon_turn_resumedon_end_of_turnon_eager_end_of_turn	on_updater0   )r@   r   ENr   r_   rF   rH   rJ   rL   rY   rN   rX   apply_updatesuper__init___api_key_url_should_interrupt	_encoding_mip_opt_out_tag_websocket_url_receive_task_register_event_handlerasyncioEvent_connection_established_event_last_stt_time_watchdog_task_user_is_speaking)selfrd   r]   r^   rX   r_   r`   rY   ra   rb   rc   kwargsdefault_settings	__class__s                r2   rp   zDeepgramFluxSTTService.__init__   s   N 3#[[ $
 "7,CWM%*" "8-DE7=7Q7Q 4171E1E .282G2G /+1>>+?R (::#+ **C282G2G /%%1"("4"4K ))(3 	
#$%	
 		
  	!1&'I2	"! 	$$%78$$%67$$%56$$%;<$$[1-4]]_* #"!&r1   c                 r   K   t         |           d{    | j                          d{    y7 7 w)zConnect to WebSocket and start background tasks.

        Establishes the WebSocket connection to the Deepgram Flux API and starts
        the background task for receiving transcription results.
        N)ro   _connect_connect_websocket)r   r   s    r2   r   zDeepgramFluxSTTService._connect  s5      g   %%''' 	!'s   737577c                   K   t         |           d{    	 | j                          d{    d| _        y7 %7 # t        $ r)}| j	                  d| |       d{  7   Y d}~9d}~ww xY w# d| _        w xY ww)zDisconnect from WebSocket and clean up tasks.

        Gracefully disconnects from the Deepgram Flux API, cancels background tasks,
        and cleans up resources to prevent memory leaks.
        NUnknown error occurred: 	error_msg	exception)ro   _disconnect_disconnect_websocket	Exception
push_error
_websocket)r   er   s     r2   r   z"DeepgramFluxSTTService._disconnect(  s      g!###	#,,...
 #DO 	$ / 	Y//.Fqc,JVW/XXX	Y #DOsX   B ;B ? =? 	B ? 	A1A,!A$"A,'A4 ,A11A4 4	A==B duration_secsc                    K   d}d}t        | j                  |z        }d||z  |z  z  }| j                  j                  |       d{    y7 w)zCSend a block of silence of the specified duration (default 500 ms).          N)rQ   r^   r   send)r   r   sample_widthnum_channelsnum_samplessilences         r2   _send_silencez$DeepgramFluxSTTService._send_silence8  sQ     $**]:;[<7,FGoo""7+++s   AAA	Ac                 &  K   | j                   r| j                   j                  t        j                  u rt	        j
                         }| j                  rd| j                  rX|| j                  z
  dkD  rFt        j                  d       | j                          d {    t	        j
                         | _        t        j                  d       d {    | j                   r(| j                   j                  t        j                  u ry y y y 7 q7 =w)N      ?z0Sending silence to Flux to prevent dangling taskg?)r   stater   OPENtime	monotonicr   r}   r   warningr   rz   sleep)r   nows     r2   _watchdog_task_handlerz-DeepgramFluxSTTService._watchdog_task_handler@  s     oo$//"7"75::"E.."C%%$*=*=#H[H[B[^aBaQR((***&*nn&6#--$$$ oo$//"7"75::"Eo"Eo
 + %s*   BDD5DD6D	DDc                 b  K   	 | j                   r'| j                   j                  t        j                  u ry| j                  j                          d| _        t        | j                  dd| j                   i       d{   | _         | j                   j                  j                  j                         D ci c]  \  }}|j                  d      s|| }}}t        j                  |  d| d       | j                   s/| j#                  | j%                  | j&                              | _        | j(                  s$| j#                  | j+                               | _        t        j                  d	       | j                  j-                          d{    t        j                  d
       | j/                  d       d{    y7 Ic c}}w 7 <7 # t0        $ rL}| j3                  d| |       d{  7   d| _         | j/                  d|        d{  7   Y d}~yd}~ww xY ww)a  Establish WebSocket connection to API.

        Creates a WebSocket connection to the Deepgram Flux API using the configured
        URL and authentication headers. Handles connection errors and reports them
        through the event handler system.
        NFAuthorizationzToken )additional_headerszdg-z0: Websocket connection initialized: {"headers": }z7WebSocket connected, waiting for server confirmation...z$Connected to Deepgram Flux Websocketon_connectedr   r   on_connection_error)r   r   r   r   r|   clearr   websocket_connectrw   rq   responseheadersitems
startswithr   debugrx   create_task_receive_task_handler_report_errorr~   r   wait_call_event_handlerr   r   )r   kvr   r   s        r2   r   z)DeepgramFluxSTTService._connect_websocketK  s    "	J4??#8#8EJJ#F..446%*D"$5##$3vdmm_5M#N% DO "&!9!9!A!A!G!G!IAQ\\Z_M`1G  LLD6!RSZR[[]^_ %%%)%5%5..t/A/AB&"
 &&&*&6&6t7R7R7T&U# LLRS4499;;;LL?@**>:::1
" <: 	J//.Fqc,JVW/XXX"DO**+@QCIII	Js   H/2G H/A
G G
:G <GGB;G G-G GG 	H/
G G G 	H, H'9G<:"H'HH'"H/'H,,H/c                 $  K   	 | j                   r,| j                  | j                   d       d{    d| _         | j                  r3| j                  | j                  d       d{    d| _        d| _        | j                  j                          | j                          d{    | j                  rO| j                          d{    t        j                  d       | j                  j                          d{    d| _        | j                  d       d{    y7 7 7 7 b7 -# t        $ r)}| j                  d| |       d{  7   Y d}~Xd}~ww xY w7 D# d| _        | j                  d       d{  7   w xY ww)zClose WebSocket connection and clean up state.

        Closes the WebSocket connection to the Deepgram Flux API and stops all
        metrics collection. Handles disconnection errors gracefully.
        g       @)timeoutNz*Disconnecting from Deepgram Flux WebsocketzError closing websocket: r   on_disconnected)rx   cancel_taskr~   r}   r|   r   stop_all_metricsr   _send_close_streamr   r   closer   r   r   )r   r   s     r2   r   z,DeepgramFluxSTTService._disconnect_websocketv  sc    	>!!&&t'9'93&GGG%)"""&&t':':C&HHH&*#&*#..446'')))--///IJoo++--- #DO**+<===% H I
 * 0- 	Z//.Gs,KWX/YYY	Z > #DO**+<===s   F,D3 D)7D3 (D+)?D3 (D-)#D3 D/6D3 D1D3 F#E($F)D3 +D3 -D3 /D3 1D3 3	E%<E EE E*  E%%E* (F*FF	FFreturnc                 4  K   	 | j                   rPt        j                  d       ddi}| j                   j                  t	        j
                  |             d{    yy7 # t        $ r)}| j                  d| |       d{  7   Y d}~yd}~ww xY ww)zSends a CloseStream control message to the Deepgram Flux WebSocket API.

        This signals to the server that no more audio data will be sent.
        z,Sending CloseStream message to Deepgram FluxtypeCloseStreamNzError sending closeStream: r   )r   r   r   r   jsondumpsr   r   )r   messager   s      r2   r   z)DeepgramFluxSTTService._send_close_stream  s     
	\KL!=1oo**4::g+>???  @ 	\//.I!,MYZ/[[[	\sM   BAA# A!A# B!A# #	B,BBBBBBfieldsc                   K   ddi}d|v r| j                   j                  |d<   i }d|v r| j                   j                  |d<   d|v r| j                   j                  |d<   d|v r| j                   j                  |d<   |r||d<   t        j                  |  d	|        | j                  j                  t        j                  |             d
{    y
7 w)a/  Send a Configure control message to update settings mid-stream.

        Builds a Configure JSON message containing only the fields that changed
        and sends it over the existing WebSocket connection.

        Args:
            fields: Set of changed field names to include in the message.
        r   	ConfigurerL   keytermsrH   rF   rJ   
thresholdsz: sending Configure message: N)rU   rL   rH   rF   rJ   r   r   r   r   r   r   )r   r   r   r   s       r2   _send_configurez&DeepgramFluxSTTService._send_configure  s      $*;"7"&.."8"8GJ%'
f$*...*F*FJ' F*040R0RJ,-v%+/>>+H+HJ'($.GL!v:7)DEoo""4::g#6777s   CCCCc                      y)zCheck if this service can generate processing metrics.

        Returns:
            True, as Deepgram service supports metrics generation.
        Tr0   r   s    r2   can_generate_metricsz+DeepgramFluxSTTService.can_generate_metrics  s     r1   deltac                 z  K   t         |   |       d{   }|s|S |j                         | j                  z  }|rK| j                  r?| j                  j
                  t        j                  u r| j                  |       d{    | j                  |j                         | j                  z
         |S 7 7 4w)a  Apply a settings delta.

        Configure-able fields (keyterm, eot_threshold, eager_eot_threshold,
        eot_timeout_ms) are sent to Deepgram via a Configure WebSocket message.
        Other fields are stored but cannot be applied to the active connection.
        N)
ro   _update_settingskeys_CONFIGURE_FIELDSr   r   r   r   r    _warn_unhandled_updated_settings)r   r   changedconfigure_fieldsr   s       r2   r   z'DeepgramFluxSTTService._update_settings  s      077N"<<>D,B,BBDOO4I4IUZZ4W&&'7888--gllnt?U?U.UV 8 9s"   B;B7A-B;B93B;9B;framec                   K   t         |   |       d{    d| j                  j                   d| j                   d| j
                   g}| j                  j                  (|j                  d| j                  j                          | j                  j                  (|j                  d| j                  j                          | j                  j                  (|j                  d| j                  j                          | j                  5|j                  dt        | j                        j                                 | j                  j                  D ]  }|j                  t        d	|i               | j                  D ]  }|j                  t        d
|i               | j                    ddj#                  |       | _        | j'                          d{    y7 7 w)a?  Start the Deepgram Flux STT service.

        Initializes the service by constructing the WebSocket URL with all configured
        parameters and establishing the connection to begin transcription processing.

        Args:
            frame: The start frame containing initialization parameters and metadata.
        Nzmodel=zsample_rate=z	encoding=zeager_eot_threshold=zeot_threshold=zeot_timeout_ms=zmip_opt_out=rL   rY   ?&)ro   startrU   r_   r^   rt   rF   appendrH   rJ   ru   strlowerrL   r
   rv   rr   joinrw   r   )r   r   
url_paramsrL   	tag_valuer   s        r2   r   zDeepgramFluxSTTService.start  s     gmE""" T^^))*+4++,-'(

 >>--9 4T^^5W5W4XYZ>>''3t~~/K/K.LMN>>((40M0M/NOP(S1B1B-C-I-I-K,LMN ~~-- 	?GiG(<=>	?  	=Ii	(:;<	= "&1SXXj-A,BCmmo; 	#: 	s"   G3G.GG3(G1)G31G3c                 t   K   t         |   |       d{    | j                          d{    y7 7 w)z]Stop the Deepgram Flux STT service.

        Args:
            frame: The end frame.
        N)ro   stopr   r   r   r   s     r2   r   zDeepgramFluxSTTService.stop  s6      gl5!!!    	"    848688c                 t   K   t         |   |       d{    | j                          d{    y7 7 w)zbCancel the Deepgram Flux STT service.

        Args:
            frame: The cancel frame.
        N)ro   cancelr   r   s     r2   r   zDeepgramFluxSTTService.cancel  s6      gnU###    	$ r   audioc                   K   | j                   sy	 t        j                         | _        | j	                  || j
                         d{    d y7 
# t        $ r}t        d|        Y d}~yd}~ww xY ww)a  Send audio data to Deepgram Flux for transcription.

        Transmits raw audio bytes to the Deepgram Flux API for real-time speech
        recognition. Transcription results are received asynchronously through
        WebSocket callbacks and processed in the background.

        Args:
            audio: Raw audio bytes in linear16 format (signed little-endian 16-bit PCM).

        Yields:
            Frame: None (transcription results are delivered via WebSocket callbacks
                rather than as return values from this method).

        Raises:
            Exception: If the WebSocket connection is not established or if there
                are issues sending the audio data.
        Nr   )error)r   r   r   r}   send_with_retryr   r   r   )r   r   r   s      r2   run_sttzDeepgramFluxSTTService.run_stt  st     $ 	"&.."2D&&ud.@.@AAA
 
 B 	%=aS#ABB	s@   A>8A 	A
A A>A 	A;A61A>6A;;A>c                 @   K   | j                          d{    y7 w)z-Start TTFB and processing metrics collection.N)start_processing_metricsr   s    r2   start_metricsz$DeepgramFluxSTTService.start_metrics/  s      ++---s   
transcriptis_finalrf   c                    K   yw)z+Handle a transcription result with tracing.Nr0   )r   r   r   rf   s       r2   _handle_transcriptionz,DeepgramFluxSTTService._handle_transcription9  s     
 	s   c                 H    | j                   r| j                   S t        d      )aQ  Get the current WebSocket connection.

        Returns the active WebSocket connection instance, raising an exception
        if no connection is currently established.

        Returns:
            The active WebSocket connection instance.

        Raises:
            Exception: If no WebSocket connection is currently active.
        zWebsocket not connected)r   r   r   s    r2   _get_websocketz%DeepgramFluxSTTService._get_websocket@  s!     ????"122r1   datac                     t        |t              st        j                  d       yd|vrt        j                  d       yy)a3  Validate basic message structure from Deepgram Flux.

        Ensures the received message has the expected structure before processing.

        Args:
            data: The parsed JSON message data to validate.

        Returns:
            True if the message structure is valid, False otherwise.
        zMessage is not a dictionaryFr   zMessage missing 'type' fieldT)
isinstancedictr   r   )r   r   s     r2   _validate_messagez(DeepgramFluxSTTService._validate_messageP  s9     $%NN89NN9:r1   c                   K   | j                         2 3 d{   }t        |t              r0	 t        j                  |      }| j                  |       d{    It        j                  dt        |              k7 f7 )# t        j                  $ r"}t        j                  d|        Y d}~d}~wt        $ r%}| j                  d| |       d{  7    d}~ww xY w6 yw)a  Receive and process messages from WebSocket.

        Continuously receives messages from the Deepgram Flux WebSocket connection
        and processes various message types including connection status, transcription
        results, turn information, and error conditions. Handles different event types
        such as StartOfTurn, EndOfTurn, EagerEndOfTurn, and Update events.
        NzFailed to decode JSON message: r   r   zReceived non-string message: )r   r   r   r   loads_handle_messageJSONDecodeErrorr   r   r   r   r   r   )r   r   r   r   s       r2   _receive_messagesz(DeepgramFluxSTTService._receive_messagese  s      "002 	P 	P''3'
::g.D..t444 !>tG}oNO	P 5++ LL#B1#!FG  //6Nqc4R^_/``` 3sr   C(C&A>C&C()BB B#C(>C& BC#B2-C(2C#>CCCC##C(c                 ,  K   | j                  |      sy|j                  d      }	 t        |      }|xt        j                  k(  r | j                          d{    yxt        j                  k(  r | j                  |       d{    yxt        j                  k(  r | j                  |       d{    yxt        j                  k(  r t	        j                  |  d|        yt        j                  k(  ra|j                  dd      }|j                  dd      }d	| d
| }t	        j                  |  d|        | j!                  |       d{    yy# t        $ r t	        j
                  d|xs d        Y yw xY w7 07 7 7 9w)a  Handle a parsed WebSocket message from Deepgram Flux.

        Routes messages to appropriate handlers based on their type. Validates
        message structure before processing.

        Args:
            data: The parsed JSON message data from the WebSocket.
        Nr   zUnhandled message type: unknownz: Configure accepted: 
error_codedescriptionzno descriptionzConfigure rejected: [z] z: )r   )r   getr!   
ValueErrorr   r   r+   _handle_connection_establishedr,   _handle_fatal_errorr-   _handle_turn_infor.   infor/   r   r   )r   r   message_typeflux_message_typer  r  r   s          r2   r   z&DeepgramFluxSTTService._handle_message}  sg     %%d+xx'	 / =
  22299;;;444..t444***,,T222222tf$:4&AB 22!XXlI>
"hh}6FG3J<r+O	$r)56oo	o::: 3  	LL3L4MI3NOP	 <42 ;sj   $FE (FF
-FF	-F6F7B!FFF%FFFFFFFc                 j   K   t        j                  d       | j                  j                          yw)zHandle successful connection establishment to Deepgram Flux.

        This event is fired when the WebSocket connection to Deepgram Flux
        is successfully established and ready to receive audio data for
        transcription processing.
        z)Connected to Flux - ready to stream audioN)r   r  r|   setr   s    r2   r	  z5DeepgramFluxSTTService._handle_connection_established  s'      	?@**..0s   13c                 x   K   |j                  dd      }d| }t        j                  |       t        |      w)a  Handle fatal error messages from Deepgram Flux.

        Fatal errors indicate unrecoverable issues with the connection or
        configuration that require intervention. These errors will cause
        the connection to be terminated.

        Args:
            data: The error message data containing error details.

        Raises:
            Exception: Always raises to trigger error handling in the parent service.
        r   zUnknown errorzFatal error: )r  r   r   r   )r   r   r   deepgram_errors       r2   r
  z*DeepgramFluxSTTService._handle_fatal_error  s;      HHWo6	(4^$''s   8:c                   K   |j                  d      }|j                  dd      }	 t        |      }|xt        j
                  k(  r | j                  |       d{    yxt        j                  k(  r | j                  |       d{    yxt        j                  k(  r | j                  ||       d{    yxt        j                  k(  r | j                  ||       d{    yt        j                  k(  r| j                  |       d{    yy# t        $ r t        j                  d|        Y yw xY w7 7 7 7 _7 5w)an  Handle TurnInfo events from Deepgram Flux.

        TurnInfo messages contain various turn-based events that indicate
        the state of speech processing, including turn boundaries, interim
        results, and turn finalization events.

        Args:
            data: The TurnInfo message data containing event type, transcript and some extra metadata.
        eventr    zUnhandled TurnInfo event: N)r  r4   r  r   r   r:   _handle_start_of_turnr;   _handle_turn_resumedr<   _handle_end_of_turnr=   _handle_eager_end_of_turnr>   _handle_update)r   r   r  r   flux_event_types        r2   r  z(DeepgramFluxSTTService._handle_turn_info  s     !XXlB/
	+E2O
 ,,,00<<<+++//666***..z4@@@00044ZFFF%%))*555 &  	LL5eW=>	 =6@F5s{   $ED )EE-E	E
.E8E9.E'E(+EE	E!D>;E=D>>EEEE	Ec                 p  K   t        j                  d       d| _        | j                  t               d{    | j
                  r| j                          d{    | j                          d{    | j                  d|       d{    |rt        j                  d|        yy7 v7 T7 >7 &w)a\  Handle StartOfTurn events from Deepgram Flux.

        StartOfTurn events are fired when Deepgram Flux detects the beginning
        of a new speaking turn. This triggers bot interruption to stop any
        ongoing speech synthesis and signals the start of user speech detection.

        The service will:
        - Send a BotInterruptionFrame upstream to stop bot speech
        - Send a UserStartedSpeakingFrame downstream to notify other components
        - Start metrics collection for measuring response times

        Args:
            transcript: maybe the first few words of the turn.
        zUser started speakingTNrh   zStart of turn transcript: )
r   r   r   broadcast_framer   rs   broadcast_interruptionr   r   tracer   r   s     r2   r  z,DeepgramFluxSTTService._handle_start_of_turn  s      	,-!%""#;<<<!!--///  """&&'9:FFFLL5j\BC  	=/"FsE   5B6B.#B6B0B63B24B6B4!B60B62B64B6r  c                 r   K   t        j                  d|        | j                  d       d{    y7 w)am  Handle TurnResumed events from Deepgram Flux.

        TurnResumed events indicate that speech has resumed after a brief pause
        within the same turn. This is primarily used for logging and debugging
        purposes and doesn't trigger any significant processing changes.

        Args:
            event: The event type string for logging purposes.
        zReceived event TurnResumed: ri   Nr   r  r   )r   r  s     r2   r  z+DeepgramFluxSTTService._handle_turn_resumed  s1      	3E7;<&&'8999s   -757c                    |j                  d      }|rt        |t              sy|D cg c]9  }t        |j                  d      t        t        f      s)|j                  d      ; }}|syt        |      t        |      z  S c c}w )zwCalculate the average confidence from transcript data.

        Return None if the data is missing or invalid.
        wordsN
confidence)r  r   rR   rO   rQ   sumlen)r   transcript_datar$  wconfidencess        r2   _calculate_average_confidencez4DeepgramFluxSTTService._calculate_average_confidence  s      ##G,Jud3).
$%*QUU<=PSXZ]R^2_AEE,
 
 ;#k"222
s   *BBc           
        K   t        j                  d       d| _        | j                  |      }| j                  j
                  r|| j                  j
                  kD  rO| j                  t        || j                  t               | j                  j                  |d             d{    nt        j                  d|        | j                  |d| j                  j                         d{    | j                          d{    | j                  t               d{    | j!                  d|       d{    y7 7 V7 @7 %7 w)a  Handle EndOfTurn events from Deepgram Flux.

        EndOfTurn events are fired when Deepgram Flux determines that a speaking
        turn has concluded, either due to sufficient silence or end-of-turn
        confidence thresholds being met. This provides the final transcript
        for the completed turn.

        The service will:
        - Create and send a final TranscriptionFrame with the complete transcript
        - Trigger transcription handling with tracing for metrics
        - Stop processing metrics collection
        - Send a UserStoppedSpeakingFrame to signal turn completion

        Args:
            transcript: The final transcript text for the completed turn.
            data: The TurnInfo message data containing event type, transcript and some extra metadata.
        zUser stopped speakingFT)result	finalizedNz9Transcription confidence below min_confidence threshold: rj   )r   r   r   r+  rU   rN   
push_framer   _user_idr   rf   r   r   stop_processing_metricsr  r   r   )r   r   r   average_confidences       r2   r  z*DeepgramFluxSTTService._handle_end_of_turn  s&    $ 	,-!& "??E~~,,0BT^^EbEb0b //"MM$&NN++"	 	 	 NNKL^K_` ((T4>>;R;RSSS**,,,""#;<<<&&'7DDD%	 	T,<Ds[   B&E(E)AE0E1EE		E%E&E?E EE	EEEc           	        K   t        j                  d|        | j                  t        || j                  t               | j                  j                  |             d{    | j                  d|       d{    y7 7 w)a  Handle EagerEndOfTurn events from Deepgram Flux.

        EagerEndOfTurn events are fired when the end-of-turn confidence reaches the
        EagerEndOfTurn threshold but hasn't yet reached the full end-of-turn threshold.
        These provide interim transcripts that can be used for faster response
        generation while still allowing the user to continue speaking.

        EagerEndOfTurn events enable more responsive conversational AI by allowing
        the LLM to start processing likely final transcripts before the turn
        is definitively ended.

        Args:
            transcript: The interim transcript text that triggered the EagerEndOfTurn event.
            data: The TurnInfo message data containing event type, transcript and some extra metadata.
        zEagerEndOfTurn - )r-  Nrk   )	r   r  r/  r   r0  r   rU   rf   r   )r   r   r   s      r2   r  z0DeepgramFluxSTTService._handle_eager_end_of_turnC  s       	(56$ oo% "''
 	
 	
 &&'=zJJJ	
 	Ks$   A!B#B$B=B>BBc                 z   K   |r3t        j                  d|        | j                  d|       d{    yy7 w)a2  Handle Update events from Deepgram Flux.

        Update events provide incremental transcript updates during an ongoing
        turn. These events allow for real-time display of transcription progress
        and can be used to provide visual feedback to users about what's being
        recognized.

        The service stops TTFB (Time To First Byte) metrics when the first
        substantial update is received, indicating successful processing start.

        Args:
            transcript: The current partial transcript text for the ongoing turn.
        zUpdate event: rl   Nr"  r   s     r2   r  z%DeepgramFluxSTTService._handle_updatep  sA      LL>*67 **;
CCC  Ds   0;9;)r   )r   NrB   );r'   r(   r)   r*   r@   SettingsrP   r   r   r[   r   r	   rQ   rZ   rR   rp   r   r   rO   r   r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r   bytesr   r   r   r   r   r   r   r   r   r   r  r   r	  r
  r  r  r  r+  r  r  r  __classcell__)r   s   @r2   rT   rT   `   s   * 'H&&]/i /F 6%)&*#'"(,!%6:C' C' 	C'
 c]C' d^C' }C' C' d^C' %C' C' 23C'J(# , ,	%)JV>:\8CH 86d ,C SRUX (& &P! !!+ !5 ^E4K-H <. NR)-9A(9K 3 d38n  *P0";$sCx. ";H	1(d38n (&6DcN 6>Dc D2: :3 3 -EC -EtCH~ -E^+K# +KT#s(^ +KZDs Dr1   rT   )9r*   rz   r   r   dataclassesr   r   enumr   typingr   r   r   r	   urllib.parser
   logurur   pydanticr   pipecat.frames.framesr   r   r   r   r   r   r   r   r   pipecat.services.settingsr   r   r   r   pipecat.services.stt_servicer   pipecat.transcriptions.languager   pipecat.utils.timer   (pipecat.utils.tracing.service_decoratorsr   websockets.asyncio.clientr   r   websockets.protocolr   ModuleNotFoundErrorr   r   r   r   r!   r4   r@   rT   r0   r1   r2   <module>rG     s    ;    (  6 6 "  
 
 
 ` _ < 4 / ?,F)+c4 +C  Xk X X*fD0 fDq  ,FLL;qc"#FLLab
&qc*
++,s   6B6 6C2;2C--C2