Ë
    vÝj"  ã                  ó´   — d Z ddlmZ ddlZddlmZ ddlmZmZ ddlm	Z	 ddl
mZmZmZ dd	lmZ  ed
¬«       G d„ d«      «       Zdd„Zdd„Z G d„ d«      Zy)u˜  Tagesbudget je Backend (Anzahl Jobs, optional Token-SchÃ¤tzung).

Ablauf: available() fÃ¼r die Routingentscheidung (reserviert nichts),
reserve() unmittelbar vor der AusfÃ¼hrung (atomar unter Dateisperre),
settle() danach: consumed=True verbucht, consumed=False gibt frei.
Reservierungen, die nie abgerechnet wurden (Absturz), zÃ¤hlen nach
reservation_timeout als verbraucht (fail-closed).
Tagesgrenze: UTC.
é    )ÚannotationsN)Ú	dataclass)ÚdatetimeÚtimezone)ÚPath)ÚCallableÚMappingÚOptionalé   )ÚLockedJsonFileT)Úfrozenc                  ó&   — e Zd ZU ded<   dZded<   y)ÚBudgetLimitÚintÚ
daily_jobsNzOptional[int]Údaily_token_estimate)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r   © ó    ú3/home/aria/aria-v3-dev/python/aria_router/budget.pyr   r      s   … àƒOØ*.Ð˜-Ô.r   r   c                ó&   — t        d| dz   dz  «      S )u1   Grobe SchÃ¤tzung: 4 Bytes je Token, mindestens 1.r   é   é   )Úmax)Ú
text_bytess    r   Úestimate_tokensr      s   € äˆq�: ‘> aÑ'Ó(Ð(r   c                ó„   — t        j                  | t        j                  ¬«      j	                  «       j                  «       S )N)Útz)r   Úfromtimestampr   ÚutcÚdateÚ	isoformat)Únows    r   Úutc_dayr'       s+   € Ü×!Ñ! #¬(¯,©,Ô7×<Ñ<Ó>×HÑHÓJÐJr   c                  ón   — e Zd Zej                  df	 	 	 dd„Zdd„Zdd„Zdd„Zddd„Zdd„Z	dd„Z
dd	„Zy
)ÚBudgetLedgeri  c                ó`   — t        |«      | _        t        |«      | _        || _        || _        y ©N)r   Ú_fileÚdictÚ_limitsÚ_clockÚ_reservation_timeout)ÚselfÚpathÚlimitsÚclockÚreservation_timeouts        r   Ú__init__zBudgetLedger.__init__%   s(   € ä# DÓ)ˆŒ
Ü˜F“|ˆŒØˆŒØ$7ˆÕ!r   c                óš  — |j                  di «      }|j                  di «      }t        |«      D ]h  }||   }|d   | j                  z   |k  sŒ|j                  |d   i «      j                  |d   dddœ«      }|dxx   d	z  cc<   |d
xx   |d
   z  cc<   ||= Œj t        |dz
  «      }|D �	cg c]
  }	|	|k  sŒ	|	‘Œ c}	D ]  }
||
= Œ y c c}	w )NÚreservationsÚdaysÚtsÚdayÚbackendr   ©ÚjobsÚtokensr>   r   r?   i Œ
 )Ú
setdefaultÚlistr0   r'   )r1   Údatar&   r8   r9   Újob_idÚentryÚusageÚcutoffÚdr;   s              r   Ú_prunezBudgetLedger._prune,   sæ   € Ø—‘ ~°rÓ:ˆØ�‰˜v rÓ*ˆÜ˜<Ó(ò 	)ˆFØ  Ñ(ˆEØ�T‰{˜T×6Ñ6Ñ6¸Ó<ØŸ™¨¨e©°bÓ9×DÑDÀUÈ9ÑEUÐ`aÐmnÑWoÓp�Ø�f“ Ñ"“Ø�h“ 5¨¡?Ñ2“Ø  Ñ(ð	)ô ˜˜y™Ó)ˆØ#Ö2˜! q¨6£z’AÒ2ò 	ˆCØ�S‘	ñ	ùÒ2s   Â-
CÂ8Cc                ó  — |j                  di «      j                  |i «      j                  |dddœ«      }|d   |d   }}|j                  di «      j                  «       D ]!  }|d   |k(  sŒ|d   |k(  sŒ|d	z  }||d   z  }Œ# ||fS )
Nr9   r   r=   r>   r?   r8   r<   r;   r   )ÚgetÚvalues)r1   rB   r<   r;   rE   r>   r?   rD   s           r   Ú_usagezBudgetLedger._usage:   s¡   € Ø—‘˜ Ó$×(Ñ(¨¨bÓ1×5Ñ5°gÈÐUVÑ?WÓXˆØ˜V‘} e¨H¡oˆfˆØ—X‘X˜n¨bÓ1×8Ñ8Ó:ò 	*ˆEØ�YÑ 7Ó*¨u°U©|¸sÓ/BØ˜‘	�Ø˜% ™/Ñ)‘ð	*ð �Vˆ|Ðr   c                óâ   — | j                   j                  |«      }|€y| j                  ||t        |«      «      \  }}|dz   |j                  kD  ry|j
                  �||z   |j
                  kD  ryy)NFr   T)r.   rJ   rL   r'   r   r   )r1   rB   r<   r?   r&   Úlimitr>   Úused_tokenss           r   Ú_fitszBudgetLedger._fitsC   sr   € Ø—‘× Ñ  Ó)ˆØˆ=ØØ ŸK™K¨¨g´w¸s³|ÓDÑˆˆkØ�!‰8�e×&Ñ&Ò&ØØ×%Ñ%Ð1°kÀFÑ6JÈU×MgÑMgÒ6gØØr   c                ó~   — | j                  «       }| j                  j                  «       }| j                  ||||«      S r+   )r/   r,   Úread_snapshotrP   )r1   r<   r?   r&   rB   s        r   Ú	availablezBudgetLedger.availableN   s4   € Ø�k‰k‹mˆØ�z‰z×'Ñ'Ó)ˆØ�z‰z˜$ ¨°Ó5Ð5r   c                óD  — | j                  «       }| j                  j                  «       5 }| j                  ||«       ||d   v r
	 d d d «       y| j	                  ||||«      s
	 d d d «       y|t        |«      t        |«      |dœ|d   |<   	 d d d «       y# 1 sw Y   y xY w)Nr8   F)r<   r?   r;   r:   T)r/   r,   ÚtransactionrH   rP   r   r'   )r1   r<   rC   r?   r&   rB   s         r   ÚreservezBudgetLedger.reserveS   s§   € Ø�k‰k‹mˆØ�Z‰Z×#Ñ#Ó%ð 		¨Ø�K‰K˜˜cÔ"Ø˜˜nÑ-Ñ-Ø÷		ð 		ð —:‘:˜d G¨V°SÔ9Ø÷		ð 		ð #¬c°&«kÄ'È#Ã,ÐVYñ,ˆD�Ñ  Ñ(ð ÷		÷ 		ñ 		ús   «BÁBÁ- BÂBc               ó‚  — | j                  «       }| j                  j                  «       5 }| j                  ||«       |d   j	                  |d «      }|�|s
	 d d d «       y |d   j                  |d   i «      j                  |d   dddœ«      }|dxx   dz  cc<   |d	xx   |d	   z  cc<   d d d «       y # 1 sw Y   y xY w)
Nr8   r9   r;   r<   r   r=   r>   r   r?   )r/   r,   rU   rH   Úpopr@   )r1   rC   Úconsumedr&   rB   rD   rE   s          r   ÚsettlezBudgetLedger.settle`   sÃ   € Ø�k‰k‹mˆØ�Z‰Z×#Ñ#Ó%ð 	/¨Ø�K‰K˜˜cÔ"Ø˜Ñ(×,Ñ,¨V°TÓ:ˆEØˆ}¡HØ÷		/ð 	/ð
 ˜‘L×+Ñ+¨E°%©L¸"Ó=×HÑHØ�iÑ ¨1¸Ñ":ó<ˆEà�&‹M˜QÑ‹MØ�(‹O˜u X™Ñ.‹O÷	/÷ 	/ñ 	/ús   «-B5Á!AB5Â5B>c                ó  — | j                  «       }| j                  j                  «       }| j                  ||t	        |«      «      \  }}| j
                  j                  |«      }|||r|j                  nd|r|j                  dœS d dœS )Nr   )r>   r?   r   r   )	r/   r,   rR   rL   r'   r.   rJ   r   r   )r1   r<   r&   rB   r>   r?   rN   s          r   Úusage_todayzBudgetLedger.usage_todayl   s†   € Ø�k‰k‹mˆØ�z‰z×'Ñ'Ó)ˆØ—{‘{ 4¨´'¸#³,Ó?‰ˆˆfØ—‘× Ñ  Ó)ˆàØÙ.3˜%×*Ò*¸ÙBG E×$>Ñ$>ñ	
ð 	
ð NRñ	
ð 	
r   N)r2   r   r3   zMapping[str, BudgetLimit]r4   zCallable[[], float]r5   r   )rB   r-   r&   ÚfloatÚreturnÚNone)rB   r-   r<   Ústrr;   r`   r^   ztuple[int, int])
rB   r-   r<   r`   r?   r   r&   r]   r^   Úbool)r   )r<   r`   r?   r   r^   ra   )r<   r`   rC   r`   r?   r   r^   ra   )rC   r`   rY   ra   r^   r_   )r<   r`   r^   r-   )r   r   r   Útimer6   rH   rL   rP   rS   rV   rZ   r\   r   r   r   r)   r)   $   sD   „ à.2¯i©iÐTXð8Ø+ð8ØNQó8óóó	ô6ó
ó
/ô

r   r)   )r   r   r^   r   )r&   r]   r^   r`   )Ú__doc__Ú
__future__r   rb   Údataclassesr   r   r   Úpathlibr   Útypingr   r	   r
   Ústater   r   r   r'   r)   r   r   r   ú<module>ri      sY   ðñõ #ã Ý !ß 'Ý ß .Ñ .å !ñ �$Ô÷/ð /ó ð/ó
)ó
K÷R
ò R
r   