
    љiG                     L   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J	r	J
r
  S SKJr  S SKJrJrJrJrJrJrJrJr  S SK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&J'r'  S	SK(J)r)  S	SK*J+r+  S	SK,J-r-  S	SK.J/r/J0r0  S	SK1J2r2  S	SK3J4r4  S	SK5J6r6  S	SK7J8r8  S	SK9J:r:  S	SK;J<r<  SSK=J>r>J?r?J@r@  SSKAJBrB  \R                  " \D5      rE " S S\5      rF " S S\5      rG " S S\5      rH " S  S!\5      rI " S" S#\5      rJ " S$ S%\5      rK " S& S'\5      rL " S( S)\B5      rMg)*    N)ListDictOptionalAnyCallable	Awaitable)uuid4)	APIRouterDependsHTTPExceptionstatusRequestFile
UploadFileForm)JSONResponseResponse)
HTTPBearerHTTPAuthorizationCredentials)EventSourceResponse)	BaseModel
ConfigDict   )PoolProvider)STSPipeline)
STSRequestSTSResponse)SpeechDetectorDummy)SpeechRecognizer)OpenAISpeechRecognizer)SpeakerRegistryMatchTopKResult)
LLMService)ContextManager)SpeechSynthesizer)SessionStateManager)PerformanceRecorder)VoiceRecorder   )AvatarControlRequestAIAvatarRequestAIAvatarResponse)Adapterc                   H    \ rS rSr% \\S'   Sr\\   \S'   Sr	\\   \S'   Sr
g)SynthesizeRequest   textN
style_infolanguage )__name__
__module____qualname____firstlineno__str__annotations__r2   r   r   r3   __static_attributes__r4       V/home/james-whalen/.local/lib/python3.13/site-packages/aiavatar/adapter/http/server.pyr/   r/      s#    
I!%J%"Hhsm"r<   r/   c                   L    \ rS rSr% \\S'   \\S'   \\\4   \S'   Sr	\
\S'   Srg)		Candidate%   
speaker_id
similaritymetadataFis_newr4   N)r5   r6   r7   r8   r9   r:   floatr   r   rD   boolr;   r4   r<   r=   r?   r?   %   s%    O38nFDr<   r?   c                   L    \ rS rSr% \\S'   \\   \S'   \S\SS 4S j5       r	Sr
g)	MatchTopKResultModel,   chosen
candidatesmatch_resultreturnc                 h   U " [        UR                  R                  UR                  R                  UR                  R                  UR                  R
                  S9UR                   Vs/ s H7  n[        UR                  UR                  UR                  UR
                  S9PM9     snS9$ s  snf )zCParse MatchTopKResult from speaker_registry to MatchTopKResultModel)rA   rB   rC   rD   )rJ   rK   )r?   rJ   rA   rB   rC   rD   rK   )clsrL   cs      r=   parseMatchTopKResultModel.parse0   s     '..99'..99%,,55#**11	 (22 3a  || ||ZZ88	
 3
 	
s   ,>B/
r4   N)r5   r6   r7   r8   r?   r:   r   classmethodr"   rQ   r;   r4   r<   r=   rH   rH   ,   s3    Y
 
5K 
 
r<   rH   c                   f    \ rS rSr% Sr\\   \S'   Sr\\	   \S'   Sr
\\	   \S'   Sr\\   \S'   Srg)TranscribeResponseE   Nr1   preprocess_metadatapostprocess_metadataspeakersr4   )r5   r6   r7   r8   r1   r   r9   r:   rW   dictrX   rY   rH   r;   r4   r<   r=   rU   rU   E   s>    D(3-*.$.+/(4.//3Hh+,3r<   rU   c                   *    \ rS rSr% \\S'   \\S'   Srg)PostSpeakerNameRequestL   rA   namer4   N)r5   r6   r7   r8   r9   r:   r;   r4   r<   r=   r\   r\   L   s    O
Ir<   r\   c                       \ rS rSr% \" SS9rSr\\   \	S'   Sr
\\\\4      \	S'   \\	S'   Sr\\   \	S'   Sr\\\\\4         \	S	'   S
rg)PostChatMessagesRequestQ   ignore)extraNqueryinputsuserconversation_idfilesr4   )r5   r6   r7   r8   r   model_configrd   r   r9   r:   re   r   rg   rh   r   r;   r4   r<   r=   r`   r`   Q   s`    H-LE8C='+FHT#s(^$+
I%)OXc]),0E8Dc3h()0r<   r`   c                       \ rS rSr% \\S'   Sr\\   \S'   Sr\\   \S'   Sr	\\   \S'   Sr
\\   \S'    " S S	5      rS
rg)PostChatMessagesResponse[   eventN
message_idrg   answer
created_atc                       \ rS rSrSrSrg)PostChatMessagesResponse.Configb   Tr4   N)r5   r6   r7   r8   exclude_noner;   r4   r<   r=   Configrr   b   s    r<   ru   r4   )r5   r6   r7   r8   r9   r:   rn   r   rg   ro   rp   intru   r;   r4   r<   r=   rk   rk   [   sI    J $J$%)OXc]) FHSM  $J$ r<   rk   c            O         ^  \ 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/\S0\S1\S2\S3\S4\S5\S6\S7\S8\4NU 4S9 jjjrS:\4S; jrS<\4S= jrS>\S:\4S? jrSHS@\S\S\	4SA jjrSB\4SC jrSD\SE\4SF jrSGrU =r$ )IAIAvatarHttpServerf   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: UTCzaiavatar.dbTrecorded_voicesg      $@F)'input_sample_rateopenai_api_keyopenai_base_urlopenai_modelsystem_promptvoicevox_speakervoicevox_urlstssttllmtts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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speaker_registryapi_keydebugr}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   c       '   
      
  > U=(       d    [        S!0 S[        5       _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U l        [        T(U ]  U R                  5        U%U l        U'U l        U&U l        [        SS 9U l
        g )"Nvadr   )r~   sample_rater   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   F
auto_errorr4   )r   r   r    r   super__init__r   r   r   r   _bearer_scheme))selfr}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   	__class__s)                                           r=   r   AIAvatarHttpServer.__init__g   s   l  &
+ &
#%&
  --+@/@	&
 &
  2C^&
 &8&
  /<&
 0@=&
 !4&
  !&
" .=#&
$ "6!I9I%&
(  )&
* .+&
, %<-&
. "6/&
0 (B1&
2 .3&
4  25&
6 .7&
8 09&
: #8;&
< "6=&
> *?&
@ $:A&
B  2C&
D '@E&
F *G&
H .I&
J K&
R 	" !1 
 (E:r<   rM   c                     SU R                   0$ )Nr   )r   )r   s    r=   
get_configAIAvatarHttpServer.get_config   s    TZZ
 	
r<   credentialsc                     U(       a8  UR                   R                  5       S:w  d  UR                  U R                  :w  a  [	        [
        R                  SS9eUR                  $ )NbearerzInvalid or missing API Key)status_codedetail)schemelowerr   r   r   r   HTTP_401_UNAUTHORIZED)r   r   s     r=   api_key_authAIAvatarHttpServer.api_key_auth   sV    k00668HDH_H_cgcocoHo"883  &&&r<   r1   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   r1   avreqface_pattarnfacesanimation_pattarn
animationss          r=   parse_avatar_control_request/AIAvatarHttpServer.parse_avatar_control_request   sp    $&L )

<.#AhEO"%E 3ZZ 18
#-a=E '*E$r<   pathc                   ^ ^^ [        5       n[        SS9nUR                  S5      [        U5      4S[        S[
        4U 4S jjj5       nUR                  U5      [        U5      4S[        S[
        4U 4S jjj5       nUR                  S[        S	S
9[        U5      4S[        S[
        4U 4S jjj5       nUR                  S5      [        S5      [        S 5      [        U5      4S[        S[        [           S[
        4U U4S jjj5       n	UR                  S5      [        U5      4S[        S[
        4U 4S jjj5       n
UR                  S5      [        U5      4S[        S[
        4U U4S jjj5       nU$ )NFr   z/startrequestr   c                   >^ #    T R                   (       d  [        SSS0S9$ TR                  (       a  TR                  U5        TR                   H  nU" T S 5      I S h  vN   M     U 4S jn[        U" 5       5      $  N7f)N  errorsession_id is required.r   contentc                    >#    [        ST R                  T R                  T R                  0 S9R	                  5       7v   g 7f)N	connected)type
session_iduser_id
context_idrC   )r,   r   r   r   model_dump_json)r   s   r=   stream_responseNAIAvatarHttpServer.get_api_router.<locals>.post_start.<locals>.stream_response
  s<     &$&11#OO&11 "/#$s   >A)r   r   r   r   _on_session_start_handlersr   )r   r   on_session_startr   r   s   `   r=   
post_start5AIAvatarHttpServer.get_api_router.<locals>.post_start   s}     
 %%# #$&?@ 
 ||!!+.$($C$C &w555 %D$ ''899 6s   AB A> B c                   >^ #    T R                   (       d  [        SSS0S9$ TR                  (       a  TR                  U5        TR                   H  nU" T 5      I S h  vN   M     U U4S jn[        U" 5       5      $  N7f)Nr   r   r   r   c                   >#    TR                   (       a%  [        R                  " TR                   5      Tl         TR                  R	                  [        TR                  TR                  TR                  TR                  TR                  TR                   TR                  TR                  TR                  S9	5        S h  vN n [        U R                  U R                  U R                  U R                  U R                  U R                  U R                   U R                   =(       d    0 S9nTR"                   H  nU" X5      I S h  vN   M     U R                  S:X  aw  U R$                  Ul        TR'                  U R                  5      Ul        U R                   (       a5  [        R*                  " U R                   5      R-                  S5      nX1l         U R                  S:X  a(  U R.                  R1                  5       UR                   S'   OU R                  S:X  aY  U R                  (       aG  [2        R4                  " SU R                  5      =n(       a  SUl        S	UR7                  S
5      0Ul        O)U R                  S:X  a  TR9                  U 5      I S h  vN   UR;                  5       7v   GM   GN GNs N 
 g 7f)N)	r   r   r   r   r1   
audio_datarh   system_prompt_paramswait_in_queue)r   r   r   r   r1   
voice_textr   rC   chunkzutf-8	tool_callfinalz\[vision:(\w+)\]visionsource   stop)r   base64	b64decoder   invoker   r   r   r   r   r1   rh   r   r   r,   r   rC   _on_response_handlersr3   r   avatar_control_request	b64encodedecoder   to_dictr   searchgroupstop_responser   )responseaiavatar_responseon_resp	b64_chunkimage_source_matchr   r   s        r=   r   MAIAvatarHttpServer.get_api_router.<locals>.post_chat.<locals>.stream_response'  s>    %%)/)9)9':L:L)MG&&*hhooj &11#OO&11 &11!--)0)E)E")"7"7
7 
' 2>( )9%]]#+#6#6 ( 0 0#+#6#6%]]#+#6#6#+#6#6!)!2!2!8b	)% $(#=#=%&7BBB $>  }}/5=5F5F)2 DHCdCdemererCs)@ $..(.(8(89L9L(M(T(TU\(]I;D8}}3BJBTBTB\B\B^)22;?!'1#==57YY?RT\TaTa5bb1b9A 1 6<DFXF^F^_`Fa;b 1 :!&0"00:::+;;==e2>0 C0 ;a
'sP   B;K>KJ:KBK
J=EKK  K:K=K KK)r   r   r   r   _on_request_handlersr   )r   r   on_reqr   r   s   `   r=   	post_chat4AIAvatarHttpServer.get_api_router.<locals>.post_chat  s|     
 %%# #$&?@ 
 ||!!+. 33Wo%% 46>p ''899u &s   AB A> B z/chat-messageszDify-compatible endpoint)response_modelsummaryc                    >^ ^#    TR                   (       a  TR                  U5        TR                   H  nU" T 5      I S h  vN   M     S[        5        3mUU U4S jn[	        U" 5       5      $  N-7f)Nmessage_c                 D  >#    S n TR                   R                  [        STR                  =(       d    ST 3TR                  TR                  TR
                  TR                  TR                  S95        S h  vN nU (       d  [        [        R                  " 5       5      n TR                   H  nU" S U5      I S h  vN   M     UR                  S:X  aV  [        UR                  R                  S5      SL a  SOSTUR                  UR                   U S	9nUR#                  5       7v   M  UR                  S
:X  a*  [        STUR                  S9nUR#                  5       7v   M  UR                  S:X  d  GM  TR%                  U5      I S h  vN   GM!   GN N N
 g 7f)Nstart
sess_temp_)r   r   r   r   r1   rh   r   r   is_guardrail_triggeredTmessage_replacemessage)rm   rn   rg   ro   rp   r   message_end)rm   rn   rg   r   )r   r   r   rg   rf   rd   rh   re   rv   timer   r   rk   rC   getr   r1   r   r   )created_at_intr   r   chat_messages_responsern   r   r   s       r=   r   VAIAvatarHttpServer.get_api_router.<locals>.post_chat_messages.<locals>.stream_responsen  sk    !%&*hhooj &66SJzl:S#LL&66 !--)07 ' #;( *),TYY[)9 $(#=#=%dH555 $>  }}/1I7?7H7H7L7LMe7fjn7n"3t}'1,4,?,?#+=='52. 5DDFF!'11I"/'1,4,?,?2.
 5DDFF!&0"00:::G#; 6* ;G'sV   A3F 6F:F;F>AF ?F B6F ;F FF FF F F )r   r   r   r	   r   )r   r   r   r   rn   r   s   `   @r=   post_chat_messages=AIAvatarHttpServer.get_api_router.<locals>.post_chat_messagesa  sh     
 ||!!+. 33Wo%% 4 $EG9-J%;N ''899U &s   =A2A0.A2z/transcribe.audior   c                   >#    TR                   (       a  TR                  U5        U R                  5       I S h  vN nU(       d  [        SSS0S9$ T	=(       d    TR                  R
                  R                  XS9I S h  vN nS nTR                  (       a^   TR                  R                  UT	=(       d    TR                  R
                  R                  S9nU(       a  [        R                  U5      n[        UR                   UR"                  UR$                  US9$  N N! [         a"  n[        R                  SU 35         S nANUS nAff = f7f)	Nr   r   zaudio data is required.r   )r   data)audio_bytesr   zError at speaker matching: )r1   rW   rX   rY   )r   r   readr   r   r   	recognizer   match_topk_from_pcmr   rH   rQ   	ExceptionloggerwarningrU   r1   rW   rX   )
r  r   r   r  resultrY   rL   exr   r   s
           r=   post_transcribe:AIAvatarHttpServer.get_api_router.<locals>.post_transcribe  sG     ||!!+. %

,K# #$&?@ 
  /488<<::j:ccFH$$G#'#8#8#L#LYdsv  tGz~  {C  {C  {G  {G  sT  sT#L  $UL##7#=#=l#K &[[$*$>$>%+%@%@!	 ' - d ! GNN%@#EFFGsM   6ED AE D"EAD$ 6+E"E$
E.EEEEz/transcribe/speakerc                 &  >#    TR                   (       a  TR                  U5        TR                  (       aQ  TR                  R                  U R                  SU R
                  5        [        U R                  U R
                  S.S9$ [        0 S9$ 7f)Nr^   )rA   r^   )r   )r   r   r   set_metadatarA   r^   r   )r   r   r   s     r=   post_transcribe_speakerBAIAvatarHttpServer.get_api_router.<locals>.post_transcribe_speaker  sp     
 ||!!+.$$%%2273E3Evw||\#7;M;MW^WcWc,dee#B//s   BBz/synthesizec                 P  >#    TR                   (       a  TR                  U5        U R                  (       d  [        SSS0S9$ T=(       d    TR                  R
                  R                  U R                  U R                  U R                  S9I S h  vN n[        USSS0S	9$  N7f)
Nr   r   ztext is required.r   )r1   r2   r3   z	audio/wavzContent-Dispositionzattachment; filename=voice.wav)r   
media_typeheaders)
r   r   r1   r   r   r   
synthesizer2   r3   r   )r   r   r  r   r   s      r=   post_synthesize:AIAvatarHttpServer.get_api_router.<locals>.post_synthesize  s     
 ||!!+.<<# #$&9: 
 "%!4 @ @\\"-- )) !A ! K #&.0PQ s   BB&B$B&)r
   r   postr   r+   r   rk   r`   r   r   r   r   r9   r\   r/   )r   r   r   r   routerbearer_schemer   r   r  r   r$  r*  s   ` ``        r=   get_api_router!AIAvatarHttpServer.get_api_router   s   "e4	X	 9@8N	:$	:5	: 
	:6 
T	 9@8NI	:$I	:5I	: 
I	:V 
%6NXr	s 9@8N3	:,3	:53	: 
t3	:j 
]	# $S	(,T
8?8N 	 	  	 6 	  	 
$ 	D 
*	+ 9@8N	0+	05	0 
,	0 
]	# 9@8N	&	5	 	 
$	2 r<   r   c                    #    g 7fNr4   )r   r   s     r=   handle_response"AIAvatarHttpServer.handle_response          r   r   c                    #    g 7fr2  r4   )r   r   r   s      r=   r    AIAvatarHttpServer.stop_response  r5  r6  )r   r   r   r   r   )z/chatNN) r5   r6   r7   r8   rv   r9   r   r   r#   r%   r$   r   rE   r   r&   r'   r(   rF   r!   r   rZ   r   r   r   r*   r   r/  r   r3  r   r;   __classcell__)r   s   @r=   rx   rx   f   s   
 "'"#%! "4   $!%  %"& "!%.2 8$&#"&), %X,/ :"')-!.5948(,'+"3+/ $!& -1 gi; 	i;
 i; i; i; i; i; i; i; i; i;  !i;& 'i;(  )i;* +i;, -i;. /i;0 ,1i;2 3i;4 "5i;6 97i;8  9i;: "';i;< "=i;> %*?i;@ Ai;B  Ci;D 'Ei;F Gi;H  3Ii;J 2Ki;L &Mi;N !%Oi;P  Qi;R $)Si;T Ui;V Wi;\ *]i;b ci;f gi; i;V
D 

'(D ' 9M ,m3 m7G mUf m^k c s  r<   rx   )Nr   loggingr   r  typingr   r   r   r   r   r   uuidr	   fastapir
   r   r   r   r   r   r   r   fastapi.responsesr   r   fastapi.securityr   r   sse_starlette.sser   pydanticr   r   databaser   r   r   
sts.modelsr   r   sts.vadr   sts.sttr   sts.stt.openair    sts.stt.speaker_registryr!   r"   sts.llmr#   sts.llm.context_managerr$   sts.ttsr%   sts.session_state_managerr&   sts.performance_recorderr'   sts.voice_recorderr(   modelsr*   r+   r,    r-   	getLoggerr5   r  r/   r?   rH   rU   r\   r`   rk   rx   r4   r<   r=   <module>rQ     s      	  A A  ^ ^ ^ 4 E 1 * $  1 * ' 4 H ! 5 ( < ; / L L 			8	$#	 #	 
9 
24 4Y 
1i 1y D Dr<   