
    љi?                     ^   S SK r S SKrS SKr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Jr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJ r   SSK!J"r"  SSK#J$r$  SSK%J&r&  SSK'J(r(J)r)J*r*  SSK+J,r,  \RZ                  " \.5      r/ " S S5      r0 " S S\,5      r1g)    N)ListDictCallable	Awaitable)	APIRouter	WebSocket   )PoolProvider)
STSRequestSTSResponse)STSPipeline)SpeechDetector)SpeechRecognizer)OpenAISpeechRecognizer)
LLMService)ContextManager)SpeechSynthesizer)SessionStateManager)PerformanceRecorder)VoiceRecorder   )AvatarControlRequestAIAvatarRequestAIAvatarResponse)Adapterc                       \ rS rSrS rSrg)WebSocketSessionData   c                      S U l         0 U l        g N)iddataselfs    [/home/james-whalen/.local/lib/python3.13/site-packages/aiavatar/adapter/websocket/server.py__init__WebSocketSessionData.__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SSSSSSSSSSSSSSSSSSSSSSSSSS	S
SS
SSSSSSSSSSSS	SSSS.-S\S\S\S\S\S\S\S\S\S\S\S \	S!\
S"\S#\S$\S%\S&\S'\S(\S)\S*\S+\S,\S-\S.\\   S/\S0\S1\S2\S3\S4\S5\S6\S7\S8\S9\S:\S;\S<\S=\S>\S?\S@\SA\4ZU 4SB jjjrSC\4SD jrSE\\\/\S   4   4SF jrSE\\/\S   4   4SG jrSH\SI\4SJ jrSK\SC\4SL jrSM\ 4SN jr!SO\"4SP jr#SQ\SR\4SS jr$SWST\4SU jjr%SVr&U =r'$ )XAIAvatarWebSocketServer!   g      Ig      ?i>  Nzgpt-4.1.   zhttp://127.0.0.1:50021g      N@g        zo$Previous user's request and your response have been canceled. Please respond again to the following request:

z$Current date and time: UTCFzaiavatar.dbTrecorded_voicesg      $@r   )-volume_db_thresholdsilence_duration_thresholdinput_sample_rateopenai_api_keyopenai_base_urlopenai_modelsystem_promptvoicevox_speakervoicevox_urlstsvadsttllmttsvad_volume_db_thresholdvad_silence_duration_thresholdvad_sample_ratestt_sample_ratellm_openai_api_keyllm_base_url	llm_modelllm_system_promptllm_context_managertts_voicevox_urltts_voicevox_speaker	wakewordswakeword_timeoutmerge_request_thresholdmerge_request_prefixtimestamp_interval_secondstimestamp_prefixtimestamp_timezonemute_on_barge_indb_pool_providerdb_connection_strsession_state_managerperformance_recordervoice_recordervoice_recorder_enabledvoice_recorder_dirinvoke_queue_idle_timeoutinvoke_timeoutuse_invoke_queueresponse_audio_chunk_sizedebugr5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   c       -   
        >^  U
=(       d    [        S$0 SU_SU=(       d    U_SU=(       d    U_SU=(       d    U_SU=(       d    [        UU=(       d    US9_SU_SU=(       d    U_S	U=(       d    U_S
U=(       d    U_SU=(       d    U_SU_SU_SU=(       d    U	_SU=(       d    U_SU_SU_SU_SU_SU_SU_SU _SU"_SU#_SU$_SU%_SU&_SU'_SU(_SU)_SU*_S U+_S!U-_6T l        [        T.T ]  T R                  5        0 T l        0 T l        S T l        S T l        U,T l	        U!(       a1  T R                  R                  R                  S"[        4U 4S# jj5       n!U-T l        S T l        g )%Nr?   rC   rD   rE   r@   )r8   sample_raterA   rG   rH   rI   rJ   rK   rB   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   ra   
session_idc                 F   >#    TR                  U S5      I S h  vN   g  N7f)N )stop_response)rd   r$   s    r%   rU   :AIAvatarWebSocketServer.__init__.<locals>.mute_on_barge_in   s     ((R888s   !!r.   )r   r   r>   superr&   
websocketssessions_on_connect_on_disconnectr`   r?   on_recording_startedstrra   last_response)/r$   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   	__class__s/   `                                             r%   r&    AIAvatarWebSocketServer.__init__"   s>   t  )
+ )
)
 %<$R?R)
 ,J+gMg	)

 ,@/@)
  --+@/@)
 )
  2C^)
 &8)
  /<)
  0@=!)
" !4#)
& ')
( .=))
* "6!I9I+)
.  /)
0 .1)
2 %<3)
4 "65)
6 (B7)
8 .9)
:  2;)
< .=)
> 0?)
@ #8A)
B "6C)
D *E)
F $:G)
H  2I)
J '@K)
L *M)
N .O)
P Q)
X 	"029; `dQU *C& XX\\..93 9 /9 
!r(   returnc                 4    U R                   U R                  S.$ )Nr`   ra   ru   r#   s    r%   
get_config"AIAvatarWebSocketServer.get_config   s    )-)G)GZZ
 	
r(   funcc                     Xl         U$ r    )rl   r$   rx   s     r%   
on_connect"AIAvatarWebSocketServer.on_connect   s    r(   c                     Xl         U$ r    )rm   rz   s     r%   on_disconnect%AIAvatarWebSocketServer.on_disconnect   s    "r(   	websocketsession_datac                 0
  #    UR                  5       I S h  vN n[        R                  " U5      nUR                  (       d  UR	                  [        SUR                  UR                  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                   H  nU" U5      I S h  vN   M     UR                  S:X  Ga  XR                  UR                  '   UR                  Ul        [        R                  SUR                   35        U R                    H  nU" XB5      I S h  vN   M     UR                  (       a<  U R"                  R$                  R'                  UR                  SUR                  S5        UR                  (       a<  U R"                  R$                  R'                  UR                  S	UR                  S5        UR(                  UR*                  S
'   X R,                  UR                  '   U R/                  [        SUR                  UR                  UR                  S95      I S h  vN   U R0                  (       a&  [2        R4                  " U R1                  XB5      5        g g UR                  S:X  Ga  UR                  (       a  UR                  nO0U R"                  R$                  R7                  UR                  S	5      nU R"                  R9                  [;        UR                  UR                  UR                  UUR<                  UR>                  UR@                  URB                  URD                  URF                  S9
5        S h  vN nU R"                  R/                  U5      I S h  vN   M.  UR                  S:X  aX  [H        RJ                  " UR>                  5      n	U R"                  R$                  RM                  XR                  5      I S h  vN   g UR                  S:X  az  [O        U R"                  R$                  S5      (       aT  UR(                  RQ                  S5      n
U
(       a1  U R"                  R$                  RS                  UR                  U
5        g g g UR                  S:X  a;  [        R                  SUR                   35        UR                  5       I S h  vN   g g  GN GNl GNB GN% GN GN GNz GNZ
 g  N N"7f)Nfinalerrorz-WebSocket disconnect: session_id is required.)typerd   user_id
context_idmetadatastartz!WebSocket connected for session: r   Tr   r   	connected)r   rd   r   r   invoke)
r   rd   r   r   text
audio_datafilessystem_prompt_paramsallow_mergewait_in_queuer"   configr5   stopz"WebSocket disconnect for session: )*receive_textr   model_validate_jsonrd   	send_textr   r   r   model_dump_jsonloggerinfoclose_on_request_handlersr   rj   r!   _on_session_start_handlersr>   r?   set_session_datar   r"   rk   handle_responserl   asynciocreate_taskget_session_datar   r   r   r   r   r   r   r   base64	b64decodeprocess_sampleshasattrgetset_volume_db_threshold)r$   r   r   r"   requeston_reqon_session_startr   rr   r5   s              r%   process_websocket)AIAvatarWebSocketServer.process_websocket   s    ++--!55d;!!%%&6"--"--!#RS' o! ! ! KKGH//### //F/!! 0 <<7"2;OOG../%00LOKK;G<N<N;OPQ$($C$C &w=== %D --g.@.@)W__^bc!!--g.@.@,PWPbPbdhi,3,<,<Lj)-9MM,//*&&'7 "--"--	(    ##D$4$4W$KL   \\X%!!$//
!XX\\::7;M;M|\
88??:\\"--%\\"--mm%,%A%A#//%33,  2a hh..q111\\V#))'*<*<=J((,,..z;M;MNNN\\X%txx||%:;;&-&6&6&:&:;P&Q#&HHLL889K9KM`a ' <
 \\V#KK<W=O=O<PQR//### $Y .! $
 " > 2 2  O $s   TS8A8TS;,T<S>=TTA>TTDT+T,D TTT
TT3T4A(TTCT1T2T;T>TTTT
TTTTr   c                     [        5       nU(       d  U$ Sn[        R                  " X15      nU(       a  US   Ul        SUl        Sn[        R                  " XQ5      nU(       a  US   Ul        SUl        U$ )Nz\[face:(\w+)\]r   g      @z\[animation:(\w+)\])r   refindall	face_nameface_durationanimation_nameanimation_duration)r$   r   avreqface_pattarnfacesanimation_pattarn
animationss          r%   parse_avatar_control_request4AIAvatarWebSocketServer.parse_avatar_control_request   sp    $&L )

<.#AhEO"%E 3ZZ 18
#-a=E '*E$r(   aiavatar_responsec                    #    U R                   UR                     R                  UR                  5       5      I S h  vN   g  N7fr    )rj   rd   r   r   )r$   r   s     r%   send_response%AIAvatarWebSocketServer.send_response  s9     oo/::;EE--/
 	
 	
s   :AAAresponsec                   #    [        UR                  UR                  UR                  UR                  UR
                  UR                  UR                  UR                  =(       d    0 S9nU R                   H  nU" X!5      I S h  vN   M     UR                  S:X  GaG  UR                  R                  S5      (       a.  U R                  UR                  UR                  5      I S h  vN   UR                  Ul        U R                  UR
                  5      Ul        UR                  (       Ga  U R                  S:  Gao  [         R"                  " [$        R&                  " UR                  5      S5       nUR)                  5       nUR+                  5       nUR-                  5       nUR/                  5       nUR1                  U5      n	S S S 5        WWWS.n
XR                  S'   S Ul        U R3                  U5      I S h  vN   [5        S[7        W	5      U R                  5       H  n[8        R:                  " XXR                  -    5      R=                  S5      n[        UR                  UR                  UR                  UR                  USU
0S	9nU R3                  U5      I S h  vN   M     g [8        R:                  " UR                  5      R=                  S5      nXl        OUR                  S
:X  a(  UR>                  RA                  5       UR                  S
'   OUR                  S:X  aH  [B        RD                  " SUR
                  5      =n(       a  SUl        SURG                  S5      0Ul        O)UR                  S:X  a  U R                  U5      I S h  vN   U R3                  U5      I S h  vN   g  GN4 GN! , (       d  f       GN= f GN GN. N< N%7f)N)r   rd   r   r   r   
voice_textr   r   chunkis_guardrail_triggeredr   rb)rc   channelssample_width
pcm_formatzutf-8)r   rd   r   r   r   r   	tool_callr   z\[vision:(\w+)\]visionsource   r   )$r   r   rd   r   r   r   r   r   r   _on_response_handlersr   rg   languager   avatar_control_requestr`   waveopenioBytesIO
getnframesgetframerategetnchannelsgetsampwidth
readframesr   rangelenr   	b64encodedecoder   to_dictr   searchgroup)r$   r   r   on_respwav_fileframesrc   r   r   r   r   i	b64_chunkchunk_responseimage_source_matchs                  r%   r   'AIAvatarWebSocketServer.handle_response  sX    ,**$$******&&,"	
 11G+666 2 ==G#  $$%=>>(()<)<h>Q>QRRR *2):):& 8<7X7XYaYfYf7g4 """11A52::h.A.A#BDIX!)!4!4!6&.&;&;&=#+#8#8#:'/'<'<'>%-%8%8%@
 J (3$,(4"J @J..|<37%0,,->??? #1c*ot7U7UV$*$4$4Z!FdFdBd5e$f$m$mnu$v	)9!)'/':':$,$4$4'/':':'0&2J%?* #00@@@ W  !' 0 01D1D E L LW UI3<0]]k)6>6H6H6P6P6R&&{3]]g%%'YY/BHMM%RR!R)1!&,46H6N6Nq6Q+R!*]]f$$$X...  !2333E 7
 S JI  @ A" /3s   BON:A"O)N=*BO7AO 	7O OB&O'O(C3OOO4O5O=O 
O
	OOOOrd   r   c                 T   #    U R                  [        SUUS95      I S h  vN   g  N7f)Nr   )r   rd   r   )r   r   )r$   rd   r   s      r%   rg   %AIAvatarWebSocketServer.stop_responsek  s.       !1!!"
  	 	s   (&(pathc                 `   ^  [        5       nUR                  U5      S[        4U 4S jj5       nU$ )Nr   c                   >#    U R                  5       I S h  vN   [        5       n  TR                  X5      I S h  vN   M   N+ N! [         ak  n[	        U5      nSU;   a'  [
        R                  SUR                   35         S nAO6SU;   a'  [
        R                  SUR                   35         S nAO	e S nAff = fUR                  (       a  TR                  (       a  TR                  U5      I S h  vN    TR                  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                  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)NzWebSocket is not connectedz'WebSocket disconnected (1): session_id=z <CloseCode.NO_STATUS_RCVD: 1005>z'WebSocket disconnected (2): session_id=)acceptr   r   	Exceptionro   r   r   r!   rm   r>   finalizerj   rk   )r   r   exerror_messager$   s       r%   websocket_endpointHAIAvatarWebSocketServer.get_websocket_router.<locals>.websocket_endpointv  s    ""$$$/1L;00III 	 %
 J  #B/=@KK"I,//IZ [\\7=HKK"I,//IZ [\\  ??**"11,???((++LOO<<<#$//9 OOLOO<#$--7 MM,//: 8 #<??**"11,???((++LOO<<<#$//9 OOLOO<#$--7 MM,//: 8 #s   I!AI!A AA I!A 
B<3B7F 	(B71F 6B77B<<F ?6I!5C86-I!#D&$A*I!7IG-I3G64A*II!)r   r   r   )r$   r   routerr   s   `   r%   get_websocket_router,AIAvatarWebSocketServer.get_websocket_routers  s5    			$		;	 	; 
 	;: r(   )rl   rm   ra   rp   r`   rk   r>   rj   )z/ws)(r)   r*   r+   r,   floatintro   r   r   r   r   r   r   r   boolr
   r   r   r   r&   dictrv   r   r   r   r   r{   r~   r   r   r   r   r   r   r   r   rg   r   r-   __classcell__)rq   s   @r%   r0   r0   !   sy   
 &+,/!&"#%! "4  " $!% */03$$"& "!%.2 8$&#"&), %X,/ :"'!&)-!.5948(,'+"3+/ $!& *+oy" #	y"
 %*y" y" y" y" y" y" y" y" y"  !y"" #y"$ %y"& 'y", "'-y". )./y"0 1y"2 3y"4  5y"6 7y"8 9y": ;y"< ,=y"> ?y"@ "Ay"B 9Cy"D  Ey"F "'Gy"H "Iy"J %*Ky"L My"N  Oy"P Qy"R 'Sy"T Uy"V  3Wy"X 2Yy"Z &[y"\ !%]y"^  _y"` $)ay"b cy"d ey"j $'ky"n oy" y"v
D 
x:N(OQZ[_Q`(`a (,@+A9T?+R"S 
O$ O$J^ O$d 9M ,
5E 

P4k P4dc s ! ! !r(   r0   )2r   r   r   loggingr   r   typingr   r   r   r   fastapir   r   databaser
   
sts.modelsr   r   sts.pipeliner   sts.vadr   sts.sttr   sts.stt.openair   sts.llmr   sts.llm.context_managerr   sts.ttsr   sts.session_state_managerr   sts.performance_recorderr   sts.voice_recorderr   modelsr   r   r   baser   	getLoggerr)   r   r   r0   r.   r(   r%   <module>r     su      	  	  2 2 ( $ 1 ' % ' 4 ! 5 ( < ; / L L 			8	$ sg sr(   