+
    Ji[                      a  0 t $ ^ RIHt ^ RIHt ^ RIHtHt ^ RIHt ^ RI	H
t
HtHtHt ^ RIHtHt RRR	R/t]! R
4      t]! R4      t]Rh,          t]Ri,          t]! RR7       ! R R4      4       t]! RR7       ! R R4      4       t]! RR7       ! R R4      4       t]! RR7       ! R R4      4       tR t/ Rj]! ]! R4      ]! R4      ]! R4      ]! R4      RRRR7      bRk]! ]! R4      ]! R4      ]! R 4      ]! R!4      RRRR7      bRl]! ]! R"4      ]! R#4      ]! R$4      RR%R&R'7      bRm]! ]! R(4      ]! R)4      ]! R*4      RR%R&R'7      bRn]! ]! R+4      ]! R,4      ]! R-4      RR%R&R'7      bRo]! ]! R.4      ]! R/4      ]! R04      RR%R&R'7      bRp]! ]! R04      ]! R.4      ]! R14      RR%R&R'7      bRq]! ]! R#4      ]! R24      ]! R"4      RR%R&R'7      bRr]! ]! R34      ]! R44      ]! R54      RR%R&R'7      bRs]! ]! R4      ]! R4      ]! R 4      ]! R!4      RRR6R7      bRt]! ]! R74      ]! R84      ]! R94      ]! R:4      RRR6R7      bRu]! ]! R4      ]! R4      ]! R4      ]! R4      RRR6R7      bRv]! ]! R;4      ]! R$4      ]! R<4      ]! R 4      RRR6R7      bRw]! ]! R=4      ]! R>4      RR?R@RA7      bRx]! ]! R54      ]! RB4      RR?R@RA7      bRy]! ]! R$4      ]! R#4      RRCRDRA7      bRz]! ]! R(4      ]! R)4      RRCRDRA7      bR{]! ]! R04      ]! R.4      RRCRDRA7      /CtRE]RF&   RG RH ltRI RJ ltR|RL RM lltRN RO lt RP RQ lt!RR RS lt"R}RT RU llt#RVRKRWRK/RX RY llt$RVRKRZRKR[RK/R\ R] llt%R}R^ R_ llt&R}R` Ra llt'RVRKRZRKR[RK/Rb Rc llt(Rd Re lt)Rf Rg lt*RK# )~    )annotations)	dataclass)datetimetimezone)Decimal)AnyDictLiteralOptional)fetch_endpoint_model_metadatafetch_model_metadatainput        output01000000official_docs_snapshotT)frozenc                      ] tR t^t$ ^ tR]R&   ^ tR]R&   ^ tR]R&   ^ tR]R&   ^ t	R]R&   ^t
R]R&   RtR	]R
&   ]R R l4       t]R R l4       tRtR# )CanonicalUsageintinput_tokensoutput_tokenscache_read_tokenscache_write_tokensreasoning_tokensrequest_countNzOptional[dict[str, Any]]	raw_usagec                   V ^8  d   QhRR/#    returnr    )formats   "0/home/ubuntu/hermes-agent/agent/usage_pricing.py__annotate__CanonicalUsage.__annotate__&   s     T Ts T    c                	^    V P                   V P                  ,           V P                  ,           # N)r   r   r   selfs   &r%   prompt_tokensCanonicalUsage.prompt_tokens%   s$      4#9#99D<S<SSSr(   c                   V ^8  d   QhRR/# r    r#   )r$   s   "r%   r&   r'   *   s     7 7c 7r(   c                	<    V P                   V P                  ,           # r*   )r-   r   r+   s   &r%   total_tokensCanonicalUsage.total_tokens)   s    !!D$6$666r(   r#   )__name__
__module____qualname____firstlineno__r   __annotations__r   r   r   r   r   r   propertyr-   r1   __static_attributes__r#   r(   r%   r   r      st    L#M3scM3*.I'.T T 7 7r(   r   c                  H    ] tR t^.t$ R]R&   R]R&   RtR]R&   RtR]R&   RtR	# )
BillingRoutestrprovidermodel base_urlunknownbilling_moder#   N)r3   r4   r5   r6   r7   r@   rB   r9   r#   r(   r%   r;   r;   .   s     MJHc!L#!r(   r;   c                      ] tR t^6t$ RtR]R&   RtR]R&   RtR]R&   RtR]R&   Rt	R]R&   Rt
R	]R
&   RtR]R&   RtR]R&   RtR]R&   RtR# )PricingEntryNOptional[Decimal]input_cost_per_millionoutput_cost_per_millioncache_read_cost_per_millioncache_write_cost_per_millionrequest_costnone
CostSourcesourceOptional[str]
source_urlpricing_versionOptional[datetime]
fetched_atr#   )r3   r4   r5   r6   rF   r7   rG   rH   rI   rJ   rM   rO   rP   rR   r9   r#   r(   r%   rD   rD   6   sf    04-415.559!296: "3:&*L#*FJ $J$%)O])%)J")r(   rD   c                  j    ] tR t^Ct$ R]R&   R]R&   R]R&   R]R&   R	tR
]R&   R	tR]R&   RtR]R&   RtR	# )
CostResultrE   
amount_usd
CostStatusstatusrL   rM   r<   labelNrQ   rR   rN   rP   ztuple[str, ...]notesr#   )	r3   r4   r5   r6   r7   rR   rP   rY   r9   r#   r(   r%   rT   rT   C   s8    !!J%)J")%)O])E?r(   rT   c                 J    \         P                  ! \        P                  4      # r*   )r   nowr   utcr#   r(   r%   <lambda>r]   N   s    8<<-r(   z15.00z75.00z1.50z18.75zChttps://docs.anthropic.com/en/docs/build-with-claude/prompt-cachingz#anthropic-prompt-caching-2026-03-16)rF   rG   rH   rI   rM   rO   rP   z3.00z0.30z3.75z2.50z10.00z1.25zhttps://openai.com/api/pricing/zopenai-pricing-2026-03-16)rF   rG   rH   rM   rO   rP   z0.15z0.60z0.075z2.00z8.00z0.50z0.40z1.60z0.10z0.025z40.00z1.10z4.40z0.55zanthropic-pricing-2026-03-16z0.80z4.00z0.08z1.00z0.25z0.03z0.14z0.28z1https://api-docs.deepseek.com/quick_start/pricingzdeepseek-pricing-2026-03-16)rF   rG   rM   rO   rP   z2.19zhttps://ai.google.dev/pricingzgoogle-pricing-2026-03-16z#Dict[tuple[str, str], PricingEntry]_OFFICIAL_DOCS_PRICINGc                    V ^8  d   QhRRRR/# )r!   valuer   r"   rE   r#   )r$   s   "r%   r&   r&   "  s      s 0 r(   c                \    V f   R #  \        \        V 4      4      #   \         d     R # i ; ir*   )r   r<   	Exceptionr`   s   &r%   _to_decimalrd   "  s0    }s5z"" s    ++c                    V ^8  d   QhRRRR/# )r!   r`   r   r"   r   r#   )r$   s   "r%   r&   r&   +  s      3 3 r(   c                R     \        T ;'       g    ^ 4      #   \         d     ^ # i ; i)r   )r   rb   rc   s   &r%   _to_intrg   +  s)    5::A s     &&Nc               (    V ^8  d   QhRRRRRRRR/# )r!   
model_namer<   r=   rN   r@   r"   r;   r#   )r$   s   "r%   r&   r&   2  s6     [ [[[ [ 	[r(   c                   T;'       g    R P                  4       P                  4       pT;'       g    R P                  4       P                  4       pT ;'       g    R P                  4       pV'       g'   RV9   d    VP                  R^4      w  rgVR9   d   TpTpVR8X  d   \        RYR;'       g    R RR7      # VR8X  g   RV9   d   \        RYR;'       g    R R	R7      # VR8X  d0   \        RVP                  R4      R,          T;'       g    R R
R7      # VR8X  d0   \        RVP                  R4      R,          T;'       g    R R
R7      # VR9   g   V'       d*   RV9   d#   \        T;'       g    RYR;'       g    R RR7      # \        T;'       g    RV'       d   VP                  R4      R,          MR T;'       g    R RR7      # )r?   /	anthropicopenaizopenai-codexsubscription_included)r=   r>   r@   rB   
openrouterzopenrouter.aiofficial_models_apir   custom	localhostrA   >   googlerm   rl   >   localrq   )striplowersplitr;   )ri   r=   r@   provider_namebaser>   inferred_provider
bare_models   &&&     r%   resolve_billing_router}   2  s   
 ^^**,224MNN!!#))+D2$$&ESE\(-C(;% AA-ME&^5>>WYh  A  	A$4(?\UWf{||#[C8H8LW_WeWece  uM  N  	N XU[[5Eb5IT\TbTb`b  rJ  K  	K++9L]%>%>heVdVdbds|}}!;!;)[`5;;sCSTVCWfhs{  tB  tB  @B  QZ  [  [r(   c                    V ^8  d   QhRRRR/# r!   router;   r"   Optional[PricingEntry]r#   )r$   s   "r%   r&   r&   M  s     M M M:P Mr(   c                t    \         P                  V P                  V P                  P	                  4       34      # r*   )r^   getr=   r>   rw   r   s   &r%   _lookup_official_docs_pricingr   M  s)    !%%u~~u{{7H7H7J&KLLr(   c                    V ^8  d   QhRRRR/# r   r#   )r$   s   "r%   r&   r&   Q  s      \ 6L r(   c                D    \        \        4       V P                  R RR7      # )z>https://openrouter.ai/docs/api/api-reference/models/get-modelszopenrouter-models-apirO   rP   )_pricing_entry_from_metadatar   r>   r   s   &r%   _openrouter_pricing_entryr   Q  s"    'S/	 r(   c          
     ,    V ^8  d   QhRRRRRRRRRR/# )	r!   metadatazDict[str, Dict[str, Any]]model_idr<   rO   rP   r"   r   r#   )r$   s   "r%   r&   r&   Z  s:     ) )')) 	)
 ) )r(   c                  W9  d   R # W,          P                  R4      ;'       g    / p\        VP                  R4      4      p\        VP                  R4      4      p\        VP                  R4      4      p\        VP                  R4      ;'       g+    VP                  R4      ;'       g    VP                  R4      4      p\        VP                  R4      ;'       g+    VP                  R	4      ;'       g    VP                  R
4      4      p	Vf   Vf   Vf   R # R R lp
\        V
! V4      V
! V4      V
! V4      V
! V	4      VRVV\        4       R7	      # )Npricingprompt
completionrequest
cache_readcached_promptinput_cache_readcache_writecache_creationinput_cache_writec                    V ^8  d   QhRRRR/# )r!   r`   rE   r"   r#   )r$   s   "r%   r&   2_pricing_entry_from_metadata.<locals>.__annotate__t  s     $ $): $?P $r(   c                (    V f   R # V \         ,          # r*   )_ONE_MILLIONrc   s   &r%   _per_token_to_per_million?_pricing_entry_from_metadata.<locals>._per_token_to_per_milliont  s    =|##r(   provider_models_api)	rF   rG   rH   rI   rJ   rM   rO   rP   rR   )r   rd   rD   _UTC_NOW)r   r   rO   rP   r   r   r   r   r   r   r   s   &&$$       r%   r   r   Z  sB     $$Y/552GX./FW[[67J'++i01GL! 	+ 	+;;'	+ 	+;;)*J
 M" 	, 	,;;'(	, 	,;;*+K
 ~*,$
 8@ 9* E$=j$I%>{%K$':
 
r(   c          
     ,    V ^8  d   QhRRRRRRRRRR/# )	r!   ri   r<   r=   rN   r@   api_keyr"   r   r#   )r$   s   "r%   r&   r&     s:     0 000 0 	0
 0r(   c           	        \        WVR 7      pVP                  R8X  d"   \        \        \        \        \        RRR7      # VP                  R8X  d   \        V4      # VP                  '       d_   \        \        VP                  T;'       g    RR7      VP                  VP                  P                  R4       R	2R
R7      pV'       d   V# \        V4      # )r=   r@   rn   rK   included-route)rF   rG   rH   rI   rM   rP   ro   r?   )r   rk   z/modelszopenai-compatible-models-apir   )r}   rB   rD   _ZEROr=   r   r@   r   r   r>   rstripr   ri   r=   r@   r   r   entrys   &&&&  r%   get_pricing_entryr     s     "*(SE44#($)(-).,
 	
 ~~%(//~~~,)%..'--RPKK..//45W=:	
 L(//r(   r=   api_modec               (    V ^8  d   QhRRRRRRRR/# )r!   response_usager   r=   rN   r   r"   r   r#   )r$   s   "r%   r&   r&     s2     : :: : 	:
 :r(   c               h   V '       g   \        4       # T;'       g    RP                  4       P                  4       pT;'       g    RP                  4       P                  4       pVR8X  g   VR8X  d[   \        \	        V R^ 4      4      p\        \	        V R^ 4      4      p\        \	        V R^ 4      4      p\        \	        V R^ 4      4      pEM,VR8X  d   \        \	        V R^ 4      4      p	\        \	        V R^ 4      4      p\	        V R	R
4      p
\        V
'       d   \	        V
R^ 4      M^ 4      p\        V
'       d   \	        V
R^ 4      M^ 4      p\        ^ W,
          V,
          4      pM\        \	        V R^ 4      4      p\        \	        V R^ 4      4      p\	        V RR
4      p
\        V
'       d   \	        V
R^ 4      M^ 4      p\        V
'       d   \	        V
R^ 4      M^ 4      p\        ^ W,
          V,
          4      p^ p\	        V RR
4      pV'       d   \        \	        VR^ 4      4      p\        VVVVVR7      # )ue  Normalize raw API response usage into canonical token buckets.

Handles three API shapes:
- Anthropic: input_tokens/output_tokens/cache_read_input_tokens/cache_creation_input_tokens
- Codex Responses: input_tokens includes cache tokens; input_tokens_details.cached_tokens separates them
- OpenAI Chat Completions: prompt_tokens includes cache tokens; prompt_tokens_details.cached_tokens separates them

In both Codex and OpenAI modes, input_tokens is derived by subtracting cache
tokens from the total — the API contract is that input/prompt totals include
cached tokens and the details object breaks them out.
r?   anthropic_messagesrl   r   r   cache_read_input_tokenscache_creation_input_tokenscodex_responsesinput_tokens_detailsNcached_tokenscache_creation_tokensr-   completion_tokensprompt_tokens_detailsr   output_tokens_detailsr   )r   r   r   r   r   )r   rv   rw   rg   getattrmax)r   r=   r   ry   moder   r   r   r   input_totaldetailsprompt_totalr   output_detailss   &$$           r%   normalize_usager     s   " ^^**,224MNN!!#))+D##}'Cw~~qIJ KL#GN<UWX$YZ$W^=Z\]%^_	"	"gnnaHI KL.*@$G#GGG_a$HYZ[$<CGG4a8
 1k=@RRSw~JK8KQ OP.*A4H#GGG_a$HYZ[$9@GG115a
 1l>ASST^-DdKN"7>;Mq#QR!#+-) r(   r@   r   c               0    V ^8  d   QhRRRRRRRRRRR	R
/# )r!   ri   r<   usager   r=   rN   r@   r   r"   rT   r#   )r$   s   "r%   r&   r&     sL     L LLL 	L
 L L Lr(   c               Z   \        WVR 7      pVP                  R8X  d   \        \        RRRRR7      # \	        WW4R7      pV'       g   \        RRRR	R
7      # . p\        pVP
                  '       d(   VP                  f   \        RRVP                  R	R
7      # VP                  '       d(   VP                  f   \        RRVP                  R	R
7      # VP                  '       d)   VP                  f   \        RRVP                  R	RR7      # VP                  '       d)   VP                  f   \        RRVP                  R	RR7      # VP                  e9   V\        VP
                  4      VP                  ,          \        ,          ,          pVP                  e9   V\        VP                  4      VP                  ,          \        ,          ,          pVP                  e9   V\        VP                  4      VP                  ,          \        ,          ,          pVP                  e9   V\        VP                  4      VP                  ,          \        ,          ,          pVP                   e@   VP"                  '       d.   V\        VP"                  4      VP                   ,          ,          pRp	RVR 2p
VP                  R8X  d   V\        8X  d   Rp	Rp
VP$                  R8X  d   VP'                  R4       \        VV	VP                  V
VP(                  VP*                  \-        V4      R7      # )r   rn   includedrK   r   )rU   rW   rM   rX   rP   r=   r@   r   NrA   zn/a)rU   rW   rM   rX   )rU   rW   rM   rX   rY   	estimatedz~$.2fro   zBOpenRouter cost is estimated from the models API until reconciled.)rU   rW   rM   rX   rR   rP   rY   )z(cache-read pricing unavailable for route)z)cache-write pricing unavailable for route)r}   rB   rT   r   r   r   rF   rM   r   rG   r   rH   r   rI   r   r   rJ   r   r=   appendrR   rP   tuple)ri   r   r=   r@   r   r   r   rY   amountrW   rX   s   &&$$$      r%   estimate_usage_costr     s    "*(SE44,
 	
 jh`ET)FRWXXEFe::BT)ELLX]^^u<<DT)ELLX]^^,,4 ||C  --5 ||D  ##/'%,,-0L0LL|[[$$0'%--.1N1NNQ]]]((4'%112U5V5VVYeee))5'%223e6X6XX[ggg%%*=*=*='%--.1C1CCC$FE||v&E/~~%YZ||##--El r(   c          
     ,    V ^8  d   QhRRRRRRRRRR/# )	r!   ri   r<   r=   rN   r@   r   r"   boolr#   )r$   s   "r%   r&   r&   0  s:        	
 
r(   c                d    \        WVR7      pVP                  R8X  d   R# \        WW#R7      pVRJ# )u   Check whether we have pricing data for this model+route.

Uses direct lookup instead of routing through the full estimation
pipeline — avoids creating dummy usage objects just to check status.
r   rn   Tr   N)r}   rB   r   r   s   &&&&  r%   has_known_pricingr   0  s9     "*(SE44jh`Er(   c          
     ,    V ^8  d   QhRRRRRRRRRR/# )	r!   ri   r<   r=   rN   r@   r   r"   zDict[str, float]r#   )r$   s   "r%   r&   r&   B  s:        	
 r(   c                    \        WW#R7      pV'       g   RRRR/# R\        VP                  ;'       g    \        4      R\        VP                  ;'       g    \        4      /# )zBackward-compatible thin wrapper for legacy callers.

Returns only non-cache input/output fields when a pricing entry exists.
Unknown routes return zeroes.
r   r   r   r   )r   floatrF   r   rG   )ri   r=   r@   r   r   s   &&&& r%   get_pricingr   B  s\     jh`Eh,,u33<<u=%55>>? r(   c               4    V ^8  d   QhRRRRRRRRRRR	RR
R/# )r!   r>   r<   r   r   r   r=   rN   r@   r   r"   r   r#   )r$   s   "r%   r&   r&   V  sN     - --- -
 - - - -r(   c               |    \        V \        WR7      VVVR7      p\        VP                  ;'       g    \        4      # )zBackward-compatible helper for legacy callers.

This uses non-cached input/output only. New code should call
`estimate_usage_cost()` with canonical usage buckets.
)r   r   r   )r   r   r   rU   r   )r>   r   r   r=   r@   r   results   &&&$$$ r%   estimate_cost_usdr   V  s=     !LNF ""++e,,r(   c                    V ^8  d   QhRRRR/# )r!   secondsr   r"   r<   r#   )r$   s   "r%   r&   r&   n  s      U s r(   c                    V ^<8  d   V R R2# V ^<,          pV^<8  d   VR R2# V^<,          pV^8  d:   \        V^<,          4      pV'       d   \        V4       RV R2# \        V4       R2# V^,          pVR R2# )<   .0fsmzh h.1fd)r   )r   minuteshoursremaining_mindayss   &    r%   format_duration_compactr   n  s    |#a  lG|#a  bLErzGbL)4A#e*Ra0W#e*UVGWW2:D3Zq>r(   c                    V ^8  d   QhRRRR/# )r!   r`   r   r"   r<   r#   )r$   s   "r%   r&   r&   |  s      c c r(   c                N   \        \        V 4      4      pVR 8  d   \        \        V 4      4      # V ^ 8  d   RMRpR	pV F`  w  rEW8  g   K  W,          pV^
8  d   VR pMV^d8  d   VR pMVR pRV9   d!   VP                  R4      P                  R4      pV V V 2u # 	  V R # )
  -r?   r   r   r   .r   ,))i ʚ;B)i@B M)r   K)absr   r<   r   )r`   	abs_valuesignunits	thresholdsuffixscaledtexts   &       r%   format_token_count_compactr   |  s    CJI53u:!)3DBE"	!*F{ #  d{{{3'..s3VD6&** # AYr(   )actualr   r   rA   )provider_cost_apiprovider_generation_apir   r   user_overridecustom_contractrK   )rl   zclaude-opus-4-20250514)rl   zclaude-sonnet-4-20250514)rm   zgpt-4o)rm   zgpt-4o-mini)rm   zgpt-4.1)rm   zgpt-4.1-mini)rm   zgpt-4.1-nano)rm   o3)rm   zo3-mini)rl   zclaude-3-5-sonnet-20241022)rl   zclaude-3-5-haiku-20241022)rl   zclaude-3-opus-20240229)rl   zclaude-3-haiku-20240307)deepseekzdeepseek-chat)r   zdeepseek-reasoner)rs   zgemini-2.5-pro)rs   zgemini-2.5-flash)rs   zgemini-2.0-flash)NN)NNN)+__conditional_annotations__
__future__r   dataclassesr   r   r   decimalr   typingr   r	   r
   r   agent.model_metadatar   r   DEFAULT_PRICINGr   r   rV   rL   r   r;   rD   rT   r   r^   r7   rd   rg   r}   r   r   r   r   r   r   r   r   r   r   r   )r   s   @r%   <module>r     sS   " " ! '  / / TC3/y!AB

 $7 7 7$ $" " " $	* 	* 	* $      .
L? &w/ ' 0$+FO%,W%5'X=	L? &v ' 0$+FO%,V_'X=!L?4 &v ' 0$+FO'43;L?J &v '$+G$4'43QL?` &v '$+FO'43gL?v &v '$+FO'43}L?L &v '$+G$4'43SL?b &w/ ' 0$+FO'43iL?x &v '$+FO'43L?P &v ' 0$+FO%,V_'X6WL?h &v '$+FO%,V_'X6oL?@ &w/ ' 0$+FO%,W%5'X6GL?X &v '$+FO%,V_'X6_L?r &v ''F5yL?F &v ''F5ML?\ &v ' 0'23cL?p &v ''23wL?D &v ''23KL? ; L^[6M)X0<: #: #	:zL #	L
 #L "L^$(-
 #- #- "-0r(   