o
    y	i\7                     @   sN   d Z ddlZddlZddlZddlZddlmZ ddlmZ G dd dZ	dS )zR
Sarvam AI Speech-to-Text Service
Handles audio transcription using Sarvam AI API
    N)Optional)Logc                   @   s   e Zd ZdZdd Zdededee fddZd	edee fd
dZde	dedee fddZ
dededee fddZdedee fddZddededefddZdededee fddZdS )SarvamSTTServicez8Sarvam AI Speech-to-Text service for audio transcriptionc                 C   sj   t dd| _t dd| _t dd| _t dd| _d	| _| j d
| _t	d| j d| j  d S )NZSARVAM_API_KEYZ$sk_plejgbkc_tIeBnij5Cl5YQINTez4opajYZSARVAM_BASE_URLzhttps://api.sarvam.aiZSARVAM_MODELzsaarika:v2.5ZSARVAM_LANGUAGEzen-IN   z/speech-to-textu-   🎤 Sarvam STT Service initialized - Model: z, Language: )
osgetenvapi_keyZbase_urlmodellanguagetimeoutstt_urlr   info)self r   services/sarvam_stt_service.py__init__   s   zSarvamSTTService.__init__
audio_data
session_idreturnc              
      s  znt |}td| dt| d t|dk r)tdt| d W dS | ||I dH }|s?td|  W dS | ||I dH }|rm| |}|rdt	d| d	|dd
  d |W S td| d W dS  t
y } ztd| d|  W Y d}~dS d}~ww )a  
        Transcribe audio using Sarvam AI API
        
        Args:
            audio_data: Base64 encoded audio data
            session_id: Session identifier for logging
            
        Returns:
            Transcribed text or None if failed
        u   🎤 Decoded audio for session :  bytes@  u/   🎤 Audio too short for Sarvam transcription: Nu2   ⚠️ Failed to process audio format for session u*   🎤 Sarvam transcribed audio for session : 'd   ...'u1   🎤 Filtered out false positive transcription: ''u.   ❌ Error in Sarvam transcription for session )base64	b64decoder   debuglen_process_audio_formatwarning_call_sarvam_api_filter_transcriptionr   	Exceptionerror)r   r   r   audio_bytesprocessed_audiotranscriptionfiltered_transcriptioner   r   r   transcribe_audio   s0   

 z!SarvamSTTService.transcribe_audior(   c                    sb  |sdS |   }td| d g d ddl}|dd|  }| v s,| v r7td| d dS t|d	k rHtd
| d dS | }t|dkret|d dkretd| d dS | }t|dkrt fdd|D rtd| d dS |	dd	dd	dd	dd  dkrtd| d dS td| d |S )a  
        Filter out common false positive transcriptions from Sarvam STT.
        
        Args:
            transcription: Raw transcription from Sarvam
            
        Returns:
            Filtered transcription or None if it's a false positive
        Nu    🎤 Raw Sarvam transcription: 'r   )yesyeahZyepokayokmmhmmZuhZumZahZohnoZnopeZsurerightZalrightZhellohiZheyZthanksz	thank youZbyeZgoodbyer   z[.,!?]+ u   🎤 Filtered false positive: '   u$   🎤 Filtered short transcription: '      u"   🎤 Filtered single short word: 'c                 3   s    | ]}| v V  qd S )Nr   ).0ZwordZfalse_positivesr   r   	<genexpr>z   s    z9SarvamSTTService._filter_transcription.<locals>.<genexpr>u.   🎤 Filtered repeated false positive words: '.,!?u/   🎤 Filtered punctuation-only transcription: 'u   🎤 Accepted transcription: ')
striplowerr   r   resubr   splitallreplace)r   r(   ZcleanedrB   Zcleaned_no_punctZwordsZwords_no_punctr   r:   r   r#   I   s4   
",z&SarvamSTTService._filter_transcriptionaudio_chunksc           
         sz  zt d| dt| d d}|D ]*}zt|}||7 }W q ty> } zt d| d|  W Y d}~qd}~ww |sLt d|  W dS t|d	k r`t d
t| d W dS | ||I dH }|snW dS | ||I dH }|r| 	|}	|	rt 
d| d|	dd  d |	W S t d| d W dS  ty } zt d| d|  W Y d}~dS d}~ww )a  
        Transcribe combined audio buffer using Sarvam AI API
        
        Args:
            audio_chunks: List of base64 encoded audio chunks
            session_id: Session identifier for logging
            
        Returns:
            Transcribed text or None if failed
        u2   🎤 Transcribing Sarvam audio buffer for session  - z chunks    u0   ⚠️ Failed to decode audio chunk for session r   Nu)   ⚠️ No valid audio chunks for session i  u8   🎤 Combined audio too short for Sarvam transcription: r   u3   🎤 Sarvam transcribed combined audio for session r   r   r   u8   🎤 Filtered out false positive buffer transcription: 'r   u5   ❌ Error in Sarvam buffer transcription for session )r   r   r   r   r   r$   r!   r    r"   r#   r   r%   )
r   rG   r   Zcombined_audiochunkZdecoded_chunkr*   r'   r(   r)   r   r   r   transcribe_audio_buffer   sF   

 z(SarvamSTTService.transcribe_audio_bufferr&   c              
      s   zC|  |}|std|  W dS | j|dd}t|dk r/tdt| d W dS td| dt| d	t| d |W S  tyb } ztd
| d|  W Y d}~dS d}~ww )u  
        Process audio format for Sarvam API (convert μ-law to WAV)
        
        Args:
            audio_bytes: Raw audio bytes
            session_id: Session identifier for logging
            
        Returns:
            Processed WAV audio bytes or None if failed
        u3   ⚠️ Failed to convert μ-law to PCM for session Nr   )sample_rateu   🎵 WAV file too short: r   u(   🎵 Processed audio format for session r   z -> u.   ❌ Error processing audio format for session )_mulaw_to_pcmr   r!   _create_wav_filer   r   r$   r%   )r   r&   r   pcm_dataZwav_datar*   r   r   r   r       s"   
&z&SarvamSTTService._process_audio_format
mulaw_datac              
   C   sR   zddl }||d}|W S  ty( } ztd|  W Y d}~dS d}~ww )u   
        Convert μ-law encoded audio to PCM
        
        Args:
            mulaw_data: μ-law encoded audio bytes
            
        Returns:
            PCM audio bytes or None if failed
        r   N   u$   ❌ Error converting μ-law to PCM: )audioopZulaw2linr$   r   r%   )r   rP   rR   rO   r*   r   r   r   rM      s   
zSarvamSTTService._mulaw_to_pcmr   rO   rL   c                 C   s~   ddl }ddl}| }||d}|d |d || || W d   n1 s1w   Y  |d |	 S )z
        Create WAV file from PCM data
        
        Args:
            pcm_data: PCM audio data
            sample_rate: Sample rate in Hz
            
        Returns:
            WAV file bytes
        r   Nwbr7   rQ   )
waveioBytesIOopenZsetnchannelsZsetsampwidthZsetframerateZwriteframesseekread)r   rO   rL   rT   rU   Z
wav_bufferZwav_filer   r   r   rN      s   



z!SarvamSTTService._create_wav_filec              
      sd  zd| j i}t }|jd|ddd |d| j |d| j td| d	t| d
 t	 4 I dH }|j
| j||tj| jdd4 I dH }|jdkr| I dH }|dd}td| d| d t|dk r|tdt| d | dv rtd| d | W  d  I dH  W  d  I dH  W S | I dH }	td| d|j d|	  tdt| d
 	 W d  I dH  W d  I dH  W dS 1 I dH sw   Y  W d  I dH  W dS 1 I dH sw   Y  W dS  tjy   td|  Y dS  ty1 }
 ztd| d|
  W Y d}
~
dS d}
~
ww ) z
        Call Sarvam AI API for transcription
        
        Args:
            audio_data: WAV audio data
            session_id: Session identifier for logging
            
        Returns:
            Transcribed text or None if failed
        zapi-subscription-keyfilez	audio.wavz	audio/wav)filenameZcontent_typer	   Zlanguage_codeu$   🎤 Calling Sarvam API for session z - Audio size: r   N)total)headersdatar      Z
transcriptr5   u%   🎤 Sarvam API response for session r   r   i>  u#   ⚠️ Short audio sent to Sarvam: z" bytes (may cause false positives))r,   r-   r.   r/   r0   r1   u.   ⚠️ Potential false positive from Sarvam: 'z)' - Audio may be too short or low qualityu!   ❌ Sarvam API error for session r   rH   u(   🎤 Audio data size that caused error: u#   ❌ Sarvam API timeout for session u)   ❌ Error calling Sarvam API for session )r   aiohttpZFormDataZ	add_fieldr	   r
   r   r   r   ZClientSessionZpostr   ZClientTimeoutr   statusZjsongetr!   rA   r@   textr%   asyncioTimeoutErrorr$   )r   r   r   r]   r^   ZsessionZresponseresultr(   Z
error_textr*   r   r   r   r"     sX   
2z!SarvamSTTService._call_sarvam_apiN)r   )__name__
__module____qualname____doc__r   strr   r+   r#   listrK   bytesr    rM   intrN   r"   r   r   r   r   r      s    ,>7!r   )
rj   r   r   r`   rd   typingr   Zservices.log_utilsr   r   r   r   r   r   <module>   s    