
    #i                        S SK JrJrJrJrJ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  S SK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JrJrJrJr  S SK J!r!J"r"J#r#  S S	K$J%r%J&r&  S S
K'J(r(  \" \)5      r*\+" \5      \*RX                  S'   S\*RX                  S'   \-" \R\                  R_                  SS5      5      r0\!" \)5      r1\" 5       r2\
Rf                  " 5       r4\" \5      S-  S-  r5Sr6Sr7\r80 q90 q:\
Rv                  " 5       r<\
Rv                  " 5       r=\
Rv                  " 5       r>S r?S r@SLS jrA\64S jrBSMS jrC\?" 5         S rDS rES rFSNS jrGSOS jrHS rIS rJ\D" 5         S  rKS! rLS" rMS# rN\*R                  S$5      S% 5       rP\*R                  S&S'/S(9S) 5       rQ\*R                  S*S'/S(9S+ 5       rR\*R                  S,S'/S(9S- 5       rSS. rTS/ rUS0 rV\*R                  S1S2/S(9S3 5       rW\*R                  S45      S5 5       rX\*R                  S65      S7 5       rY\*R                  S85      S9 5       rZ\*R                  S:S2/S(9S; 5       r[\*R                  S<5      S= 5       r\\*R                  S>S'/S(9S? 5       r]SMS@ jr^SPSA jr_SB r`\*R                  SCS2/S(9SD 5       ra\*R                  SES2/S(9SF 5       rb\)SG:X  a"  \c" SH5        \c" SI5        \*R                  \\SJSK9  gg)Q    )Flaskrequestjsonifyrender_templatesend_from_directoryN)ThreadPoolExecutoras_completedsecure_filenamePath)	RAGSystem)
PDF_DIRPROCESSED_DIRWEB_HOSTWEB_PORT	NOTES_DIRDOCUMENTS_DIRENRICHMENT_DEFAULT_THREADSENRICHMENT_MAX_THREADSENRICHMENT_STATUS_PATHENRICHMENT_LOG_PATH)
get_loggerlog_performancelog_error_with_context)FileUploadErrorValidationError)RAGAgentUPLOAD_FOLDERi   MAX_CONTENT_LENGTHMAX_CONCURRENT_UPLOADS   metadatazprocessing_status.jsoni  i,  c                  J   [         R                  5       (       a1   [        [         S5       n [        R                  " U 5      qSSS5        g0 qg! , (       d  f       g= f! [        R                  [        [        4 a$  n[        R                  SU 35        0 q SnAgSnAff = f)z Load processing status from filerNz"Failed to load processing status: )PROCESSING_STATUS_FILEexistsopenjsonloadprocessing_statusJSONDecodeErrorIOErrorOSError
app_loggerwarningfes     0/var/www/html/leadgen/backtest/airagagent/app.pyload_processing_statusr5   6   s     $$&&	#,c2a$(IIaL! 32  32$$gw7 	#!CA3GH "	#s4   A AA 
AA A B">BB"c                  (    [         R                  R                  SSS9  [        [         S5       n [        R
                  " [        U SS9  SSS5        g! , (       d  f       g= f! [         a"  n[        R                  SU 35         SnAgSnAff = f)zSave processing status to fileTparentsexist_okw   indentNz"Failed to save processing status: )
r&   parentmkdirr(   r)   dumpr+   	Exceptionr/   errorr1   s     r4   save_processing_statusrC   C   u    C%%++D4+H(#.!II'15 /.. C=aSABBC4   .A% AA% 
A"A% "A% %
B/BBc                 v   [         R                   " 5       n[        U 5      n[           [        R	                  U0 5      R                  5       nU=(       d    0 nSU;  a  UR	                  SU5      US'   SU;  a  SU;   a  US   US'   SU;  a  SU;   a  US   US'   SU;  a  SU;   a  US   US'   XgS'   UR                  UUUUS.5        UR                  5        H  u  pUS;  d  M  XU'   M     [        XWR	                  SU5      -
  S5      US	'   U[        U'   [        5         S
S
S
5        g
! , (       d  f       g
= f)z=Update processing status for a file with persistent metadata.
started_at	file_size	client_iporiginal_namefilename)statusprogressmessageupdated)rG   rH   rI   rJ   r;   elapsed_secondsN)
timer   status_lockr+   getcopyupdateitemsroundrC   )
rK   rL   rM   rN   extranowsafe_filenameentrykeyvalues
             r4   update_processing_statusr^   L   s;   
))+C#H-M	!%%mR8==?u$"'))L#">E,e#u(<!&{!3E+e#u(<!&{!3E+%'Ou,D%*?%;E/")j 	
 	  ++-JCSS"c
 ( $)yys/K)KQ#O +0-( 5 
s   B:D*%<D**
D8c           	         [         R                   " 5       nSn[           [        [        R	                  5       5       Hv  n[        R                  U0 5      nUR                  S5      nUR                  SUR                  SU5      5      nUS;   d  MT  X-
  U :  d  M^  [        R                  US5        SnMx     U(       a
  [        5         SSS5        g! , (       d  f       g= f)zORemove stale completed/failed processing entries to keep the status file small.FrL   rO   rG   )	completedfailedNT)rQ   rR   listr+   keysrS   poprC   )retention_secondsrY   removedrK   r[   rL   rO   s          r4   cleanup_processing_statusrg   l   s    
))+CG	.3356H%))(B7EYYx(Fii	599\3+GHG00cmGX5X!%%h5 7 "$ 
s   A.CC-C
Cc                    U=(       d    [         R                   " 5       nUR                  5       nXS'   UR                  S5      =(       d    UR                  S5      =(       d    UnXCS'   UR                  SU5      nXSS'   [        X$-
  S5      US'   X%-
  n[        US5      US'   UR                  S5      S	:H  =(       a	    U[        :  US
'   U$ )z5Prepare a processing status entry for JSON responses.rK   rG   rO   last_updater;   rP   stale_secondsrL   
processingstale)rQ   rT   rS   rW   !PROCESSING_STATUS_STALE_THRESHOLD)rK   r[   rY   
normalizedstartedri   	stale_ages          r4   normalize_processing_entryrq   {   s    

CJ%znn\*NjnnY.GN3G&|..G4K +}$)#-$;J !!I"'	1"5J$..2lBtyStGtJw    c            	         SSSSS[         0 [        R                  " 5       S.n [        R                  5       (       a1   [	        [        S5       n[
        R                  " U5      qSSS5        OU R                  5       q[        R                  S0 5        [        R                  S[         5        [        R                  S	[        R                  " 5       5        g! , (       d  f       Nh= f! [         a    U R                  5       q Nf = f)
z Load enrichment status from fileidler    )rL   rM   rN   files_processedtotal_filesthread_countactive_fileslast_activityr%   Nry   rx   rz   )r   rQ   ENRICHMENT_STATUS_FILEr'   r(   r)   r*   enrichment_statusrA   rT   
setdefault)default_statusr2   s     r4   load_enrichment_statusr      s     2	N $$&&	6,c2a$(IIaL! 32
 +//1  4  1KL  $))+> 32 	6 . 3 3 5	6s/   C( C$C( 
C%!C( %C( (DDc                  (    [         R                  R                  SSS9  [        [         S5       n [        R
                  " [        U SS9  SSS5        g! , (       d  f       g= f! [         a"  n[        R                  SU 35         SnAgSnAff = f)zSave enrichment status to fileTr7   r:   r;   r<   Nz"Failed to save enrichment status: )
r{   r>   r?   r(   r)   r@   r|   rA   r/   rB   r1   s     r4   save_enrichment_statusr      rD   rE   c                    [         R                   " 5       U S.UEn [        R                  R                  SSS9  [           [        [        S5       nUR                  [        R                  " U5      S-   5        SSS5        SSS5        g! , (       d  f       N= f! , (       d  f       g= f! [         a"  n[        R                  SU 35         SnAgSnAff = f)z2Append enrichment events to log file for auditing.)	timestampeventTr7   a
Nz&Failed to write enrichment log entry: )rQ   r   r>   r?   enrichment_log_lockr(   writer)   dumpsrA   r/   debug)
event_typepayloadr[   r2   excs        r4   log_enrichment_eventr      s     YY[ E
I""(((E )3/1

5)D01 0 ! // !   IA#GHHIsM   $B-  B)B:BB- 
B	B
B*&B- *B- -
C7CCc                    Uc  [         R                  S[        5      n[           [         R	                  U UUUU[
        R
                  " 5       [
        R
                  " 5       US.5        [        5         SSS5        g! , (       d  f       g= f)zUpdate enrichment statusNrx   )rL   rM   rN   rv   rw   rO   rz   rx   )r|   rS   r   rR   rU   rQ   r   )rL   rM   rN   rv   rw   rx   s         r4   update_enrichment_statusr      sg    (,,^=WX	   .&yy{!YY[(	"
 		 	  
s   AA<<
B
c                    [            [        R                  S0 5      nUR                  U 0 5      nUb  [        U5      US'   Ub  [        U5      US'   U(       a  X5S'   [        R                  " 5       US'   [        R                  " 5       [        S'   U(       a"  [        R                  S5      S:w  a	  S[        S'   [        5         S S S 5        g ! , (       d  f       g = f)	Nry   chunktotal_chunksrN   rO   rz   rL   running)rR   r|   r}   intrQ   rS   r   )	file_namechunk_indexchunk_totalrN   activer[   s         r4   update_enrichment_file_activityr      s    	"--nbA!!)R0" -E'N"$'$4E.!&)99;i-1YY[/*'++H5B*3h'  
s   B=C
Cc                     [            [        R                  S0 5      nX;   a8  UR                  U S 5        [        R                  " 5       [        S'   [        5         S S S 5        g ! , (       d  f       g = fNry   rz   )rR   r|   r}   rd   rQ   r   )r   r   s     r4   clear_enrichment_file_activityr      sL    	"--nbAJJy$'15o."$ 
s   AA$$
A2c                      [            0 [        S'   [        R                  " 5       [        S'   [        5         S S S 5        g ! , (       d  f       g = fr   )rR   r|   rQ   r    rr   r4   clear_all_enrichment_activityr      s1    	,..)-1YY[/*  
s   0A  
Ac                  r    [        [        S5      (       d  [        5       [        l        [        R                  $ )z5Get or create a thread-local RAGAgent for enrichment.	rag_agent)hasattrthread_local_agentr   r   r   rr   r4   get_thread_rag_agentr      s'    %{33'/z$'''rr   c                      [        U 5      n[	        S[        U[        5      5      $ ! [        [        4 a	    [        s $ f = f)z.Clamp requested thread count to allowed range.   )r   	TypeError
ValueErrorr   maxminr   )r]   counts     r4   sanitize_thread_countr      sC    *E
 q#e3455 z" *))*s   ' A A c                 n    U (       a  SU ;  a  gU R                  SS5      S   R                  5       nUS;   $ )z"Check if file extension is allowed.Fr   )pdftxt)rsplitlower)rK   exts     r4   allowed_filer      s8    s(*
//#q
!!
$
*
*
,C.  rr   c                      [            [        S [        R                  5        5       5      sSSS5        $ ! , (       d  f       g= f)z5Return the number of files currently being processed.c              3   R   #    U  H  oR                  S 5      S:X  d  M  Sv   M     g7f)rL   rk   r   NrS   ).0r[   s     r4   	<genexpr>-get_active_processing_jobs.<locals>.<genexpr>	  s#     d"<		(@SWc@c11"<s   '	'N)rR   sumr+   valuesr   rr   r4   get_active_processing_jobsr     s'    	d"3":":"<dd 
s	   $5
A/c                  (    [        S[        [        S9$ )Nz
index.html)enrichment_default_threadsenrichment_max_threads)r   r   r   r   rr   r4   indexr     s    #=5 rr   z/uploadPOST)methodsc                  v  ^^^^^ [         R                   " 5       m[        R                  =(       d    Sm [        R	                  ST 35        S[        R
                  ;  a'  [        R                  ST 35        [        SS05      S4$ [        R
                  S   n U R                  S:X  a'  [        R                  S	T 35        [        SS
05      S4$ U (       a  [        U R                  5      (       d4  [        R                  SU R                   ST 35        [        SS05      S4$ [        5         [        5       nU[        :  a6  SU S3n[        R                  ST SU 35        [        UU[        S.5      S4$ U R                  S[        R                  5        U R!                  5       mU R                  S5        ["        R$                  S   nTU:  a1  [        R                  ST ST 35        [        SSUS-   S305      S4$ ['        U R                  5      m[        R(                  R+                  ["        R$                  S   T5      m[        R(                  R-                  T5      nU(       Ga  S n [/        TS5       n[0        R2                  " UR5                  5       5      R7                  5       nS S S 5        U R                  S5        U R5                  5       n[0        R2                  " U5      R7                  5       n	U R                  S5        XY:X  a  [        R	                  ST S 35        Sn
 [>           [A        [B        S!5      (       av  [B        RD                  (       aa  [A        [B        RD                  S"5      (       aB  [B        RD                  RF                  (       a#  [I        [B        RD                  RF                  5      n
S S S 5        [        S$T S%3S&U
S'.5      S(4$ [        R	                  S)T S*35        SS+K&J'n  U" 5       nURQ                  5       nTU;   a  [S        [T        5      S,-  S--  nUR-                  5       (       a_   [/        US.5       n[V        RX                  " U5      nS S S 5        TW;   a  UT	 [/        US/5       n[V        RZ                  " XS0S19  S S S 5        [S        [T        5      S"-  [S        T5      R\                   S23-  nUR-                  5       (       a  UR_                  5         [        R	                  S3T S4T S5T 35        U Ra                  T5        UUUUU4S6 jn[c        TS7SS8S9TTTU R                  S:.S;9  [d        Rf                  " US&S<9nURi                  5         [        R	                  S=T S>35        [        S$T S?3S7TTSS@.5      SA4$ ! , (       d  f       GN= f! [8        [:        4 a%  n[        R=                  SU 35        S n S nAGN(S nAff = f! , (       d  f       GN.= f! [J         a#  n[        R=                  S#U 35         S nAGNYS nAff = f! , (       d  f       GN= f! , (       d  f       GN= f!    GN= f! [J         aS  n[         R                   " 5       T-
  n[k        [        USBTUSC.SD5        [        SSE[m        U5       305      SF4s S nA$ S nAff = f)GNunknownzFile upload request from filez&Upload request missing file part from rB   zNo file part  ru   z(Upload request with empty filename from zNo selected filezInvalid file type attempt: z from z<File type not allowed. Only PDF and text files are accepted.z!The processing queue already has zN active file(s). Please wait for current uploads to finish before adding more.zUpload throttled for : )rB   active_uploadsmax_uploadsi  r   r    zFile too large: z bytes from z File too large. Maximum size is    MBi  r   rbz'Could not read existing file for hash: zDuplicate file detected: z (same content hash)vector_store	documentszCould not get document count: zFile "z9" already exists with identical content. Skipping upload.T)rN   	duplicatetotal_documents   zReplacing existing file: z (different content)PDFProcessorr#   processed_files.jsonr%   r:   r;   r<   _chunks.jsonzSaving file:  (z bytes) from c                  
  >  [        TSSSSS0S9  [        R                  ST 35        [        TSSS	SS
0S9  SSKJn   U " 5       nUR                  [        T
5      5      nUc  [        R                  ST S35        [        TSSSSS0S9  [        [        5      S-  [        T5      R                   S3-  nUR                  5       (       aQ   [        US5       n[        R                  " U5      nSSS5        [        R                  S[        U5       ST 35        O)[        R                  ST S35        [        TSSSSS0S9  gU(       a  [        U5      S:X  a)  [        R                  S T S!35        [        TSSS"SS#0S9  g[        R                  S$[        U5       S%T 35        [        TSS&S'[        U5       S(3S)[        U5      S*.S9  [        R                  S+[        U5       S,35        [        TSS-S.SS/0S9  [#        [$        S05      (       a  [$        R&                  (       d%  [        R                  S15        [        TSSS2SS30S9  g[$        R)                  5         [        R                  S4[        U5       S,35        [        TSS5S6[        U5       S73S8[        U5      S*.S9   [*           [$        R&                  R-                  U5        [$        R&                  R/                  5         SSS5        Sn [#        [$        R&                  S5      (       aB  [$        R&                  R0                  (       a#  [        [$        R&                  R0                  5      n[4        R4                  " 5       T-
  n[7        [        S=UTTUT	S>9  [        R                  S?T S@[        U5       SA[9        USB5       SC35        [        TSDSESF[        U5       SG[9        USB5       SH3SD[        U5      [9        USB5      SI.S9  g! , (       d  f       GN= f! [         aG  n[        R                  SU 35        [        TSSS[!        U5       3S[!        U5      S.S9   SnAgSnAff = f! , (       d  f       GNu= f! [         aG  n[        R                  S9U 35        [        TSSS:[!        U5       3S;[!        U5      S.S9   SnAgSnAff = f! [         a#  n[        R3                  S<U 35         SnAGNSnAff = f! [         aA  n[!        U5      n[;        [        USJTT	SK.SLT 35        [        TSSSMU 3SUS.S9   SnAgSnAff = f)Nz*Process uploaded file in background threadrk   
   zStarting file processing...stageinitializingrX   z*[Background] Step 1: Extracting text from    zExtracting text from PDF...extract_textr   r   Nz[Background] File z+ already processed, loading existing chunks   zLoading existing chunks...loading_existing_chunksr   r   r%   z[Background] Loaded z existing chunks for z-[Background] Failed to load existing chunks: ra   z Failed to load existing chunks: load_existing_chunks_failed)r   rB   z, was marked as processed but no chunks foundz,File marked as processed but no chunks foundmissing_chunksz)[Background] Failed to extract text from z!. File may be corrupted or empty.z7Failed to extract text. File may be corrupted or empty.extract_text_failedz[Background] Step 2: Extracted z chunks from 2   z
Extracted z" chunks. Adding to vector store...chunks_ready)r   chunk_countz[Background] Step 3: Adding z raw chunks to vector store<   z Adding chunks to vector store...vector_store_preparer   z)[Background] Vector store not initializedVector store not initializedvector_store_missingz[Background] Step 4: Adding U   zAdding z chunks to vector store...vector_store_writez2[Background] Error adding chunks to vector store: zError adding to vector store: vector_store_errorz+[Background] Could not get document count: file_upload_processing)rK   rH   r   rI   z3[Background] Successfully processed uploaded file: r   z	 chunks, r;   zs)r`   d   z Successfully processed! Created z chunks in s)r   r   duration_secondsfile_processing)	operationrK   rI   z Error processing uploaded file: zError: )r^   r/   infopdf_processorr   process_pdfr   r   stemr'   r(   r)   r*   lenrA   rB   strr   
rag_systemr   initialize_modelvector_store_lockadd_documents
save_indexr   r   rQ   r   rW   r   )r   	processorchunks
chunk_filer2   r3   	doc_countduration	error_msgrI   	file_pathrH   rK   
start_times            r4   process_file_async'upload_file.<locals>.process_file_async  sx   j( 1"N3 "LXJ WX( 1"N3 7(N	"..tI? >OO&8
Bm$no, $4&(AB "&m!4{!BXH[H[G\\hEi!iJ!((**#!%j#!6!)-1 "7&OO.B3v;-Odemdn,op #((+=hZGs)tu0$$J#*,<"= V!1$$'PQYPZZ{%|},  Q&(=> "A#f+m\d[e fg(  V-OP$23v;O ">s6{mKf gh( 6"$:; z>::*BYBY$$%PQ,  6&(>? ++-">s6{mKf gh( c&k]*DE$8VU*"//==fE"//::< + 	Xz66DDI`I`IjIj$'
(?(?(I(I$J	  99;3
,Dh'/(1.7(1	3 "UV^U__abeflbmannwx}  G  IJ  yK  xL  LN  !O  P(6s6{m;uU]_`OaNbbcd!,'*6{,1(A,>
[ "7!6  ) 	#&,,/\]^\_-`a4 ( ( !"B3q6( K0MX[\]X^&_ #	#X +* ! 	$$'YZ[Y\%]^,  8QA(<s1vN 	  ! X$$'RSTRU%VWWX.  F	&"3Xab6xjA
 )i[)$,yAs   CS3 P	 O7/,P	 )S3 >S3 C	S3 AS3 +Q/ 1>Q/Q/ 7S3 :A!S BS3 7
PP	 	
Q=QS3 QS3 
Q,'Q/ *S3 ,Q/ /
S 9=R;6S3 ;S  S3 
S0S+%S3 +S00S3 3
T>=7T99T>rk   z%File uploaded, starting processing...queued)r   rG   rH   rI   rJ   r   targetdaemonzFile z( saved, processing started in backgroundz4" uploaded successfully. Processing in background...)rN   rL   rK   rH   rM      file_uploadr   rI   r  z#Unexpected error during file uploadzUpload failed:   )7rQ   r   remote_addrr/   r   filesr0   r   rK   r   rg   r   r!   seekosSEEK_ENDtellappconfigr   pathjoinr'   r(   hashlibmd5read	hexdigestr-   r.   r   r   r   r   r   r   r   rA   r   r   get_processed_filesr   r   r)   r*   r@   r   unlinksaver^   	threadingThreadstartr   r   )r   active_jobsrN   max_sizefile_existsexisting_hashr2   r3   new_file_contentnew_file_hashr  r   r  processed_filesmetadata_filer#   r  r	  processing_threadr  rI   r  rH   rK   r  s                       @@@@@r4   upload_filer0    s   J##0yIAC3I;?@&!G	{STG^45s::}}V$==B!I)UVG%7893>>
 <66!<T]]O6R[Q\]^G%cdegjjj 	"#02003K= AP Q  !6ykG9MN "-5  	  			!R[[!IIK			!::23x!1)LTUG'GU^H_G``b%cdegjjj"4==1GGLLO!<hG	 ggnnY/ M%)T*a$+KK$9$C$C$EM + IIaL#yy{#KK(89CCEMIIaL-";H:EY Z[	K*":~>>:CZCZ&z'>'>LLQ[QhQhQrQr,/
0G0G0Q0Q,R	 + !'z1jk!%'0   	  ";H:EY Z[6(N	"+"?"?"A.$($7*$DG]$]M$++--!!%mS!9Q+/99Q< ":'83$,X$6!%mS!9Q $		(a @ ":
 "&m!4{!BXH[H[G\\hEi!iJ!((**"))+-zI;mI;WX		)l	 l	^ 	!3!(&&!%	
 &,,4FtT! 	%z)QRSz)]^" "
   	{ +*W% %  #J1#!NO $% +* ! K$$'EaS%IJJK( ":!9 ":!9! j  C99;+'iXV1	

 ?3q6(!;<=sBBCs<  AY A	Y AY 'AY ;B
Y A/Y 6V5 3V#5V5 =A6Y 4W? :BW-W? Y #A&Y 
Y X/-Y 
Y Y (C:Y #
V2-V5 0Y 2V5 5W*W%Y %W**Y -
W<7W? :Y <W? ?
X,	X'!Y 'X,,Y /
X>9Y 
YY Y Y YY 
Z8%AZ3-Z83Z8z/askc            	      4   [         R                   " 5       n  [        R                  " 5       nU(       a  SU;  a  [        SS05      S4$ US   R	                  5       nU(       d  [        SS05      S4$ [        [        S5      (       a  [        R                  (       d:   [        S5        [        R                  5       nS[        l        [        S	U S
35        UR                  SS5      nUR                  S5      nUR                  SS5      nUR                  SS5      nUR                  SS5      n	U(       d  U(       d  U	(       d  U(       a  U(       a  UR                  S/ 5      n
U
(       d8  U(       a1  SSKJn  U" 5       nUR                  USS9nU Vs/ s H  oS   PM	     n
n[        R                   R#                  XUS9n[$        R'                  X5      [$        R)                  U5      S.nOS[        R+                  X%US9n[$        R-                  X5      [$        R)                  U5      S.nO[        R/                  X%S9n[1        U[        5      (       a  [        U/ S.5      S4$ [        U5      S4$ ! [         a3  n[        SU 35        [        SS[        U5       305      S4s S nA$ S nAff = fs  snf ! [         aW  n[         R                   " 5       U -
  n[3        [4        US[6        US .S!5        [        SS"[        U5       305      S4s S nA$ S nAff = f)#NquestionrB   zQuestion is requiredr   zQuestion cannot be empty_initializedz'Initializing RAG system for question...TzSystem ready with z
 documentszError initializing RAG system: zSystem initialization failed: r  kr"   domain_filteruse_keyword_focusedFextract_keywordsexpand_querykeywordsr   )get_keyword_managerr   )max_keywordskeyword)r4  domain)answersources)r4  r   question_processingr  z)Unexpected error in ask_question endpointzError processing question: )rQ   r   get_jsonr   stripr   r   r3  printsetup_systemrA   r   rS   keyword_managerr:  r7  r   keyword_focused_searchself_format_keyword_results_format_sources_from_resultsenhanced_search_format_enhanced_resultssearch_and_answer
isinstancer   r/   rI   )r  datar2  r  init_er4  r5  r6  r7  r8  r9  r:  km	extractedkwresultr3   r  s                     r4   ask_questionrT  [  s   JEO!z-G%;<=sBB
#))+G%?@A3FF z>22*:Q:Q_?@&335	*.
'*9+Z@A HHS!1"hh'<eD88$6>xx6 "2lm"88J3$4C,.B " 3 3H2 3 NI8AB	"9	HB#00GG^kGl #::6L#@@H $33H-3X #;;FM#@@H  11(1@Ffc""f<=sBB6?C''Y  _7x@A+I#f+)WXY[^^^_*  C2  O99;+/iU]^7	

 #>s1vh!GHI3NNOsn   0J6 (J6 1*J6 9I1 B=J6 J1 CJ6 $J6 1
J.;(J)#J.$J6 )J..J6 6
L ALLLz/add-insightc                      [         R                  " 5       n U (       a  SU ;  a  [        SS05      S4$ U S   nU R                  S0 5      nU R                  SS5      nS[	        [
        R
                  " 5       5       S	[        U5      S
-   3U0 UEUS[
        R
                  " 5       S.ESS.n[        R                  R                  U/5        [        R                  S[        U5       S35        [        SSUS   S.5      $ ! [         a9  n[        R                  S[        U5       3SS9  [        SS05      S4s SnA$ SnAff = f)zLAdd successful strategy insights to the RAG vector store for global learningcontentrB   zContent is requiredr   r#   sourceapistrategy_insight__i'  strategy_insight)rW  typer   g      ?)idrV  r#   scorez,Added strategy insight to RAG vector store: z charsTz&Strategy insight added to vector storer]  )successrN   chunk_idzError adding insight: )exc_infozFailed to add insightr  N)r   rA  r   rS   r   rQ   hashr   r   r   r/   r   r   rA   rB   r   )rN  rV  r#   rW  insight_chunkr3   s         r4   add_insightrd    sS   #@!y,G%:;<cAAy/88J+(E* &c$))+&6%7qg9N8OP *!YY[	 

 	--}o>Fs7|nTZ[\?%d+
  	  @1#a&:TJ!89:C??@s#   0D  CD   
E
.D>8E>Ec           
      R   U (       d  SU 3$ / nU SS  H`  nUR                  SS5      nUR                  S/ 5      nU(       d  M0  UR                  USS  Vs/ s H  ofS    S	US
    S3PM     sn5        Mb     U(       a   SSR                  [        USS 5      5       3$ SU 3$ s  snf )z9Format keyword-focused search results into answer format.#No relevant information found for: N   rV  ru   keyword_matchesr;   r<  r   matchesz	 matches)z Found relevant information for: , r"   zSearch completed for: )rS   extendr  set)resultsr2  rh  rS  rV  ri  ms          r4   rH  rH    s    4XJ?? O"1+**Y+**.37""X_`babXc#dXcST|nBq|nI$NXc#de	  1$))CPRQR@S<T2U1VWW'z22 $es   B$
c                 N   U (       d  SU 3$ [        S U SS  5       5      n[        5       nU SS  HO  nUR                  S0 5      nUR                  S/ 5       H$  nUR                  UR                  SS5      5        M&     MQ     U(       a  S	R	                  U5      OSnS
U SU S3$ )z2Format enhanced search results into answer format.rf  c              3   d   #    U  H&  oR                  S 0 5      R                  SS5      v   M(     g7f)keyword_analysistotal_matchesr   Nr   )r   rS  s     r4   r   +_format_enhanced_results.<locals>.<genexpr>  s.     malW]

#5r:>>PQRRals   .0Nrg  rq  matched_keywordsr=  generalrj  zFound relevant information in z	 domain (z keyword matches))r   rl  rS   addr  )rm  r2  rr  domainsrS  analysismatch
domain_strs           r4   rK  rK    s    4XJ?? mahikjkalmmMeG"1+::0"5\\"4b9EKK		(I67 : 
 (/7#IJ+J<yO`aarr   c                    / n[        U SS 5       H  u  p#UR                  S0 5      nUR                  SSUS-    35      [        UR                  SS5      5      S	:  a  UR                  SS5      SS	 S
-   OUR                  SS5      UR                  SS5      S.nSU;   a8  US   n[        UR                  S/ 5      5      US'   UR                  SS5      US'   UR                  U5        M     U$ )z)Format search results into source format.Nr"   r#   rW  z	Document r   rV  ru   r   z...r^  g        )rW  previewr^  rq  rt  rh  keyword_score)	enumeraterS   r   append)rm  r?  irS  r#   rW  rx  s          r4   rI  rI    s   Gwr{+	::j"-ll8y1->?BEfjjQZ\^F_B`cfBfvzz)R0#6>lrlvlv  xA  CE  mFZZ-
 '01H(+HLL9KR,P(QF$%&.ll?C&HF?#v ,  Nrr   z/statusGETc                      Sn Sn [        [        S5      (       a  [        R                  (       a  [           [        [        S5      (       av  [        R                  (       aa  [        [        R                  S5      (       aB  [        R                  R
                  (       a#  [        [        R                  R
                  5      n [        R                  S LnS S S 5        O| [        [        5      S-  nUS-  nUR                  5       (       aN  [        US5       n[        R                  " U5      n[        U[        5      (       a  [        U5      OSn S S S 5        O [        [&        R(                  " S
5      5      n[        [&        R(                  " S5      5      n[+        Xx-   S SS9n	/ n
0 n[        [        5      S-  S-  nUR                  5       (       a,   [        US5       n[        R                  " U5      nS S S 5        U	 H  nUR,                  UR/                  5       R0                  [3        UR/                  5       R0                  S-  S5      UR/                  5       R4                  UR,                  U;   UR,                  U;   a,  UR7                  UR,                  0 5      R7                  SS5      OSS.nU
R9                  U5        M     [;        U [        U5      [        U5      [        U	5      UU	 Vs/ s H  oDR,                  PM     snU
S.5      S4$ ! , (       d  f       GN= f! , (       d  f       GN= f!    GN= f! [          a#  n["        R%                  S	U 35         S nAGNS nAff = f! , (       d  f       GN= f!    GN= fs  snf ! [          aR  n["        R=                  SU 35        SS KnUR@                  " 5         [;        SS[C        U5       305      S4s S nA$ S nAff = f)Nr   Fr3  r   r   
embeddingszdocuments_metadata.jsonr%   zCould not get doc count: *.pdfz*.txtc                 6    U R                  5       R                  $ N)statst_mtime)xs    r4   <lambda>get_status.<locals>.<lambda>%  s    @Q@Qrr   T)r\   reverser#   r   r   r;   r   )namesizesize_mbuploaded	processedr  )r   	pdf_files	txt_filesrw   model_loaded	file_listr  r   zStatus check failed: rB   r  )"r   r   r3  r   r   r   r   r   r   r   r'   r(   r)   r*   rM  rb   rA   r/   r   r   globsortedr  r  st_sizerW   r  rS   r  r   rB   	traceback	print_excr   )r  r  embeddings_dirr.  r2   r#   r3   r  r  	all_filesr  r-  r  	file_infor  s                  r4   
get_statusr    s=   DI 		z>22z7N7N&z>::z?V?V":#:#:KHHZMdMdMnMn(+J,C,C,M,M(NI#-#7#7t#CL	 '&%)-%8<%GN$25N$NM$++--!-5'+yy|H9CHd9S9SHYZI 65 . g./	g./	906Q[_`	 	]+j8;QQ!!--&*iilO .
 #I!!(00 !1!9!9[!I1M%NN,55&^^>[d[i[im|[|/--innbAEEmUVW  CDI Y' # (YYy>(*34)Q&&)4
   	] '& 65 	8<=	 .-& 5  I045#8Q!ABCSHH	Is   N 0M BLM N 8L9 9L'L9 A<N N !M18N  C4N 4N	N 
L$M "N $M '
L61L9 4N 6L9 9L>;M <N >M 
M.M)#N )M..N 1
N ;N >N  N NN 
O,AO'!O,'O,z/static/<path:filename>c                     [        SU 5      $ )Nstatic)r   )rK   s    r4   serve_staticr  L  s    x22rr   z/pdf/<path:filename>c                     SSK Jn  U" U 5      n[        U-  nUR                  5       (       a7  UR                  R                  5       S:X  a  [        [        [        5      U5      $ [        SS05      S4$ )zServe PDF files for viewingr   r
   z.pdfrB   zPDF not found  )	werkzeug.utilsr   r   r'   suffixr   r   r   r   )rK   r   rZ   pdf_paths       r4   	serve_pdfr  P  sb     /#H-M&HX__224>"3w<??G_-.33rr   z/chunks/<path:filename>c                    SSK Jn  SSKnSSKJn  U" U 5      nU" [
        5      S-  U" U5      R                   S3-  nUR                  5       (       aC   [        US5       nUR                  " U5      nSSS5        [        SU[        W5      US	.5      S
4$ [        SS05      S4$ ! , (       d  f       N8= f! [         a%  n[        SS[        U5       305      S4s SnA$ SnAff = f)z"Get chunks for a specific PDF filer   r
   Nr   r   r   r%   T)r_  rK   r   r  r   rB   zError reading chunks: r  zChunks not found for this filer  )r  r   r)   pathlibr   r   r   r'   r(   r*   r   r   rA   r   )	rK   r   r)   r   rZ   r  r2   r  r3   s	            r4   
get_chunksr  Z  s     /#H-Mm${2]8K8P8P7QQ]5^^J
	Nj#&!1 ') #F 	 
   !ABCSHH '&  	NG'=c!fX%FGH#MM	Ns6   B6  B%3"B6 %
B3/B6 6
C% C C% C%z/processing-statusc                     [        5         [        5         [        R                  " 5       n U 0 0 S.n[           [        R                  5        HR  u  p#[        X#U S9nUR                  S5      S:X  a	  XAS   U'   M-  XR                  SU 5      -
  [        ::  d  MK  XAS   U'   MT     SSS5        [        US   5      US	'   [        US   5      US
'   [        U5      S4$ ! , (       d  f       N== f)z9Return snapshot of all processing jobs (active + recent).)r   r   recent)rY   rL   rk   r   ri   r  Nactive_countrecent_countr   )r5   rg   rQ   rR   r+   rV   rq   rS   #PROCESSING_STATUS_RETENTION_SECONDSr   r   )rY   snapshotrK   r[   rn   s        r4   list_processing_statusesr  s  s     
))+CH
 
0668OH3HMJ~~h'<7/9"8,s;;?bb3=X&x0  9 
  #8H#56H^"8H#56H^8c!! 
s   ACC
C&z"/processing-status/<path:filename>c           	         [        U 5      n[        5         [        5         [        R	                  U5      nU(       a  [        [        X5      5      S4$ [        [        5      S-  S-  nUR                  5       (       aW   [        US5       n[        R                  " U5      nSSS5        UW;   a$  [        SSSXQ   R	                  S	S
5      S.5      S4$  [        SS
SS.5      S4$ ! , (       d  f       NJ= f!    N&= f)z Get processing status for a filer   r#   r   r%   Nr`   r   zFile already processedr   r   )rL   rM   rN   r  r   zNo processing status found)rL   rM   rN   r  )r   r5   rg   r+   rS   r   rq   r   r   r'   r(   r)   r*   )rK   rZ   r[   r.  r2   r-  s         r4   get_processing_statusr    s    $H-M !!-0E1-GH#MM ]+j8;QQ!!--&*iilO . O3""-$'#;"1"@"D"D]TU"V	$ 
   4 3
  	 	 .-s$   =C5 	C$ 1C5 $
C2.C5 5C9z/enrichc            
      n    [         R                  " SS9=(       d    0 n U R                  S5      n[        U5      n[	        5         [
        R                  S5      S:X  aS  [        SS[
        R                  SS5      [
        R                  S	S
5      [
        R                  S[        5      S.5      S4$ [        R                  " [        U4SS9nUR                  5         [        SSUS.5      S4$ ! [         a=  n[        R                  SU 35        [        SS[        U5       305      S4s SnA$ SnAff = f)z%Trigger enrichment for new files onlyT)silentthreadsrL   r   z>Enrichment is already running. Please wait for it to complete.rM   r   rN   ru   rx   )rB   rL   rM   rN   rx   i  )r  argsr  z0Enrichment started. Processing new files only...ro   )rN   rL   rx   r  zError starting enrichment: rB   zFailed to start enrichment: r  N)r   rA  rS   r   r   r|   r   r   r$  r%  enrich_documents_asyncr&  rA   r/   rB   r   )rN  requested_threadsrx   enrichment_threadr3   s        r4   enrich_documentsr    s>   Pt,2 HHY/,->? 	   *i7Y#-11*a@,00B? 1 5 5nF` a    &,,4JR^Q`imn!I(
  	 	  P6qc:;#?Ax!HIJCOOPs$   B.C- 1;C- -
D472D/)D4/D4c           
      
   U c  [         n [        U 5      n  [        SU S9  [        SSSSSU 5        [	        [
        R                  " S5      5      n[        U5      nUS:X  a  [        SS	S
SSU 5        [        SSS9  g0 n[        R                  " 5       (       a>  [        R                  " S5       H$  n UR                  R                  SS5      nSX5'   M&     / n0 n[        [        5      S-  S-  nUR                  5       (       a,   [        US5       n	[        R                   " U	5      nSSS5        U H9  n
U
R                  nU
R"                  U;   d  M!  X;  d  M(  UR%                  U
5        M;     U(       d  [        SS	SX"U 5        [        SSS9  g[        U5      n[        SU V	s/ s H  oR"                  PM     sn	S9  [        SSSU SU  S3SUU 5        ['        [(        S5      (       a  [(        R*                  (       d   ['        [(        S5      (       a  [(        R,                  (       d&  [.        R1                  S5        [        S SS!SSU 5        g[2           [(        R,                  R5                  5         [(        R7                  5         S[(        l        SSS5        / nSnU H  n
 [=        XS$9nUR%                  U5        UR?                  S)5      (       d  [A        US*   5        US+-  n[C        SX-  S,-  -   5      n[        SUUR?                  S-5      =(       d    S.U
R"                   3UUU 5        M     U Vs/ s H5  nUR?                  S)5      (       d  M  UR?                  S/5      (       d  M3  UPM7     nn[E        S0 U 5       5      n[        U5      nU(       a  [        SS1S2UUU 5        [G        US+S39 H  u  nn [I        US*   S4S9  [K        US*   US/   5        [        S5US*   [        US/   =(       d    / 5      S69  [C        S1U[        U5      -  S7-  -   5      n[        SUS8US*    3UUU 5        [A        US*   5        SUS/'   M     O[        SS<S=UUU 5        US:  a
  S>U S?U S@3nOUU-
  nUU:X  a  SAnO	SBU SCU SD3n[        SS	UXU 5        [M        5         [        SUUUUSE9  [.        RO                  SFU SGU SHU SI35        g!    GM  = f! , (       d  f       GN= f!    GN= fs  sn	f ! , (       d  f       GNa= f! [8         a>  n[.        R1                  S"U 35        [        S SS#[;        U5       3SSU 5         SnAgSnAff = f! [8         a[  n[.        R1                  S%U
R"                   S&U 35        U
R"                  S'S%U
R"                   S&[;        U5       3SSS(.n SnAGNSnAff = fs  snf ! [8         a@  n[.        R1                  S9US*    S&U 35        [        S:US*   [;        U5      S;9   SnAGNSnAff = f! [A        US*   5        SUS/'   f = f! [8         a[  n[.        R1                  SJU 35        [        SK[;        U5      SL9  [M        5         [        S SSM[;        U5       3SSU 5         SnAgSnAff = f)NzMEnrich documents in background - only process files without cards (threaded).Nrun_started)r  r   r   z*Checking for files that need enrichment...r  r`   r   zNo PDF files foundrun_completedzNo files to processrN   z*_cards.json_cardsru   Tr#   r   r%   z%All files already have enriched cardszAll files already enrichedfiles_queued)r  r"   zFound z file(s) to enrich. Starting (z thread(s))...r3  r   z)Vector store not available for enrichmentra   r   z2Failed to initialize vector store for enrichment: z$Vector store initialization failed: )rx   Error enriching r   Fr   r_  rN   enriched_chunksr   r_  r   r   P   rN   	Finished r  c              3   h   #    U  H(  n[        UR                  S 5      =(       d    / 5      v   M*     g7f)r  N)r   rS   )r   r%   s     r4   r   )enrich_documents_async.<locals>.<genexpr>A  s)     $cRbQS/@)A)GR%H%HRbs   02Z   z-Updating vector store with enriched chunks...)r&  zIndexing enriched chunksvector_update)r   r  r   zIndexed enriched chunks for zVector store update failed for vector_update_failedr   rB   _   z5No enriched chunks generated. Vector store unchanged.zEnrichment complete! Processed z file(s) with z total chunks.zNEnrichment completed but no files generated new cards. Check logs for details.z"Enrichment completed with issues. z succeeded, z	 skipped.)enrichedtotalr  rN   zEnrichment completed: r   z files enriched, z total chunkszError in enrichment process: 
run_failed)rB   zEnrichment failed: )(r   r   r   r   rb   r   r  r   r   r'   r   replacer   r   r(   r)   r*   r  r  r   r   r3  r   r/   rB   r   load_existing_indexr   rA   r   process_file_for_enrichmentrS   r   r   r   r~  r   %apply_enriched_chunks_to_vector_storer   r   )rx   r  rw   existing_cards	card_filesource_stemfiles_to_enrichr-  r.  r2   pdf_file	file_stemtotal_files_to_processr3   rm  rv   rS  rM   r%   enriched_resultstotal_chunks_processedenriched_countidxrN   skipped_counts                            r4   r  r    s   1(6Ljb]LA A/[]^`acop g./	)n!$[#7KQPQS_` :OP &^^N;	"+.."8"82"FK26N/ < ]+j8;QQ!!--&*iilO .
 "H I}}/I4S&&x0 "
 $[#7^`k  {G  H :VW!$_!5^O3TOqFFO3TU +,,J<.Xfg"	
 z>22*:Q:Qz>::*BYBY$$%PQ,Xq:XZ[]^`lm '++??A//1.2J+ '  (H
4XY NN6"::i((.vf~>q O1 HBNNOH$

9%D9X]]O)D&) (< (/`w!!%%	2BAquuM^G_Aw`!$$cRb$c!c-.$?&  ))9CV53F6NLfg9&.&QbJcd(vf~VYZ`arZsZywyVz{"2s3C/D)D(J#JKH,! 6vf~6FG'.$ 36&>B04F,-)  D, %G& A77G~VlUmm{|G2^CM 66j>~>Nl[hZiirs c7<Rlxy%'_~Mc  mC  MT  	U00@BXAYYj  lB  kC  CP  Q  	Ra .- 4U& '&    #UVWUX!YZ(18\]`ab]c\d6eghjkmyz    #3HMM?"QC!HI$MM$!1(--3q6(K'+#$6 a6 ! d$$'Fvf~FVVXYZX[%\]()?fVn\_`a\bccd 36&>B04F,-2  b8<=\Q8%' 10CCF8.LaQRT`aa	bsd  A$X ;5X 1 S2X S! S'S! /X X 5X X $S)
9AX  AT  T  >S.T  	X &	U/B
X 9V3V3/V35AX <A5V81BX SX 
SS! X S! !S&#X .
S=8T  ;X =T   
U
4U>X UX 
V0AV+%X +V00X 8
X5W=7X=XXXX 
Z'AY==Zc                 `  ^ ^ T R                   SSSSS.n [        T R                   SS9  [        T R                   S3-  nUR	                  5       (       d@  S	T R                    S
3US'   [        ST R                   S9  [        T R                   US   S9  U$ [        US5       n[        R                  " U5      nSSS5        W(       a  [        U[        5      (       d@  ST R                    S3US'   [        ST R                   S9  [        T R                   US   S9  U$ [        U5      n[        T R                   SUSU S3S9  [        ST R                   XaS9  [        5       n[        R                  " 5       mU4S jn[        R                  " USS9n	U	R!                  5         U 4S jn
 UR#                  XZUS9nTR%                  5         U(       a  UR'                  SU[        U5      ST R                    S[        U5       S3S.5        [        T R                   [        U5      [        U5      S S9  [        S!T R                   [        U5      S"9  U$ S#T R                    S3US'   [        T R                   US   S9  [        S$T R                   S9   U$ ! , (       d  f       GN= f! TR%                  5         f = f! [(         al  nS%T R                    S&[+        U5       3US'   [+        U5      US''   [        T R                   US   S9  [        S(T R                   [+        U5      S)9   SnAU$ SnAff = f)*zWorker function to build enriched chunks for a single PDF.

Args:
    pdf_file: Path object for the PDF file
    thread_count: Number of threads to use for chunk-level parallel processing
Fru   Nr   r  zLoading chunksr  r   zNo chunks found for z, skipping.rN   file_missing_chunks)r   r%   z Invalid or empty chunk data for r   file_invalid_chunksz&Generating knowledge cards (starting, z thread(s))r   r   rN   file_started)r   r   rx   c                  f   > T R                  S5      (       d   T R                  S5      (       d  M  g g )Nr   )wait)
stop_events   r4   	heartbeat.process_file_for_enrichment.<locals>.heartbeat  s&     oob)) !oob))rr   Tr  c           
      @   > [        TR                  U USU  SU S3S9  g )NzGenerating knowledge cards (r   )r  )r   r  )currentr  r  s     r4   progress_callback6process_file_for_enrichment.<locals>.progress_callback  s*    +#!6wiqqI	rr   )r  rx   r  r   z enriched chunks))r_  r  r   rN   zCards ready for indexingfile_completed)r   r  z!No enriched chunks generated for file_no_cardsr  r   rB   
file_errorr  )r  r   r   r   r'   r   r(   r)   r*   rM  rb   r   r   r$  Eventr%  r&  build_enriched_chunksrl  rU   rA   r   )r  rx   rS  r  r2   chunks_datar   agentr  heartbeat_threadr  r  r3   r  s   `            @r4   r  r    s    FBM'?OP"l%CC
  """6x}}o[ QF9 !6X]]K+HMM6)CTUM*c"a))A,K # *[$"?"?"B8==/QR SF9 !6X]]K+HMM6)CTUM+&'1R]  jP  Q]  P^  ^i  hj  	k^(--[t$&__&
	
 %++9TJ 		#99+  zF9  GONNMM#2"?3&x}}oRO8L7MM^_	  ,002	 !!1WZ[jWkl M #DHMM?RS TF9+HMM6)CTU x}}E Mu #"D NN&  M.x}}oRAxHya&w'vi?PQ\SVLMMs^   A>J7 J7 !J8A#J7 B
J7 'J" 7BJ7 >J7 
JJ7 "J44J7 7
L-A!L((L-c                    U(       d  [         R                  SU  S35        g [         R                  SU  S[        U5       S35        [           [
        R                  R                  X5        [
        R                  R                  5         SSS5        [         R                  SU  35        g! , (       d  f       N'= f! [         a!  n[         R                  SU  S	U 35        e SnAff = f)
z
Safely replace existing vector store entries for a source with enriched chunks.

This method uses replace_source_documents which rebuilds the index to ensure
consistency and prevent index corruption (index/document count mismatch).
z No enriched chunks provided for z, skipping vector store updateNzUpdating vector store for z with z enriched chunksz&Successfully updated vector store for z Error updating vector store for r   )r/   r0   r   r   r   r   r   replace_source_documentsr   rA   rB   )source_namer  r3   s      r4   r  r    s     =k]Jhij4[MOH\G]]mno
 ##<<[Z##..0 
 	@NO   ;K=1#NOs/   +B> >B- B> -
B;7B> >
C)C$$C)z/enrichment-statusc                      [        5         [        R                  S5      S:X  a@  [        R                  S5      (       a&  [        R                  S0 5      n U (       a	  S[        S'   [        [        5      S4$ )zGet current enrichment statusrL   rt   ry   r   r   )r   r|   rS   r   )ry   s    r4   get_enrichment_statusr    s_     X&&05F5J5J>5Z5Z(,,^R@*3h'$%s**rr   z/reprocessing-statusc            
         [        [        5      S-  S-  n U R                  5       (       a9   [        U S5       n[        R
                  " U5      nSSS5        [        W5      S4$ [        SSS	S
SSSS.5      S4$ ! , (       d  f       N0= f! [        R                  [        [        4 a"  n[        R                  SU 35         SnANbSnAff = f)zGet current reprocessing statusr#   zreprocessing_status.jsonr%   Nr   z$Failed to load reprocessing status: rt   r   zNo reprocessing in progressru   )rL   rM   rN   current_filerv   rw   chunks_created)r   r   r'   r(   r)   r*   r   r,   r-   r.   r/   r   )status_filer2   rL   r3   s       r4   get_reprocessing_statusr    s     }%
25OOK	k3'11 (6?C'' 0  	  (' $$gw7 	CA3GH	s.   B
 A9B
 9
BB
 
C)CC__main__zStarting Flask application...z/RAG system will be initialized on first requestT)hostportr   )r   ru   Nr  )r   ru   r   r   N)NNN)r   )eflaskr   r   r   r   r   r  rQ   r)   r  r$  concurrent.futuresr   r	   r  r   r  r   r  airagagent.mainr   airagagent.configr   r   r   r   r   r   r   r   r   r   airagagent.logging_configr   r   r   airagagent.exceptionsr   r   airagagent.mistral_integrationr   __name__r  r   r  r   environrS   r!   r/   r   localr   r&   r  rm   r{   r+   r|   LockrR   r   r   r5   rC   r^   rg   rq   r   r   r   r   r   r   r   r   r   r   r   router   r0  rT  rd  rH  rK  rI  r  r  r  r  r  r  r  r  r  r  r  r  rC  runr   rr   r4   <module>r     s   O O 	     ? *   %   Z Y B 3Ho "'l

? #3

  RZZ^^,DaHI  !
 [
__&  m,z9<TT &* #$' !/   nnnn& NN$ C!@ 1T %   ?2CI!"!"%!  (6!e
 3  9vh'EC (ECN
 6F8$GO %GOR >F8,%@ -%@N3$b * 9ug&EI 'EIN $%3 &3 !"4 #4 $%I &I0 %1" 2". /0  1 D 9vh'P (P@obbQf8 %1+ 2+ !E73 4* z	
)*	
;<GGG5 rr   