+
    iHàjë  ã                  óV  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIHt ^ RIH	t	H
t
HtHt ]P                  ! ]4      tRt^@RuttRt]! RRR	7      tR
]R&   / tR]R&   Rs/ tR]R&   R tR R ltR R ltR R ltR R ltR R lt]P>                  R R l4       t R R lt!R  R! lt"R" R# lt#R# )$a<  Per-image token cost learned from the provider's own usage, never from a vendor formula.

A flat per-image constant is wrong in both directions: a 1920x1080 screenshot costs ~1,100 tokens
on one provider and 4,000+ on a local mmproj model. The provider prices every image exactly on the
request that carries it, so the cost is observable: with a fresh usage anchor (real prompt count of
the previous response), the residual between the next real ``prompt_tokens`` and
``anchor + text-only delta`` is the price of the N images that delta introduced (#70328).

The learned value is kept per ``model@host`` in ``~/.hermes/cache/image_token_costs.json`` so a new
session starts calibrated, and bound per turn through a ContextVar so every estimator
(preflight trigger, tail-budget walk, gateway hygiene) prices images the same way.
)ÚannotationsN)Ú
ContextVar)ÚAnyÚDictÚListÚOptionaliÜ  i €  g      à?Úhermes_image_token_cost)ÚdefaultzContextVar[Optional[int]]Ú_image_cost_varúdict[str, int]Ú_LEARNEDFzdict[str, dict[str, int]]Ú_LEARNED_BY_HOMEc                 ó   € ^ RI Hp  V ! R4      # )é    ©Ú_cache_filezimage_token_costs.json)Úagent.model_metadatar   r   s    Ú;/home/ubuntu/.hermes/hermes-agent/agent/image_token_cost.pyÚ_cache_pathr   $   s   € Ý0áÐ/Ó0Ð0ó    c               ó$   € V ^8„  d   QhRRRRRR/# )é   Úmodelr   Úbase_urlÚreturnÚstr© )Úformats   "r   Ú__annotate__r   *   s&   € ÷ Fñ F�ð F˜sð F sñ Fr   c                ód   € ^ RI Hp T ;'       g    R RT! T;'       g    R4      ;'       g    R 2# )r   )Úbase_url_hostnameÚ Ú@)Úutilsr    )r   r   r    s   && r   Ú_keyr$   *   s1   € Ý'à�kˆk�rˆ]˜!Ñ-¨h¯n¨n¸"Ó=×CÐCÀÐDÐEÐEr   c               ó   € V ^8„  d   QhRR/# ©r   r   r   r   )r   s   "r   r   r   0   s   € ÷ Mñ M�^ñ Mr   c                 óè   € ^ RI Hp  V ! \        4       4      P                  4        UUu/ uF<  w  r\	        V\
        4      '       g   K  \        Tu;8:  d   \        8:  g   K6  M K:  WbK>  	  upp# u uppi )r   )Ú_load_json_dict)r   r(   r   ÚitemsÚ
isinstanceÚintÚ_MIN_PLAUSIBLEÚ_MAX_PLAUSIBLE)r(   ÚkÚvs      r   Ú_read_cacher0   0   sh   € Ý4á,¬[«]Ó;×AÑAÔCô MÑC‘T�QÜ˜!œS×!ô Ü&4¸Ö&K¼^Ñ&Kô Ù&Kñ ˆAŠDÑCò Mð Mùó Ms   ¨A.ÁA.Á A.Á$A.c               ó   € V ^8„  d   QhRR/# r&   r   )r   s   "r   r   r   7   s   € ÷ ñ �ñ r   c                 óð   € ^ RI Hp Hp V ! 4       f2   \        '       g    Rs\        P                  \        4       4       \        # V! 4       p\        P                  V4      pVf   \        4       ;p\        V&   V# )zFThe active profile's learned table, loaded lazily from its cache file.)Úget_hermes_home_overrideÚhermes_home_keyT)	Úhermes_constantsr3   r4   Ú_LOADEDr   Úupdater0   r   Úget)r3   r4   Úhome_keyÚtables       r   Ú_tabler;   7   sb   € ÷ KáÓ!Ò)ß‹wØˆGÜ�O‰OœK›MÔ*ÜˆÙÓ €HÜ× Ñ  Ó*€EØ‚}Ü-8«]Ð:ˆÔ  Ñ*Ø€Lr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   r   r   r+   r   )r   s   "r   r   r   H   s&   € ÷ Iñ I Cð I°3ð I¸3ñ Ir   c                óP   € \        4       P                  \        W4      \        4      # )zALearned per-image cost for ``model@host``, else the flat default.)r;   r8   r$   ÚDEFAULT_IMAGE_TOKEN_COST)r   r   s   &&r   Úlearned_image_token_costr?   H   s   € ä‹8�<‰<œ˜UÓ-Ô/GÓHÐHr   c               ó   € V ^8„  d   QhRR/# )r   r   r+   r   )r   s   "r   r   r   M   s   € ÷ Dñ D #ñ Dr   c                 óB   € \         P                  4       p V e   V # \        # )z]Per-image cost bound for the running turn (see :func:`image_cost_context`), else the default.)r
   r8   r>   )Úbounds    r   Úcurrent_image_token_costrC   M   s!   € ä×ÑÓ!€EØÒ%ˆ5ÐCÔ+CÐCr   c               ó   € V ^8„  d   QhRR/# )r   ÚcostúOptional[int]r   )r   s   "r   r   r   T   s   € ÷ %ñ %˜]ñ %r   c              #  ó    "  € \         P                  V 4      p R x € \         P                  V4       R #   \         P                  T4       i ; i5i)N)r
   ÚsetÚreset)rE   Útokens   & r   Úimage_cost_contextrK   S   s9   é € ä×Ñ Ó%€Eð%Ûä×Ñ˜eÖ$øŒ×Ñ˜eÕ$üs   ‚A™4 �A´AÁAc               ó    € V ^8„  d   QhRRRR/# )r   Úagentr   r   ÚNoner   )r   s   "r   r   r   \   s   € ÷ sñ s ð s¨ñ sr   c           
     óp   € \         P                  \        \        V RR4      \        V RR4      4      4       R# )zXBind the agent's learned per-image cost to the current context for the rest of the turn.r   Nr   )r
   rH   r?   Úgetattr)rM   s   &r   Úbind_image_token_costrQ   \   s.   € ä×ÑÔ0´¸ÀÈÓ1NÔPWÐX]Ð_iÐkoÓPpÓqÖrr   c               ó    € V ^8„  d   QhRRRR/# )r   Úmessagesúlist[dict[str, Any]]r   r+   r   )r   s   "r   r   r   a   s   € ÷ Sñ SÐ/ð S°Cñ Sr   c                ó:   a€ ^ RI Ho \        V3R lV  4       4      # )r   )Ú_count_image_tokensc              3  óf   <"  € T F&  p\        V\        4      '       g   K  S! V^4      x € K(  	  R# 5i)é   N)r*   Údict)Ú.0ÚmrV   s   & €r   Ú	<genexpr>Úcount_images.<locals>.<genexpr>d   s(   øé € ÐR±(¨Q¼jÈÌD×>QÔ(Ñ" 1 a×(Ð(³(ùs   ƒ1 1)r   rV   Úsum)rS   rV   s   &@r   Úcount_imagesr_   a   s   ø€ Ý8äÔR±(ÓRÓRÐRr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rM   r   rS   rT   Úprompt_tokensr   rF   r   )r   s   "r   r   r   g   s+   € ÷ .ñ . ð .Ð/Cð .ÐTWð .Ð\iñ .r   c                ó¢  € ^ RI Hp \        V RR4      p \        T;'       g    ^ 4      pT^ 8:  g-   \        T\        4      '       d   \        T\        4      '       g   R# \        TP                  R4      ;'       g    ^ 4      pYR pT'       dD   \        T^ ,          \        4      '       d'   T^ ,          P                  R4      R8X  d
   TR,          p\        T4      pT^ 8:  d   R# \        ^ 4      ;_uu_ 4        T! Y4      p	RRR4       X	f   R# YY,
          T,          p
\        T
u;8:  d   \        8:  g    R#  R# \        \        T RR4      \        T R	R4      4      p\        4       pTP                  T4      pTf   T
M"\        T\         Y­,
          ,          ,           4      pYìT&   \"        P%                  T4        ^ R
IHp T! \+        4       \        T4      ^ RR7       \.        P3                  RYŠR TR T4       T#   \        \
        3 d     R# i ; i  + '       g   i     EL; i  \,         d    \.        P1                  RRR7        Lni ; i)a’  Learn the per-image cost from the response that just priced ``messages``.

Requires the PREVIOUS anchor (real count of the prior request) to still match: the residual
``prompt_tokens - (anchor + text-only delta)`` is then the provider's price for the images the
delta introduced. Returns the new learned cost, or None when this response teaches nothing
(no anchor, no new images, implausible residual).)Úanchored_context_tokensÚ_usage_anchorNÚ
base_countÚroleÚ	assistant:rX   NNr   r   )Úatomic_json_writeÚ,)ÚindentÚ
separatorszimage token cost persist failedT)Úexc_infozdImage token cost calibrated from provider usage: %s images priced %s tokens each (learned %s for %s))ri   Ú:)Úagent.usage_anchorrc   rP   r+   Ú	TypeErrorÚ
ValueErrorr*   rY   Úlistr8   r_   rK   r,   r-   r$   r;   Ú
_EMA_ALPHAr
   rH   r#   rh   r   Ú	ExceptionÚloggerÚdebugÚinfo)rM   rS   ra   rc   ÚanchorÚrealre   ÚdeltaÚn_imagesÚ	text_onlyÚ	per_imageÚkeyr:   ÚpriorÚlearnedrh   s   &&&             r   Úcalibrate_from_usager€   g   sò  € õ ;ä�U˜O¨TÓ2€FðÜ�=×%Ð% AÓ&ˆð ˆq„yœ
 6¬4×0Ò0¼
À8ÌT×8RÒ8RÙÜ�V—Z‘Z Ó-×2Ð2°Ó3€JØ�[Ð!€Eß”˜E !�H¤d×+Ò+°°aµ·±¸VÓ0DÈÔ0SØ�b•	ˆÜ˜EÓ"€HØ�1„}ÙÜ	˜A×	Õ	Ù+¨HÓ=ˆ	÷ 
àÒÙØÕ! hÕ.€IÜ˜YÖ8¬.Õ8Ùð 9ÙÜ
Œw�u˜g tÓ,¬g°e¸ZÈÓ.NÓ
O€CÜ‹H€EØ�I‰I�c‹N€EØ š=‰i¬c°%¼*È	ÕHYÕ:ZÕ2ZÓ.[€GØˆ#�JÜ×Ñ˜Ô ðGÝ+áœ+›-¬¨e«¸QÈ:ÕVô ‡K�KØnØ˜q�M w¨q k°Côð €NøôE ”zÐ"ô Úðú÷ 
×	Ð	ûô" ô GÜ�‰Ð6ÀˆÖFðGús4   •G= £G= Ã9	HÆ<#H) Ç=HÈHÈH&	È)"IÉI)$Ú__conditional_annotations__Ú__doc__Ú
__future__r   Ú
contextlibÚloggingÚcontextvarsr   Útypingr   r   r   r   Ú	getLoggerÚ__name__rt   r>   r,   r-   rr   r
   Ú__annotations__r   r6   r   r   r$   r0   r;   r?   rC   ÚcontextmanagerrK   rQ   r_   r€   )r�   s   @r   Ú<module>rŒ      sÄ   øðôõ #ã Û Ý "ß ,Ó ,à	×	Ò	˜8Ó	$€àÐ à!# VÐ €�Ø€
á-7Ð8QÐ[_Ô-`€Ð*Ó `Ø€ˆ.Ó Ø
€ð /1Ð Ð+Ó 0ò1õFõMõõ"Iõ
Dð ×Ñô%ó ð%õsõ
S÷.r   