
    љi#                         S SK r S SKrS SKrS SKJrJrJrJr  S SKJ	r	J
r
  SSKJr  SSKJr  SSKJr  SS	KJrJr  \R(                  " \5      r " S
 S5      r " S S5      rg)    N)DictCallable	AwaitableOptional)	APIRouter	WebSocket   )SpeechDetector)SileroStreamSpeechDetector)SpeechRecognizer   )
STTRequestSTTResponsec                       \ rS rSrS rSrg)SpeechRecognitionSessionData   c                      S U l         0 U l        g N)iddata)selfs    U/home/james-whalen/.local/lib/python3.13/site-packages/aiavatar/adapter/stt/server.py__init__%SpeechRecognitionSessionData.__init__   s    !%	    )r   r   N)__name__
__module____qualname____firstlineno__r   __static_attributes__ r   r   r   r      s    r   r   c                       \ rS rSrSrSSS.S\S\S\4S	 jjrS
 r	S\
\\/\S   4   4S jrS\
\/\S   4   4S jrS\4S jrS\S\4S jrS\4S jrSS\4S jjrSrg)StreamSpeechRecognitionServer   a3  
WebSocket server for streaming speech recognition.

For stream VAD (SileroStreamSpeechDetector):
- Sends partial results via on_speech_detecting callback
- Sends final result when speech ends

For non-stream VAD:
- Buffers audio until speech detection completes
- Sends final result with batch recognition
NF)sttdebugvadr%   r&   c                    Xl         X l        X0l        0 U l        0 U l        S U l        S U l        [        U[        5      U l	        U R                  5         g r   )r'   r%   r&   
websocketssessions_on_connect_on_disconnect
isinstancer   _is_stream_vad_setup_vad_callbacks)r   r'   r%   r&   s       r   r   &StreamSpeechRecognitionServer.__init__!   sU     
02AC mqcg ).HI 	!!#r   c                   ^  T R                   R                  S[        4U 4S jj5       nT R                  (       a  T R                   R                  S[        4U 4S jj5       nT R                   R
                  S[        S[        S[        S[        S[        4
U 4S jj5       nT R                   R                  S	[        S[        4U 4S
 jj5       ngT R                   R
                  S[        S[        S[        S[        S[        4
U 4S jj5       ng)zSetup callbacks for VAD events.
session_idc                 v   >#    U TR                   ;   a"  TR                  [        SU S95      I S h  vN   g g  N7f)Nvoicedtyper2   r)   _send_responser   )r2   r   s    r   	on_voicedEStreamSpeechRecognitionServer._setup_vad_callbacks.<locals>.on_voiced=   sA     T__,))+!)+    -s   -979textc           	         >#    UR                   nUTR                  ;   a$  TR                  [        SUU SS95      I S h  vN   g g  N7f)NpartialFr6   r2   r;   is_final)r2   r)   r8   r   )r;   sessionr2   r   s      r   on_speech_detectingOStreamSpeechRecognitionServer._setup_vad_callbacks.<locals>.on_speech_detectingG   sR     $//
0--k&#-!!&	/    1s   ;AAArecorded_datametadatarecorded_durationc           
         >#    UTR                   ;   a'  TR                  [        SUUSSU0S95      I S h  vN   g g  N7f)NfinalTdurationr6   r2   r;   r?   rD   r7   )rC   r;   rD   rE   r2   r   s        r   on_speech_detected_streamUStreamSpeechRecognitionServer._setup_vad_callbacks.<locals>.on_speech_detected_streamS   sP     0--k$#-!!%",.?!@/    1s   2><>errorc           	         >#    UTR                   ;   a-  TR                  [        SU[        U 5      SS95      I S h  vN   g g  N7f)NrL   Fr>   )r)   r8   r   str)rL   r2   r   s     r   "on_speech_recognition_error_stream^StreamSpeechRecognitionServer._setup_vad_callbacks.<locals>.on_speech_recognition_error_stream_   sK     0--k$#- Z!&	/    1s   8AAAc           
        >#    UTR                   ;  a  g TR                  (       a1   TR                  R                  X@5      I S h  vN nUR                  nOUnTR                  [        SUUSSU0S	95      I S h  vN   g  N:! [         aN  n[
        R                  SU 3SS9  TR                  [        SU[        U5      SS95      I S h  vN     S nAg S nAff = f Nb7f)
NzError in batch recognition: Texc_inforL   Fr>   rG   rH   rI   )
r)   r%   	recognizer;   	ExceptionloggerrL   r8   r   rN   )	rC   r;   rD   rE   r2   resultrecognized_textexr   s	           r   on_speech_detected_batchTStreamSpeechRecognitionServer._setup_vad_callbacks.<locals>.on_speech_detected_batchj   s     T__4 88'+xx'9'9*'T!T*0++ '+O))+ )(!(*;<+    "U$ 'CB4%HSWX"11+!('1!$R%*	3    sX   #CB B B $C:C;C B 
C>C
CCCCCN)r'   r9   rN   r.   rA   on_speech_detectedbytesdictfloaton_speech_recognition_errorrU   )r   r9   rA   rJ   rO   rZ   s   `     r   r/   2StreamSpeechRecognitionServer._setup_vad_callbacks9   s    
			 	 
	 XX))  * XX((u C [_ ty   HK  ) XX11	 WZ  2 XX((e 3 Z^ sx   GJ  )r   funcc                     Xl         U$ r   )r+   r   rb   s     r   
on_connect(StreamSpeechRecognitionServer.on_connect   s    r   c                     Xl         U$ r   )r,   rd   s     r   on_disconnect+StreamSpeechRecognitionServer.on_disconnect   s    "r   responsec                 "  #    UR                   U R                  ;   a@   U R                  UR                      R                  UR                  5       5      I Sh  vN   gg N! [         a"  n[
        R                  SU 35         SnAgSnAff = f7f)z"Send response to WebSocket client.NzError sending response: )r2   r)   	send_textmodel_dump_jsonrU   rV   rL   )r   rj   rY   s      r   r8   ,StreamSpeechRecognitionServer._send_response   s     $//1>ooh&9&9:DD,,.   2  >7t<==>s@   B9A  AA  BA   
B*BBBB	websocketsession_datac                   #    UR                  5       I Sh  vN n[        R                  " U5      nUR                  (       dj  UR	                  [        SUR                  SS0S9R                  5       5      I Sh  vN   [        R                  S5        UR                  5       I Sh  vN   gUR                  S:X  a  XR                  UR                  '   UR                  Ul        UR                  UR                  S'   X R                  UR                  '   [        R                  SUR                   35        U R!                  [        S	UR                  S
95      I Sh  vN   U R"                  (       a&  [$        R&                  " U R#                  XB5      5        ggUR                  S:X  a`  UR(                  (       aN  [*        R,                  " UR(                  5      nU R.                  R1                  XTR                  5      I Sh  vN   ggUR                  S:X  a;  [        R                  SUR                   35        UR                  5       I Sh  vN   gg GNA GN GN GN N^ N7f)z#Process incoming WebSocket message.NrL   zsession_id is required)r6   r2   rD   z-WebSocket disconnect: session_id is required.startrD   z!STT WebSocket connected: session=	connectedr5   r   stopz"STT WebSocket disconnect: session=)receive_textr   model_validate_jsonr2   rl   r   rm   rV   infocloser6   r)   r   rD   r   r*   r8   r+   asynciocreate_task
audio_database64	b64decoder'   process_samples)r   ro   rp   r   requestr{   s         r   process_websocket/StreamSpeechRecognitionServer.process_websocket   s    ++--006!!%%k"--!#;<' o	! ! !
 KKGH//###<<7"2;OOG../%00LO,3,<,<Lj)-9MM,//*KK;G<N<N;OPQ%%k "--'   
 ##D$4$4W$KL   \\V#!!#--g.@.@A
hh..z;M;MNNN " \\V#KK<W=O=O<PQR//### $E .! $ O $sm   I'IA"I'9I:,I'&I'B7I'I B%I'I#AI'I%I'I'I' I'#I'%I'r2   c                    #    [        U R                  S5      (       a$  U R                  R                  U5      I Sh  vN   g[        U R                  S5      (       a  U R                  R                  U5        gg N=7f)zClean up session resources.finalize_sessionNdelete_session)hasattrr'   r   r   )r   r2   s     r   r   .StreamSpeechRecognitionServer.finalize_session   s]     488/00((++J777TXX/00HH##J/ 1 8s   :A<A:>A<pathc                 `   ^  [        5       nUR                  U5      S[        4U 4S jj5       nU$ )z-Create FastAPI router for WebSocket endpoint.ro   c                   >#    U R                  5       I S h  vN   [        5       n  TR                  X5      I S h  vN   M   N+ N! [         a  n[	        U5      nSU;   a'  [
        R                  SUR                   35         S nAOQSU;   a'  [
        R                  SUR                   35         S nAO$[
        R                  SU 3SS9   S nAOS nAff = fUR                  (       a  TR                  (       a  TR                  U5      I S h  vN    TR                  UR                  5      I S h  vN    UR                  TR                  ;   a  TR                  UR                  	 UR                  TR                  ;   a  TR                  UR                  	 g g g ! UR                  (       a  TR                  (       a  TR                  U5      I S h  vN    TR                  UR                  5      I S h  vN    UR                  TR                  ;   a  TR                  UR                  	 UR                  TR                  ;   a  TR                  UR                  	 f f f = f7f)NTzWebSocket is not connectedz+STT WebSocket disconnected (1): session_id=z <CloseCode.NO_STATUS_RCVD: 1005>z+STT WebSocket disconnected (2): session_id=zSTT WebSocket error: rR   )acceptr   r   rU   rN   rV   rw   r   rL   r,   r   r)   r*   )ro   rp   rY   error_messager   s       r   websocket_endpointNStreamSpeechRecognitionServer.get_websocket_router.<locals>.websocket_endpoint   s    ""$$$79L;00III 	 %
 J Y #B/=@KK"MlooM^ _``7=HKK"MlooM^ _``LL#8!HSWLXY  ??**"11,???//@@@#$//9 OOLOO<#$--7 MM,//: 8 #<??**"11,???//@@@#$//9 OOLOO<#$--7 MM,//: 8 #s   I(AI(A AA I(A 
C3CF 	(C1F 6CF CF 6I(D#I(4D75A*I(7I%G#I%:G=;A*I%%I()r   ro   r   )r   r   routerr   s   `   r   get_websocket_router2StreamSpeechRecognitionServer.get_websocket_router   s5    			$		;	 	; 
 	;< r   )r.   r+   r,   r&   r*   r%   r'   r)   )z/ws/stt)r   r   r   r   __doc__r
   r   boolr   r/   r   r   r   r   re   rh   r   r8   r   r   rN   r   r   r    r!   r   r   r#   r#      s    
  !%$ $ 	$
 $0M^x5Q(RT]^bTc(cd (,H+I9UY?+Z"[ >[ >&$ &$Jf &$P0 0# # #r   r#   )ry   r|   loggingtypingr   r   r   r   fastapir   r   sts.vadr
   sts.vad.streamr   sts.sttr   modelsr   r   	getLoggerr   rV   r   r#   r!   r   r   <module>r      sI       6 6 ( % 8 ' +			8	$ X Xr   