
    љi>                        S SK J r Jr  S SKrS SKJr  S SKrS SKJrJrJ	r	J
r
Jr  S SKJr  S SKrS SKJr  S SK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"J#r#J$r$J%r%J&r&  S SK'J(r(J)r)J*r*J+r+J,r,J-r-  SSK.J/r/  SSK0J1r1  SSK2J3r3J4r4  SSK5J6r6  SSK7J8r8  SSK9J:r:  SSK;J<r<  SSK=J>r>  SSK?J@r@  SSKAJBrB  SSKCJDrD  SSKEJFrF  SSKGJHrHJIrIJJrJ  \R                  " \L5      rM " S S\5      rN " S S \F5      rOg)!    )datetimetimezoneN)Path)DictTupleOptional	AwaitableCallable)uuid4)	BaseModel)	APIRouterHTTPExceptionstatusRequestBackgroundTasksDepends)ResponseJSONResponse)
HTTPBearerHTTPAuthorizationCredentials)WebhookParser)ConfigurationAsyncApiClientAsyncMessagingApiAsyncMessagingApiBlobTextMessageReplyMessageRequest)EventMessageEventTextMessageContentStickerMessageContentLocationMessageContentImageMessageContent   )PoolProvider)STSPipeline)
STSRequestSTSResponse)SpeechDetectorDummy)SpeechRecognizerDummy)
LLMService)ContextManager)SpeechSynthesizerDummy)SessionStateManager)PerformanceRecorder   )AvatarControlRequest)Adapter   )LineBotSessionLineBotSessionManagerSQLiteLineBotSessionManagerc                   f    \ rS rSr% \\S'   \\S'   \\S'   Sr\\   \S'   Sr\\	   \S'   \
\S'   S	rg)
GetSessionResponse0   
session_idlinebot_user_iduser_idN
context_id
updated_atdata )__name__
__module____qualname____firstlineno__str__annotations__r=   r   r>   r   r   __static_attributes__r@       Y/home/james-whalen/.local/lib/python3.13/site-packages/aiavatar/adapter/linebot/server.pyr8   r8   0   s4    OL $J$%)J")
JrH   r8   c            7         ^  \ 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'\46U 4S( jjjrS)\4S* jrS+\4S, jrS-\\/\S   4   4S. jrS/\S)\\\4   4S0 jrS/\S)\\\4   4S1 jrS/\S)\\\4   4S2 jrS/\S)\\\4   4S3 jr S4\S5\S)\4S6 jr!S-\\"/\S   4   4S7 jr#S-\\$/\S   4   4S8 jr%S9\4S: jr&S-\\'\/\S   4   4S; jr(S<\'S=\4S> jr)S?\S@\4SA jr*S<\+4SB jr,S-\\-\\+\./\S   4   4SC jr/S<\+S=\SD\.4SE jr0SF\S)\14SG jr2S-\\1\-/\S   4   4SH jr3SI\$4SJ jr4SK\SL\4SM jr5SN r6SOr7U =r8$ )PAIAvatarLineBotServer:   Ni  linebot_imagesu
   Error 😢zgpt-4.1g        z$Current date and time: UTCzaiavatar.dbF)channel_access_tokenchannel_secretlinebot_session_timeoutimage_upload_dirimage_download_url_basedefault_error_messagesession_manageropenai_api_keyopenai_base_urlopenai_modelsystem_promptstsllmllm_openai_api_keyllm_base_url	llm_modelllm_system_promptllm_context_managertimestamp_interval_secondstimestamp_prefixtimestamp_timezonedb_pool_providerdb_connection_strsession_state_managerperformance_recorderapi_keydebugrO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   rg   rh   ri   c                  > U=(       dx    [        S0 S[        5       _S[        5       _SU_SU=(       d    U_SU=(       d    U	_SU=(       d    U
_SU=(       d    U_SU_S	[        5       _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        [        SS9U l
        [        US9n[        U5      U l        [        U R                  5      U l        [!        U R                  5      U l        [%        U5      U l        SU R(                  0U l        S U l        U R.                  U R0                  U R2                  U R4                  S.U l        U=(       d	    [9        US9U l        X0l        [?        U5      U l         XPl!        S U l"        S U l#        S U l$        S U l%        S U l&        X`l'        g )Nvadsttr[   r\   r]   r^   r_   r`   ttsra   rb   rc   rd   re   rf   rg   ri   F
auto_error)access_tokenmessage)textimagestickerlocation)db_pathr@   )(r&   r)   r*   r-   rZ   super__init__ri   rh   r   _bearer_schemer   r   line_api_clientr   line_apir   line_api_blobr   webhook_parserhandle_message_event_event_handlers_default_event_handlerparse_text_messageparse_image_messageparse_sticker_messageparse_location_message_message_parsersr6   rU   rQ   r   rR   rS   _edit_linebot_session_preprocess_request_preprocess_response_process_avatar_control_request_on_send_error_messagerT   )selfrO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   rg   rh   ri   line_api_configuration	__class__s                                rI   rx   AIAvatarLineBotServer.__init__;   s   R  
+ 
#%
 ()	
 
  2C^
 &8
  /<
 0@=
 !4
 '(
 (B
  .!
"  2#
$ .%
& 0'
( #8)
* "6+
, -
4 	" 
 (E: "/-"
  ..DE)$*>*>?243G3GH+N; t00 
 '+#++--1133	!
  /  
2M%3
 (?$ !%%5 6'>$%)"#' $(!/3,&*#%:"rH   returnc                 J    U R                   U R                  U R                  S.$ )NrQ   rT   ri   r   )r   s    rI   
get_config AIAvatarLineBotServer.get_config   s%    '+'C'C%)%?%?ZZ
 	
rH   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   rh   r   r   HTTP_401_UNAUTHORIZED)r   r   s     rI   api_key_auth"AIAvatarLineBotServer.api_key_auth   sV    k00668HDH_H_cgcocoHo"883  &&&rH   funcc                     Xl         U$ N)r   r   r   s     rI   edit_linebot_session*AIAvatarLineBotServer.edit_linebot_session   s    %)"rH   rq   c                 &   #    UR                   S 4$ 7fr   rr   r   rq   s     rI   r   (AIAvatarLineBotServer.parse_text_message   s     ||T!!s   c                 l   #    SU R                   R                  UR                  5      I S h  vN 4$  N7f)N )r|   get_message_contentidr   s     rI   r   )AIAvatarLineBotServer.parse_image_message   s+     ++??

KKKKKs   *424c                 x   #    SR                  UR                   Vs/ s H  o"PM     sn5      nSU 3S 4$ s  snf 7f)Nz, z3You received a sticker from user in messenger app: )joinkeywords)r   rq   ksticker_keywordss       rI   r   +AIAvatarLineBotServer.parse_sticker_message   sF     991A1A%B1AAa1A%BCDEUDVWY]]] &Cs   :5:c                 `   #    SUR                    SUR                   SUR                   3S 4$ 7f)NzHYou received a location info from user in messenger app:
    - address: z
    - latitude: z
    - longitude: )addresslatitude	longituder   s     rI   r   ,AIAvatarLineBotServer.parse_location_message   so     Z[b[j[jZkk}  F  O  O  ~P  Pc  dk  du  du  cv  w  y}  }  	}s   ,.r<   image_bytesc                   #    U S[        5        3nU R                  R                  5       (       d  U R                  R                  5         [	        U R                  U S3-  5      n[
        R                  " US5       IS h  vN nUR                  U5      I S h  vN   S S S 5      IS h  vN   U$  N/ N N
! , IS h  vN  (       d  f       U$ = f7f)N_.pngwb)r   rR   existsmkdirr   aiofilesopenwrite)r   r<   r   image_id
image_pathfs         rI   
save_image AIAvatarLineBotServer.save_image   s     Yay)$$++--!!'')$//XJd2CCD
==T22a''+&&& 32  3& 322 sZ   A?CB1CB7B3B7C*B5+C3B75C7C=C >C
Cc                     Xl         U$ r   )r   r   s     rI   preprocess_request(AIAvatarLineBotServer.preprocess_request   s    #' rH   c                     Xl         U$ r   )r   r   s     rI   preprocess_response)AIAvatarLineBotServer.preprocess_response   s    $(!rH   
event_typec                    ^ ^ UU 4S jnU$ )Nc                 &   > U TR                   T'   U $ r   )r   )r   r   r   s    rI   	decorator.AIAvatarLineBotServer.event.<locals>.decorator   s    /3D  ,KrH   r@   )r   r   r   s   `` rI   eventAIAvatarLineBotServer.event   s    	 rH   c                     Xl         U$ r   )r   r   s     rI   default_event_handler+AIAvatarLineBotServer.default_event_handler       &*#rH   r   linebot_sessionc                   #    U R                   R                  UR                  R                  5      =n(       a  U" UR                  5      I S h  vN u  pEO-[        R                  SUR                  R                   35        g S nU(       a6  U R                  UR                  US9I S h  vN nSU R                   SU 30/n[        UR                  UR                  UR                  UUS9nU R                  (       a  U R                  U5      I S h  vN   U R                  R                  U5        S h  vN n	U	R                  (       d  0 U	l        UR                   U	R                  S'   U	R                  Ul        U	R                  S:X  aJ  ["        R$                  " [&        R(                  5      Ul        U R,                  R/                  US9I S h  vN   U R                  R1                  U	5      I S h  vN   M   GN GNV N N N3 N
 g 7f)	NzUnhandled message type: )r<   r   urlz/image/)r:   r<   r=   rr   filesreply_tokenfinal)r   )r   getrq   typeloggerinfor   r<   rS   r'   r   r=   r   rZ   invokemetadatar   r   nowr   utcr>   rU   upsert_sessionhandle_response)
r   r   r   message_parserrr   r   r   r   requestresponses
             rI   r~   *AIAvatarLineBotServer.handle_message_event   s    !2266u}}7I7IJJ>J&4U]]&C CD+KK25==3E3E2FGH!___5L5LZe_ffH < <=WXJOPQE&))#++&11
 ##**7333"hhoog6 	5($$$&!/4/@/@Hm,)1)<)<O&}}'-5\\(,,-G***99/9ZZZ((**8444; !D g 4	5 [4 7s   AHG<AH)G?*A(HHH2H
6H7H
:BHH"H5H6H?HHH
HH
Hrequest_body	signaturec                    #    U R                   R                  X5       H  nU R                  U5      I S h  vN   M     g  N	7fr   )r}   parseprocess_event)r   r   r   r   s       rI   process_webhook%AIAvatarLineBotServer.process_webhook  s8     ((..|GE$$U+++ H+s   3A?
Ac                 @  #    S n U R                   R                  UR                  5      =(       d    U R                  =n(       aq  U R                  R                  UR                  R                  5      I S h  vN nU R                  (       a  U R                  U5      I S h  vN   U" UUS9I S h  vN   g [        R                  SU 35        g  NW N/ N"! [         a<  n[        R                  SU 35        U R                  UUUS9I S h  vN     S nAg S nAff = f7f)N)r   r   zUnhandled event: zError at process_event: )r   r   ex)r   r   r   r   rU   get_sessionsourcer<   r   r   r   	Exception	exceptionsend_error_message)r   r   r   event_handlerr   s        rI   r   #AIAvatarLineBotServer.process_event  s    	 $ 4 4 8 8 D cHcHcc}c(,(<(<(H(HI]I](^"^--44_EEE#$3  
 /w78 #_E  	7w?@)) / *   	s}   DA1C 7C8)C !C"C 0C1C 5D6C DC C C 
D,DDDDDDc                     Xl         U$ r   )r   r   s     rI   on_send_error_message+AIAvatarLineBotServer.on_send_error_message,  r   rH   r   c                    #    [        US5      (       d  g [        UR                  [        U R                  S9/S9nU R
                  (       a  U R                  XBX5      I S h  vN   U R                  R                  U5      I S h  vN   g  N( N7f)Nr   r   
replyTokenmessages)hasattrr   r   r   rT   r   r{   reply_message)r   r   r   r   reply_message_requests        rI   r   (AIAvatarLineBotServer.send_error_message0  s     um,, 3((!t'A'ABC!

 &&--.CV[```mm))*?@@@ a@s$   AB!B
""BBBBrr   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+)\])r1   refindall	face_nameface_durationanimation_nameanimation_duration)r   rr   avreqface_pattarnfacesanimation_pattarn
animationss          rI   parse_avatar_control_request2AIAvatarLineBotServer.parse_avatar_control_request?  sp    $&L )

<.#AhEO"%E 3ZZ 18
#-a=E '*E$rH   c                     Xl         U$ r   )r   r   s     rI   process_avatar_control_request4AIAvatarLineBotServer.process_avatar_control_requestU  s    /3,rH   r   c                   #    UR                   S:X  a  U R                  (       a  U R                  U5      I S h  vN   [        UR                  S   [	        UR
                  S9/S9nU R                  UR                  5      nU R                  (       a  U R                  X25      I S h  vN   U R                  R                  U5      I S h  vN   g g  N N+ N
7f)Nr   r   r   r  )r   r   r   r   r   
voice_textr  rr   r   r{   r  )r   r   r  avatar_control_requests       rI   r   %AIAvatarLineBotServer.handle_responseY  s     ==G#((//999 %8#,,];%8+>+>?@%! &*%F%Fx}}%U"33::;Qiii ----.CDDD# $ : j Es4   6CCA-C&C'"C	C
CCCr:   r=   c                    #    g 7fr   r@   )r   r:   r=   s      rI   stop_response#AIAvatarLineBotServer.stop_responsem  s     s   c                 z  ^  [        5       n[        SS9nUR                  S5      S[        S[        4U 4S jj5       nUR                  S5      S[        4U 4S	 jj5       nUR                  S
5      [        U5      4S[        4U 4S jjj5       nUR                  S
5      [        U5      4S[        4U 4S jjj5       nU$ )NFrn   z/webhookr   background_tasksc                    >#    UR                  TR                  U R                  5       I S h  vN R                  S5      U R                  R                  SS5      S9  g N17f)Nzutf-8zX-Line-Signaturer   )r   r   ok)add_taskr   bodydecodeheadersr   )r   r!  r   s     rI   post_webhook:AIAvatarLineBotServer.get_api_router.<locals>.post_webhookv  sX     %%$$$+LLN2::7C!//--.@"E & 
  3s   *A!A
2A!z/image/{image_id}r   c                 $  >#    [         R                  " [        TR                  U  S3-  5      S5       IS h  vN nUR	                  5       I S h  vN n[        USS9sS S S 5      IS h  vN   $  N7 N! N	! , IS h  vN  (       d  f       g = f7f)Nr   rbz	image/png)content
media_type)r   r   r   rR   readr   )r   fsr   r   s      rI   	get_image7AIAvatarLineBotServer.get_api_router.<locals>.get_image  sg     }}T$*?*?XJdBS*S%TVZ[[_a$&GGIoL \[[- \[[[sV   5BA0BA6A2A6B*A4+B2A64B6B<A?=B	Bz/session/{line_user_id}r   c           	      V  >#    TR                   (       a  TR                  U5        TR                  R                  U 5      I S h  vN nU(       d  [	        SSU  3S9e[        UR                  UR                  UR                  UR                  UR                  UR                  S9$  Nb7f)N   No session found: line_user_id: r   )r:   r;   r<   r=   r>   r?   )rh   r   rU   r   r   r8   r   r;   r<   r=   r>   r?   line_user_idr   sessionr   s      rI   r   9AIAvatarLineBotServer.get_api_router.<locals>.get_session  s     
 ||!!+. 00<<\JJG#>^_k^l<mnn%":: ' 7 7"--"--\\ 	 Ks   AB)B'A#B)c                   >#    TR                   (       a  TR                  U5        TR                  R                  U S9I S h  vN nU(       d  [	        SSU  3S9eTR                  R                  U S9I S h  vN   [        SS0S9$  ND N7f)N)r;   r3  r4  r   resultsuccess)r,  )rh   r   rU   r   r   delete_sessionr   r5  s      rI   r<  <AIAvatarLineBotServer.get_api_router.<locals>.delete_session  s     
 ||!!+. 00<<\<ZZG#>^_k^l<mnn&&55l5SSS9(=>> [ Ts#   ?BB4B7B	8B	B)
r   r   postr   r   r   rE   r   r   delete)r   routerbearer_schemer(  r0  r   r<  s   `      rI   get_api_router$AIAvatarLineBotServer.get_api_routerr  s    "e4	Z	 	 	? 	 
!	 
'	(	Mc 	M 
)	M
 
-	. 9@8N	5	 
/	( 
0	1 9@8N	?5	? 
2	? rH   )ry   r   r   r   r   r   r   r   r   rh   ri   rT   rS   rR   r{   r|   rz   rQ   rU   rZ   r}   )9rA   rB   rC   rD   rE   floatr5   r&   r+   r,   r%   r.   r/   boolrx   dictr   r   r   r
   r4   r	   r   r    r   bytesr   r#   r   r!   r   r"   r   r   r'   r   r(   r   r   r   r   r~   r   r   r   r   r   r   r   r1   r  r  r   r  rB  rG   __classcell__)r   s   @rI   rK   rK   :   s    %)")- 0'+%115 ##%!   #' "!%.2,/ :"')-!.5948 Mp; "p; 	p;
 "'p; p; "%p;  #p; /p; p; p; p; p;$ %p;& 'p;,  -p;. /p;0 1p;2 3p;4 ,5p;6 %*7p;8 9p;:  ;p;< '=p;> ?p;@  3Ap;B 2Cp;H Ip;L Mp; p;d
D 
'(D '>2BIdO2S)T 
"0B "uSRWZGX "L1D LsTYzIZ L^3H ^USVX]S]M^ ^}4J }uUXZ_U_O` }	 	% 	C 	xio0M'N +	$1O(P 
 (L.3QS\]aSb3b*c 5 5~ 5D,# ,# ,
 ,(4GY^`i3jluvzl{3{*| Ae An AZc A 9M ,8=QSf<girswix<x3y Ek E(c s 
8 8rH   rK   )Pr   r   loggingpathlibr   r	  typingr   r   r   r	   r
   uuidr   r   pydanticr   fastapir   r   r   r   r   r   fastapi.responsesr   r   fastapi.securityr   r   
linebot.v3r   linebot.v3.messagingr   r   r   r   r   r   linebot.v3.webhooksr   r   r    r!   r"   r#   databaser%   rZ   r&   
sts.modelsr'   r(   sts.vadr)   sts.sttr*   sts.llmr+   sts.llm.context_managerr,   sts.ttsr-   sts.session_state_managerr.   sts.performance_recorderr/   modelsr1   r   r2   rU   r4   r5   r6   	getLoggerrA   r   r8   rK   r@   rH   rI   <module>r_     s    '   	 = =    W W 4 E $   %  1 * , ! 5 - < ; )  _ _			8	$ pG prH   