
    qiVq                        d Z ddl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	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mZmZmZmZmZmZ ddl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-m.Z. ddl/m0Z0 ddl1m2Z2 	 ddl3Z3ddl4m5Z6 ddl7m8Z8 de-dee=   fdZ> G d d      Z?e G d de%             Z@ G d de+      ZAy# e9$ r7Z: ejv                  de:         ejv                  d        e<de:       dZ:[:ww xY w)zGladia Speech-to-Text (STT) service implementation.

This module provides a Speech-to-Text service using Gladia's real-time WebSocket API,
supporting multiple languages, custom vocabulary, and various audio processing options.
    N)	dataclassfield)AnyAsyncGeneratorLiteralOptional)logger)version)	CancelFrameEndFrameFrameInterimTranscriptionFrame
StartFrameTranscriptionFrameTranslationFrameUserStartedSpeakingFrameUserStoppedSpeakingFrame)GladiaInputParamsLanguageConfigMessagesConfigPreProcessingConfigRealtimeProcessingConfig)	NOT_GIVENSTTSettings	_NotGiven_warn_deprecated_param)GLADIA_TTFS_P99)WebsocketSTTService)Languageresolve_language)time_now_iso8601)
traced_stt)connect)StatezException: zEIn order to use Gladia, you need to `pip install pipecat-ai[gladia]`.zMissing module: languagereturnc                 @   i t         j                  dt         j                  dt         j                  dt         j                  dt         j
                  dt         j                  dt         j                  dt         j                  dt         j                  d	t         j                  d
t         j                  dt         j                  dt         j                  dt         j                  dt         j                  dt         j                   dt         j"                  di t         j$                  dt         j&                  dt         j(                  dt         j*                  dt         j,                  dt         j.                  dt         j0                  dt         j2                  dt         j4                  dt         j6                  dt         j8                  dt         j:                  dt         j<                  dt         j>                  dt         j@                  d t         jB                  d!t         jD                  d"i t         jF                  d#t         jH                  d$t         jJ                  d%t         jL                  d&t         jN                  d't         jP                  d(t         jR                  d)t         jT                  d*t         jV                  d+t         jX                  d,t         jZ                  d-t         j\                  d.t         j^                  d/t         j`                  d0t         jb                  d1t         jd                  d2t         jf                  d3i t         jh                  d4t         jj                  d5t         jl                  d6t         jn                  d7t         jp                  d8t         jr                  d9t         jt                  d:t         jv                  d;t         jx                  d<t         jz                  d=t         j|                  d>t         j~                  d?t         j                  d@t         j                  dAt         j                  dBt         j                  dCt         j                  dDi t         j                  dEt         j                  dFt         j                  dGt         j                  dHt         j                  dIt         j                  dJt         j                  dKt         j                  dLt         j                  dMt         j                  dNt         j                  dOt         j                  dPt         j                  dQt         j                  dRt         j                  dSt         j                  dTt         j                  dUt         j                  dVt         j                  dWt         j                  dXt         j                  dYt         j                  dZt         j                  d[t         j                  d\t         j                  d]t         j                  d^t         j                  d_t         j                  d`t         j                  dat         j                  dbt         j                  dci}t        | |dde      S )fzConvert a Language enum to Gladia's language code format.

    Args:
        language: The Language enum value to convert.

    Returns:
        The Gladia language code string or None if not supported.
    afamarasazbabebgbnbobrbscacscydadeeleneseteufafifofrglguhahawhehihrhthuhyidisitjajvkakkkmknkolalblnloltlvmgmimkmlmnmrmsmtmymrnenlnnnoocpaplpsptrorusasdsiskslsnsosqsrsusvswtatetgthtktltrttukuruzviyiyozhT)use_base_code)er   AFAMARASAZBABEBGBNBOBRBSCACSCYDADEELENESETEUFAFIFOFRGLGUHAHAWHEHIHRHTHUHYIDISITJAJVKAKKKMKNKOLALBLNLOLTLVMGMIMKMLMNMRMSMTMY_MRNENLNNNOOCPAPLPSPTRORUSASDSISKSLSNSOSQSRSUSVSWTATETGTHTKTLTRTTUKURUZVIYIYOZHr    )r%   LANGUAGE_MAPs     M/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/services/gladia/stt.pylanguage_to_gladia_languager   ;   s   dTdTd 	Td 	T	d
 	Td 	Td 	Td 	Td 	Td 	Td 	Td 	Td 	Td 	Td 	Td  	T!d" 	T#d$ 	T%d& 	T'd( 	T)d* 	T+d, 	T-d. 	T/d0 	T1d2 	T3d4 	T5d6 	T7d8 	T9d: 	T;d< 	e=d> 	T?d@ 	TAdB 	TCdD 	TEdF 	TGdH 	TIdJ 	TKdL 	TMdN 	TOdP 	TQdR 	TSdT 	TUdV 	TWdX 	TYdZ 	T[d\ 	T]d^ 	T_d` 	Tadb 	Tcdd 	Tedf 	Tgdh 	Tidj 	Tkdl 	Tmdn 	Todp 	Tqdr 	Tsdt 	Tudv 	Twdx 	Tydz 	{d| 	T}d~ 	Td@ 	TAdB 	TCdD 	TEdF 	TGdH 	TIdJ 	TKdL 	TMdN 	TOdP 	TQdR 	TSdT 	TUdV 	TWdX 	TYdZ 	T[d\ 	T]d^ 	T_d` 	Tadb 	Tcdd 	Tedf 	Tgdh 	Tidj 	Tkdl 	TTTTTTTTTTTTTTGdLL Hl$GG    c                       e Zd ZdZddZy)_InputParamsDescriptorz?Descriptor for backward compatibility with deprecation warning.Nc                     t        j                         5  t        j                  d       t        j                  dt        d       d d d        t
        S # 1 sw Y   t
        S xY w)NalwayszGladiaSTTService.InputParams is deprecated and will be removed in a future version. Import and use GladiaInputParams directly instead.   
stacklevel)warningscatch_warningssimplefilterwarnDeprecationWarningr   )selfobjobjtypes      r   __get__z_InputParamsDescriptor.__get__   sT    $$& 	!!(+MME"		 ! 	 ! s   2AA#N)__name__
__module____qualname____doc__r   r   r   r   r      s
    I	!r   r   c                   l   e Zd ZU dZ ed       Zedz  ez  ed<    ed       Z	e
eef   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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dz  ez  ed<   y)GladiaSTTSettingsa[  Settings for GladiaSTTService.

    Parameters:
        language_config: Language detection and handling configuration.
        custom_metadata: Additional metadata to include with requests.
        endpointing: Silence duration in seconds to mark end of speech.
        maximum_duration_without_endpointing: Maximum utterance duration without silence.
        pre_processing: Audio pre-processing options.
        realtime_processing: Real-time processing features.
        messages_config: WebSocket message filtering options.
        enable_vad: Enable VAD to trigger end of utterance detection.
    c                      t         S r  r   r  r   r   <lambda>zGladiaSTTSettings.<lambda>       W` r   )default_factoryNlanguage_configc                      t         S r  r  r  r   r   r  zGladiaSTTSettings.<lambda>   r  r   custom_metadatac                      t         S r  r  r  r   r   r  zGladiaSTTSettings.<lambda>   s    ) r   endpointingc                      t         S r  r  r  r   r   r  zGladiaSTTSettings.<lambda>       	 r   $maximum_duration_without_endpointingc                      t         S r  r  r  r   r   r  zGladiaSTTSettings.<lambda>   r  r   pre_processingc                      t         S r  r  r  r   r   r  zGladiaSTTSettings.<lambda>   r  r   realtime_processingc                      t         S r  r  r  r   r   r  zGladiaSTTSettings.<lambda>   r  r   messages_configc                      t         S r  r  r  r   r   r  zGladiaSTTSettings.<lambda>   s    	 r   
enable_vad)r  r  r  r  r   r  r   r   __annotations__r  dictstrr   r  floatr  intr  r   r  r   r  r   r  boolr  r   r   r
  r
     s     :?O`9aO^d*Y6a9>O`9aOT#s(^d*Y6a,1BS,TK	)TCH)D(#*y*@  >C)>N'$.:  HM)H1D89D  :?O`9aO^d*Y6a*/@Q*RJti'Rr   r
  c                       e Zd ZU dZeZeed<    e       Zddddddddddd	de	d
de
ded   dz  de
de
dededee   dee   dee
   dee   dededee   dee   f fdZd ZdefdZdedee
   fdZdee
ef   fd Zd!ef 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 de!e"df   fd(Z# fd)Z$ fd*Z%d+ Z&d, Z'dee
ef   fd-Z(e)	 d:d.e
d/edee
   fd0       Z*d1 Z+d2 Z,d'e fd3Z-d4 Z.d5 Z/d6 Z0d7 Z1d8e fd9Z2 xZ3S );GladiaSTTServicea  Speech-to-Text service using Gladia's API.

    This service connects to Gladia's WebSocket API for real-time transcription
    with support for multiple languages, custom vocabulary, and various processing options.
    Provides automatic reconnection, audio buffering, and comprehensive error handling.

    For complete API documentation, see: https://docs.gladia.io/api-reference/v2/live/init

    .. deprecated:: 0.0.62
        Use :class:`~pipecat.services.gladia.config.GladiaInputParams` directly instead.
    	_settingsNzhttps://api.gladia.io/v2/livewav/pcm      i  @T)regionurlencoding	bit_depthchannels
confidencesample_ratemodelparamsmax_buffer_sizeshould_interruptsettingsttfs_p99_latencyapi_keyr,  )zus-westzeu-westr-  r.  r/  r0  r1  r2  r3  r4  r5  r6  r7  r8  c                   |rNt        j                         5  t        j                  d       t        j                  dt        d       ddd       t        dddddddddd	
      }|	t        d
t
        d
       |	|_        |
t        dt
               |
j                  Nt        j                         5  t        j                  d       t        j                  dt        d       ddd       |s|
j                  |
j                  }|
j                  |
j                  }|
j                  |
j                  }|
j                  |_        |
j                  |_        |
j                  |_        |
j                  |_        |
j                   |_        |
j"                  |_        |
j$                  |_        |
j&                  r|
j&                  |_        n<|
j                  r0| j)                  |
j                        }|rt+        |gd      |_        ||j-                  |       t/        | `  d||dd|d| || _        || _        || _        d| _        || _        || _        || _        d| _         d| _!        d| _"        tG               | _$        d| _%        || _&        tO        jP                         | _)        d| _*        || _+        y# 1 sw Y   uxY w# 1 sw Y   xY w)a  Initialize the Gladia STT service.

        Args:
            api_key: Gladia API key for authentication.
            region: Region used to process audio. eu-west or us-west. Defaults to eu-west.
            url: Gladia API URL. Defaults to "https://api.gladia.io/v2/live".
            encoding: Audio encoding format. Defaults to ``"wav/pcm"``.
            bit_depth: Audio bit depth. Defaults to 16.
            channels: Number of audio channels. Defaults to 1.
            confidence: Minimum confidence threshold for transcriptions (0.0-1.0).

                .. deprecated:: 0.0.86
                    The 'confidence' parameter is deprecated and will be removed in a future version.
                    No confidence threshold is applied.

            sample_rate: Audio sample rate in Hz. If None, uses service default.
            model: Model to use for transcription.

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

            params: Additional configuration parameters for Gladia service.

                .. deprecated:: 0.0.105
                    Use ``settings=GladiaSTTSettings(...)`` for runtime-updatable
                    fields and direct init parameters for encoding/bit_depth/channels.

            max_buffer_size: Maximum size of audio buffer in bytes. Defaults to 20MB.
            should_interrupt: Determine whether the bot should be interrupted when
                Gladia VAD detects user speech. Defaults to True.
            settings: Runtime-updatable settings. When provided alongside deprecated
                parameters, ``settings`` values take precedence.
            ttfs_p99_latency: P99 latency from speech end to final transcript in seconds.
                Override for your deployment. See https://github.com/pipecat-ai/stt-benchmark
            **kwargs: Additional arguments passed to the STTService parent class.
        r   zuThe 'confidence' parameter is deprecated and will be removed in a future version. No confidence threshold is applied.r   r   Nz	solaria-1   F)
r3  r%   r  r  r  r  r  r  r  r  r3  r4  znThe 'language' parameter is deprecated and will be removed in a future version. Use 'language_config' instead.)	languagescode_switching   )r2  r8  keepalive_timeoutkeepalive_intervalr7  r   r  ),r   r   r   r   r   r
  r   r3  r%   r.  r/  r0  r  r  r  r  r  r  r  r  language_to_service_languager   apply_updatesuper__init___api_key_region_url_receive_task	_encoding
_bit_depth	_channels_session_url_session_id_connection_active	bytearray_audio_buffer_bytes_sent_max_buffer_sizeasyncioLock_buffer_lock_is_speaking_should_interrupt)r   r9  r,  r-  r.  r/  r0  r1  r2  r3  r4  r5  r6  r7  r8  kwargsdefault_settingslanguage_code	__class__s                     r   rD  zGladiaSTTService.__init__   s   n ((* %%h/:& 	 -  12 $ 
 "7,=wG%*" "8->?*,,. ))(3MMB*#$	 ??.%H##/ & 0 0I??.%H393I3I 0/5/A/A ,?? !E 392G2G /7=7Q7Q 4393I3I 0.4.?.? +))7=7M7M$4__$($E$Efoo$VM$;I'4oe<(8
 ))(3 	
#-  %	
 	
  	! "#! !"' '[ /#LLN "!1O @ s   2J=42K
=K
Kc                 :    | j                    d| j                   dS )Nz [])namerM  r   s    r   __str__zGladiaSTTService.__str__  s     ))Bt//022r   r&   c                      y)zCheck if the service can generate performance metrics.

        Returns:
            True, indicating this service supports metrics generation.
        Tr  r_  s    r   can_generate_metricsz%GladiaSTTService.can_generate_metrics  s     r   r%   c                     t        |      S )zConvert pipecat Language enum to Gladia's language code.

        Args:
            language: The Language enum value to convert.

        Returns:
            The Gladia language code string or None if not supported.
        )r   )r   r%   s     r   rA  z-GladiaSTTService.language_to_service_language  s     +844r   c                    | j                   }| j                  xs d| j                  xs d| j                  | j                  xs d|j
                  d}t        |j                  xs i       |d<   t               |d   d<   |j                  |j                  |d<   |j                  |j                  |d<   |j                  r|j                  j                  d	
      |d<   |j                  r|j                  j                  d	
      |d<   |j                  r|j                  j                  d	
      |d<   |j                  r|j                  j                  d	
      |d<   |S )Nr)  r*  r+  )r.  r/  r2  r0  r3  r  pipecatr  r  T)exclude_noner  r  r  r  )r(  rI  rJ  r2  rK  r3  r!  r  pipecat_versionr  r  r  
model_dumpr  r  r  )r   sr7  s      r   _prepare_settingsz"GladiaSTTService._prepare_settings  sc   NN 3).B+++!WW
 '+1+<+<+B&C"#1@1B"#I. ==$&'mmH]#11=66 ;<
 *+*;*;*F*FTX*F*YH&' )*)9)9)D)DRV)D)WH%&   ./.C.C.N.N\`.N.aH*+ *+*;*;*F*FTX*F*YH&'r   framec                 t   K   t         |   |       d{    | j                          d{    y7 7 w)zStart the Gladia STT websocket connection.

        Args:
            frame: The start frame triggering service startup.
        N)rC  start_connectr   rk  r[  s     r   rm  zGladiaSTTService.start  s3      gmE"""mmo 	#   848688deltac                 l   K   t         |   |       d{   }|s|S | j                  |       |S 7 w)zApply settings delta.

        Settings are stored but not applied to the active session.

        Args:
            delta: A settings delta.

        Returns:
            Dict mapping changed field names to their previous values.
        N)rC  _update_settings _warn_unhandled_updated_settings)r   rq  changedr[  s      r   rs  z!GladiaSTTService._update_settings  s=      077N 	--g6 8s   424c                    K   t         |   |       d{    | j                          d{    | j                          d{    y7 57 7 	w)zStop the Gladia STT websocket connection.

        Args:
            frame: The end frame triggering service shutdown.
        N)rC  stop_send_stop_recording_disconnectro  s     r   rw  zGladiaSTTService.stop  sL      gl5!!!'')))    	") s1   AAAAAAAAAc                 t   K   t         |   |       d{    | j                          d{    y7 7 w)zCancel the Gladia STT websocket connection.

        Args:
            frame: The cancel frame triggering service cancellation.
        N)rC  cancelry  ro  s     r   r{  zGladiaSTTService.cancel  s6      gnU###    	$ rp  audioc                l  K   | j                          d{    | j                  4 d{    | j                  j                  |       t	        | j                        | j
                  kD  rot	        | j                        | j
                  z
  }| j                  |d | _        t        d| j                  |z
        | _        t        j                  |  d| d       ddd      d{    | j                  rL| j                  r@| j                  j                  t        j                  u r	 | j                  |       d{    d y7 47 "7 h# 1 d{  7  sw Y   xxY w7 '# t         j"                  j$                  $ r+}t        j                  |  d|        d| _
        Y d}~hd}~ww xY ww)zRun speech-to-text on audio data.

        Args:
            audio: Raw audio bytes to transcribe.

        Yields:
            None (processing is handled asynchronously via WebSocket).
        Nr   z) Audio buffer exceeded max size, trimmed z bytesz- Websocket closed while sending audio chunk: F)start_processing_metricsrU  rP  extendlenrR  maxrQ  r	   warningrN  
_websocketstater$   OPEN_send_audio
websockets
exceptionsConnectionClosed)r   r|  	trim_sizees       r   run_sttzGladiaSTTService.run_stt  s     ++--- $$ 	d 	d%%e,4%%&)>)>> 2 23d6K6KK	%)%7%7	
%C"#&q$*:*:Y*F#G $'PQZP[[abc	d 	d ""t4??;P;PTYT^T^;^0&&u---
 
) 	.	d 	d 	d 	d 	d .((99 0$'TUVTWXY*/''0s   F4E
F4EF4B-EF4'E(AF4+E) ?E' E) F4F4F4E$EE$ F4'E) )F1!F,'F4,F11F4c                   K   | j                   sa| j                         }| j                  |       d{   }|d   | _         |d   | _        t	        j
                  |  d| j                           | j                          d{    t        | !          d{    | j                  r=| j                  s0| j                  | j                  | j                              | _
        yyy7 7 f7 Rw)zxConnect to the Gladia service.

        Initializes the session if needed and establishes websocket connection.
        Nr-  rL   z Session URL: )rL  rj  _setup_gladiarM  r	   info_connect_websocketrC  rn  r  rH  create_task_receive_task_handler_report_error)r   r7  responser[  s      r   rn  zGladiaSTTService._connect%  s        --/H!//99H (D'~DKK4&t/@/@.ABC%%'''g   ??4#5#5!%!1!1$2L2LTM_M_2`!aD $6? :
 	( s5   1C/C)AC/C+C/C-AC/+C/-C/c                    K   t         |           d{    d| _        | j                  r*| j	                  | j                         d{    d| _        | j                          d{    y7 Z7 &7 	w)zfDisconnect from the Gladia service.

        Cleans up tasks and closes websocket connection.
        NF)rC  ry  rN  rH  cancel_task_disconnect_websocket)r   r[  s    r   ry  zGladiaSTTService._disconnect9  sp     
 g!###"'""4#5#5666!%D((*** 	$
 7 	+s3   A6A05A6A2A6*A4+A62A64A6c                   K   	 | j                   r'| j                   j                  t        j                  u ryt	        j
                  |  d       t        | j                         d{   | _         d| _        | j                  4 d{    d| _
        ddd      d{    | j                  d       d{    | j                          d{    t	        j
                  |  d       y7 7 g7 R# 1 d{  7  sw Y   bxY w7 P7 :# t        $ r%}| j                  d| |       d{  7    d}~ww xY ww)	z-Establish the websocket connection to Gladia.NzConnecting to Gladia WebSocketTr   on_connectedz Connected to Gladia WebSocketzUnable to connect to Gladia: 	error_msg	exception)r  r  r$   r  r	   debugwebsocket_connectrL  rN  rU  rQ  _call_event_handler_send_buffered_audio	Exception
push_errorr   r  s     r   r  z#GladiaSTTService._connect_websocketH  s!    	4??#8#8EJJ#FLLD6!?@A$5d6G6G$HHDO&*D# (( % %#$ % % **>::: ++---LLD6!?@A I% % % % % ; .  	//.KA3,O[\/]]]	s   D>2D D>0D 'C.( D C0	D C4D C2 D 8D	9D DD -D>.D 0D 2D 4D:C=;DD D 	D;D6/D20D66D;;D>c                   K   	 | j                   r`| j                   j                  t        j                  u r:t	        j
                  |  d       | j                   j                          d{    d| _         | j                  d       d{    y7 %# t        $ r)}| j                  d| |       d{  7   Y d}~Pd}~ww xY w7 <# d| _         | j                  d       d{  7   w xY ww)z)Close the websocket connection to Gladia.z$ Disconnecting from Gladia WebSocketNzError closing websocket: r  on_disconnected)
r  r  r$   r  r	   r  closer  r  r  r  s     r   r  z&GladiaSTTService._disconnect_websocketa  s     	>4??#8#8EJJ#Fv%IJKoo++--- #DO**+<=== . 	Z//.Gs,KWX/YYY	Z > #DO**+<===sw   C0A'B +B,B 0C0CC0B 	CC 5B86C ;C
  CC
 C0
C-&C)'C--C0c           
        K   t        j                         4 d {   }i }| j                  r| j                  |d<   |j                  | j                  d| j
                  i||      4 d {   }|j                  r:|j                          d {   cd d d       d {    cd d d       d {    S |j                          d {   }t        j                  |  d|j                   d|xs |j                          t        |  d|j                   d|       7 7 7 7 7 x7 a# 1 d {  7  sw Y   nxY wd d d       d {  7   y # 1 d {  7  sw Y   y xY ww)Nr,  zX-Gladia-Key)headersjsonr4  z Gladia error: z: z& Failed to initialize Gladia session: z - )aiohttpClientSessionrF  postrG  rE  okr  textr	   errorstatusreasonr  )r   r7  sessionr4  r  
error_texts         r   r  zGladiaSTTService._setup_gladiam  s]    ((* 	 	gF||#'<<x ||		'7	 $   
 ;;!)0  		 	 	 (0}}!6JLL&/@:C`QYQ`Q`Bab $& FxFWWZ[eZfg #	 1		 "7  		 	 	 	 	s   E*D!E*AE,D$-E0 D.D&D.E D(!E%E*1D*2E*7D.
D,AD.!E*$E&D.(E*E*,D..E 	4D75E 	<EE*EE*E'EE'#E*
transcriptis_finalc                 @   K   | j                          d {    y 7 wr  )stop_processing_metrics)r   r  r  r%   s       r   _handle_transcriptionz&GladiaSTTService._handle_transcription  s      **,,,s   c                   K   | j                   j                  r| j                  ryt        j                  |  d       d| _        | j                  t               d{    | j                  r| j                          d{    yy7 *7 w)zHandle speech start event from Gladia.

        Broadcasts UserStartedSpeakingFrame and optionally triggers interruption
        when VAD is enabled.
        Nz User started speakingT)	r(  r  rV  r	   r  broadcast_framer   rW  broadcast_interruptionr_  s    r   _on_speech_startedz#GladiaSTTService._on_speech_started  sz      ~~((D,=,=v345 ""#;<<<!!--/// " 	=/s$   ABB#BB
B
Bc                    K   | j                   j                  r| j                  syd| _        | j                  t               d{    t        j                  |  d       y7 w)zoHandle speech end event from Gladia.

        Broadcasts UserStoppedSpeakingFrame when VAD is enabled.
        NFz User stopped speaking)r(  r  rV  r  r   r	   r  r_  s    r   _on_speech_endedz!GladiaSTTService._on_speech_ended  sV     
 ~~((0A0A!""#;<<<v345 	=s   AA%A#A%c                 :  K   | j                   r| j                   j                  t        j                  u rbt	        j
                  |      j                  d      }dd|id}| j                   j                  t        j                  |             d{    yyy7 w)z,Send audio chunk with proper message format.zutf-8audio_chunkchunk)typedataN)
r  r  r$   r  base64	b64encodedecodesendr  dumps)r   r|  r  messages       r   r  zGladiaSTTService._send_audio  sy     ??t44

B##E*11':D,woFG//&&tzz'':;;;  C? <s   BBBBc                 X  K   | j                   4 d{    | j                  rZt        j                  |  dt	        | j                         d       | j                  t        | j                               d{    ddd      d{    y7 {7 7 	# 1 d{  7  sw Y   yxY ww)z+Send any buffered audio after reconnection.Nz	 Sending z bytes of buffered audio)rU  rP  r	   r  r  r  bytesr_  s    r   r  z%GladiaSTTService._send_buffered_audio  s     $$ 	B 	B!!vYs43E3E/F.GG_`a&&uT-?-?'@AAA	B 	B 	B B	B 	B 	B 	BsW   B*BB*A"B9B:B>B*	B
B*BB*B'BB'#B*c                    K   | j                   r`| j                   j                  t        j                  u r9| j                   j	                  t        j                  ddi             d {    y y y 7 w)Nr  stop_recording)r  r  r$   r  r  r  r  r_  s    r   rx  z%GladiaSTTService._send_stop_recording  sT     ??t44

B//&&tzz6;K2L'MNNN  C?Ns   A&A2(A0)A2c                 H    | j                   r| j                   S t        d      )zGet the current WebSocket connection.

        Returns:
            The WebSocket connection.

        Raises:
            Exception: If WebSocket is not connected.
        zWebsocket not connected)r  r  r_  s    r   _get_websocketzGladiaSTTService._get_websocket  s!     ????"122r   c           
        K   | j                         2 3 d{   }	 t        j                  |      }|d   dk(  r~|j                  d      rm|d   d   }| j                  4 d{    |d   }|| j
                  kD  r*|| j
                  z
  }| j                  |d | _        || _        ddd      d{    nJ|d   dk(  r|d   d	   }|d
   }|d   }|d   d   }	|	rV| j                  t        || j                  t               ||             d{    | j                  ||	|       d{    n| j                  t        || j                  t               ||             d{    n|d   dk(  rM|d   d   }
|d   d   }|
d
   }|
d   }||k7  ro| j                  t        |dt               |             d{    nA|d   dk(  r| j                          d{    n |d   dk(  r| j                          d{    7 7 7 Y# 1 d{  7  sw Y   xY w7 7 7 7 m7 N7 /# t        j                   $ r t#        j$                  |  d|        Y Lw xY w6 yw)zxReceive and process websocket messages.

        Continuously processes messages from the websocket connection.
        Nr  r  acknowledgedr  
byte_ranger+  r  	utterancer%   r  r  )result)r  r  r%   translationtranslated_utteranceoriginal_language speech_start
speech_endz Received non-JSON message: )r  r  loadsgetrU  rQ  rP  
push_framer   _user_idr!   r  r   r   r  r  JSONDecodeErrorr	   r  )r   r  contentr  end_byter  r  r%   r  r  r  r  translated_languager  s                 r   _receive_messagesz"GladiaSTTService._receive_messages  s    
 "002 =	O =	O'<O**W- 6?m3N8S!(!>J#00 8 8#-a=#d&6&66(043C3C(CI151C1CIJ1OD./7D,8 8 8 V_4 ' <I(4H!*6!2J&vz:H"oo. * $ 0 2 ('.   #88'1%-%- 9    #oo5 * $ 0 2 ('.   V_5+26?;Q+R((/8K(L%*>z*J'"6v">K*.??"oo, +R1A1CEX  
 V_611333V_4//111w=	O8 8 8 8 8 41'' O$'CG9MNOy 3s   I%I#HI#I%AH/#H$H/'?H&H/1H
2AH/H"H/,H%-9H/&H''AH/;H)< H/H+ H/=H->H/I%I#H/
H/H	HH	H/%H/'H/)H/+H/-H//-I I%I  I%silencec                 B   K   | j                  d       d{    y7 w)zSend an empty audio chunk to keep the Gladia connection alive.

        Args:
            silence: Silent PCM audio bytes (unused, Gladia accepts empty chunks).
        r   N)r  )r   r  s     r   _send_keepalivez GladiaSTTService._send_keepalive  s      s###s   r  )4r  r  r  r  r
  Settingsr   r   InputParamsr   r"  r   r$  r   r#  r   r%  rD  r`  rb  r   rA  r!  r   rj  r   rm  rs  r   rw  r   r{  r  r   r   r  rn  ry  r  r  r  r"   r  r  r  r  r  rx  r  r  r  __classcell__)r[  s   @r   r'  r'     s@   
 !H   )*K 8<2!&*%)#.2/!%04,;!_2 _2 ,-4	_2
 _2 _2 _2 _2 UO_2 c]_2 }_2 *+_2 _2 _2 ,-_2  #5/!_2B3d 	5X 	5(3- 	5'4S> 'R ,= $sCx. 6! !!+ !5 ^E4K-H >b(+2
>DcN , IM--)--9A#- -
0 	6<u <BO3BOH$U $r   r'  )Br  rS  r  r  r   dataclassesr   r   typingr   r   r   r   r  logurur	   re  r
   rg  pipecat.frames.framesr   r   r   r   r   r   r   r   r   pipecat.services.gladia.configr   r   r   r   r   pipecat.services.settingsr   r   r   r   pipecat.services.stt_latencyr   pipecat.services.stt_servicer   pipecat.transcriptions.languager   r    pipecat.utils.timer!   (pipecat.utils.tracing.service_decoratorsr"   r  websockets.asyncio.clientr#   r  websockets.protocolr$   ModuleNotFoundErrorr  r  r  r"  r   r   r
  r'  r  r   r   <module>r     s       ( 9 9   .
 
 
  ` _ 8 < F / ?,F)oH( oHx} oHf! ! S S S<q$* q$O  ,FLL;qc"#FLLXY
&qc*
++,s   C	 	D2D  D