
    $^j/                     L    S r SSKrSSKJr  SSKJr   " S S5      r\" S5      rg)ug   
Audit-Logging für LLM-Enrichment.
Trackt welches Modell wann verwendet wurde, Erfolg/Fehler, Kosten.
    N)datetime)Optionalc                       \ rS rSrSrSS\4S jjr   SS\S\S\S	\S
\S\	\   S\	\   S\	\
   4S jjrS\S\S\S\S\4
S jrS\S\	\   4S jrS rSrg)EnrichmentLogger   z5Speichert Enrichment-Attempts in strukturierter Form.log_namec                 H    [         R                  " U5      U l        0 U l        g )N)logging	getLoggerloggerstats)selfr   s     /app/llm/logger.py__init__EnrichmentLogger.__init__   s    ''1
    N
contact_id
model_usedlevelsuccessvalidation_resulttokens_used	error_msgestimated_fieldsc	                    [         R                  " 5       R                  5       n	U=(       d    / nU	UUUUUU=(       d    SU=(       d    S[        U5      US.
n
U(       a  SOSU S3nU(       a  S[        U5       3OSnU R                  R                  SU S	U S
U SU SU=(       d    S U 35        UnXR                  ;  a  SSSSS.U R                  U'   U R                  U   S==   S-  ss'   U(       a  U R                  U   S==   S-  ss'   OU R                  U   S==   S-  ss'   U(       a  U R                  U   S==   U-  ss'   U
$ )uN  
Loggt einen Enrichment-Versuch.

Args:
    contact_id: Kontakt-ID
    model_used: z.B. "gpt-5-nano"
    level: 1 (billig), 2 (mittel), 3 (stark)
    success: True/False
    validation_result: z.B. "OK" oder "MISSING_CRITICAL: pain_point"
    tokens_used: Input+Output Tokens (falls verfügbar)
    error_msg: Optionale Error-Message
r    )
	timestampr   modelr   r   
validationtokenserrorestimated_fields_countestimated_fields_listu   ✓ OKu	   ✗ FAIL()z est=[z] z (Lz): z tokens=?)attempts	successesfailurestokens_totalr'      r(   r)   r*   )r   now	isoformatlenr   infor   )r   r   r   r   r   r   r   r   r   r   	log_entrystatusest_info	model_keys                 r   log_attemptEnrichmentLogger.log_attempt   sg   * LLN,,.	+1r"$+!&Q_"&)*:&;%5
	 %I6G5H*J6FU3/012B
|2j\UG3vh ?!(S)(5	
 	JJ& !	%DJJy! 	

9j)Q.)JJy!+.!3.JJy!*-2-JJy!.1[@1r   budget_used
max_budgettokens_per_levelexceededc                    US:  a  X#-  S-  OSnU(       a  SOSnSR                  S UR                  5        5       5      nU R                  R                  SU SU S	U S
U SUS SU=(       d    S 35        SU R                  ;  a  SSSS.U R                  S'   U R                  S   S==   U-  ss'   U R                  S   S==   S-  ss'   U(       a  U R                  S   S==   S-  ss'   gg)u!  
Loggt Token-Budget-Zusammenfassung pro Kontakt.

Args:
    contact_id:      Kontakt-ID
    budget_used:     Gesamte verbrauchte Tokens
    max_budget:      Maximales Budget
    tokens_per_level: Dict {"L1": 1200, "L2": 800, ...}
    exceeded:        True wenn Budget überschritten wurde
r   d   EXCEEDEDOKz, c              3   4   #    U  H  u  pU S U 3v   M     g7f)=N ).0kvs      r   	<genexpr>6EnrichmentLogger.log_contact_budget.<locals>.<genexpr>f   s     N5MTQ1QCj5Ms   r%   z	] Budget : / (.1fz%) | per Level: keinebudget)total_tokenstotal_contactsexceeded_countrL   rM   r+   rN   N)joinitemsr   r/   r   )	r   r   r6   r7   r8   r9   pctr1   	level_strs	            r   log_contact_budget#EnrichmentLogger.log_contact_budgetT   s	     3=q.{'#-a'TIIN5E5K5K5MNN	
|9VHB{m1ZL ICy()=g(>@	
 4::% !"#"#$DJJx 
 	

8^,;,

8-.!3.JJx !12a72 r   r   returnc                     XR                   ;  a  gU R                   U   S   S:X  a  gU R                   U   S   U R                   U   S   -  $ )u?   Berechnet Success-Rate für ein Modell (z.B. nach 50 Requests).Nr'   r   r(   )r   )r   r   s     r   get_success_rate!EnrichmentLogger.get_success_ratex   sO    

"::eZ(A-zz% -

50A*0MMMr   c                     [        S5        U R                  R                  5        HC  u  pUS   S:  d  M  US   US   -  S-  n[        SU SUS    SUS    S	US
 SUS    S35        ME     g)zGibt Statistiken aus.z
=== Enrichment Statistics ===r'   r   r(   r;   z  rF   rG   rH   rI   z%) | r*   z tokensN)printr   rP   )r   r   r   rates       r   print_statsEnrichmentLogger.print_stats   s    /0 JJ,,.LEZ 1$k*U:->>#E5'E+$6#7qz9J8K Ls5~)>(?wH I /r   )r   r   )
enrichment)NNN)__name__
__module____qualname____firstlineno____doc__strr   intboolr   listr4   dictrS   floatrW   r\   __static_attributes__r@   r   r   r   r      s    ?  15.26:@"@"@ @ !	@
 '*@ !)@ 'sm@ &.d^@D"8&)"8'*"8 '*"8 -1	"8
 %)"8HNc Nhuo NIr   r   r^   )rc   r
   r   typingr   r   enrichment_loggerr@   r   r   <module>rm      s1   
   |I |I@ %\2 r   