§
    ÷žyj�  ã                  ó|  — d dl mZ d dlZd dlZd dlmZ d dlmZmZ d dlm	Z	m
Z
mZ d dlZd dlmZmZ d dlmZmZmZ d dlmZ e	rd d	lmZ  ej        e¦  «        ZdFd„Z ed¬¦  «         G d„ d¦  «        ¦   «         Z ed¬¦  «         G d„ d¦  «        ¦   «         ZdGd„ZdHd„ZdId„ZddœdJd#„Z dKd&„Z!dLd)„Z"dMd*„Z#dd+d,œdNd.„Z$dMd/„Z% ed¬¦  «         G d0„ d1¦  «        ¦   «         Z&dd+d,œdOd2„Z'dPd5„Z(dQd6„Z)dRd9„Z*	 	 dSdTd:„Z+ ed¬¦  «         G d;„ d<¦  «        ¦   «         Z,d=Z-dddd>œdUd@„Z.dMdA„Z/dTdB„Z0dddCœdVdE„Z1dS )Wé    )ÚannotationsN)Ú	dataclass)ÚdatetimeÚtimezone)ÚTYPE_CHECKINGÚAnyÚOptional)Ú_is_oauth_tokenÚresolve_anthropic_token)Ú	AuthErrorÚ_read_codex_tokensÚ!resolve_codex_runtime_credentials)Úresolve_runtime_provider)Ú	TypeGuardÚreturnr   c                 ó>   — t          j        t          j        ¦  «        S ©N)r   Únowr   Úutc© ó    ú9/home/ragecks/.hermes/hermes-agent/agent/account_usage.pyÚ_utc_nowr      s   € ÝŒ<�œÑ%Ô%Ð%r   T)Úfrozenc                  óD   — e Zd ZU ded<   dZded<   dZded<   dZded	<   dS )
ÚAccountUsageWindowÚstrÚlabelNzOptional[float]Úused_percentúOptional[datetime]Úreset_atúOptional[str]Údetail)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r   r!   r#   r   r   r   r   r      sN   € € € € € € à€J€J�JØ$(€LÐ(Ð(Ð(Ñ(Ø#'€HÐ'Ð'Ð'Ñ'Ø €FÐ Ð Ð Ñ Ð Ð r   r   c                  óŒ   — e Zd ZU ded<   ded<   ded<   dZded<   dZd	ed
<   dZded<   dZded<   dZd	ed<   e	dd„¦   «         Z
dS )ÚAccountUsageSnapshotr   ÚproviderÚsourcer   Ú
fetched_atzAccount limitsÚtitleNr"   Úplanr   ztuple[AccountUsageWindow, ...]Úwindowsútuple[str, ...]ÚdetailsÚunavailable_reasonr   Úboolc                óH   — t          | j        p| j        ¦  «        o| j         S r   )r3   r/   r1   r2   ©Úselfs    r   Ú	availablezAccountUsageSnapshot.available,   s$   € å�D”LÐ0 D¤LÑ1Ô1ÐQ¸$Ô:QÐ6QÐQr   ©r   r3   )r$   r%   r&   r'   r-   r.   r/   r1   r2   Úpropertyr7   r   r   r   r)   r)   !   s®   € € € € € € à€M€M�MØ€K€K�KØÐÐÑØ!€EÐ!Ð!Ð!Ñ!Ø€DÐÐÐÑØ.0€GÐ0Ð0Ð0Ñ0Ø!€GÐ!Ð!Ð!Ñ!Ø(,ÐÐ,Ð,Ð,Ñ,àðRð Rð Rñ „XðRð Rð Rr   r)   Úvaluer"   c                óÈ   — t          | pd¦  «                             ¦   «         }|sd S |                     dd¦  «                             dd¦  «                             ¦   «         S )NÚ Ú_Ú Ú-)r   ÚstripÚreplacer-   )r:   Úcleaneds     r   Ú_title_case_slugrC   1   s\   € Ý�%�+˜2ÑÔ×$Ò$Ñ&Ô&€GØð ØˆtØ�?Š?˜3 Ñ$Ô$×,Ò,¨S°#Ñ6Ô6×<Ò<Ñ>Ô>Ð>r   r   r    c                óà  — | dv rd S t          | t          t          f¦  «        r-t          j        t          | ¦  «        t
          j        ¬¦  «        S t          | t          ¦  «        r‰|                      ¦   «         }|sd S | 	                    d¦  «        r|d d…         dz   }	 t          j
        |¦  «        }|j        r|n|                     t
          j        ¬¦  «        S # t          $ r Y d S w xY wd S )N>   Nr<   )ÚtzÚZéÿÿÿÿz+00:00)Útzinfo)Ú
isinstanceÚintÚfloatr   Úfromtimestampr   r   r   r@   ÚendswithÚfromisoformatrH   rA   Ú
ValueError)r:   ÚtextÚdts      r   Ú	_parse_dtrR   8   sö   € Ø�
ÐÐØˆtÝ�%�#�u˜Ñ&Ô&ð EÝÔ%¥e¨E¡l¤lµx´|ÐDÑDÔDÐDÝ�%�ÑÔð 
Ø�{Š{‰}Œ}ˆØð 	Ø�4Ø�=Š=˜ÑÔð 	(Ø˜˜˜”9˜xÑ'ˆDð	ÝÔ'¨Ñ-Ô-ˆBØœÐG�2�2¨¯
ª
½(¼,¨
Ñ(GÔ(GÐGøÝð 	ð 	ð 	Ø�4�4ð	øøøàˆ4s   Â <C Ã
C+Ã*C+rQ   r   c                ó¬  — | sdS |                       ¦   «         }| t          ¦   «         z
  }t          |                     ¦   «         ¦  «        }|dk    rd|                     d¦  «        › d�S t          |d¦  «        \  }}|dz  }|dk    rt          |d¦  «        \  }}d	|› d
|› d�}n|dk    r
d	|› d|› d�}nd	|› d�}|› d|                     d¦  «        › d�S )NÚunknownr   znow (z%Y-%m-%d %H:%M %Zú)i  é<   é   zin zd Úhzh Úmú ()Ú
astimezoner   rJ   Útotal_secondsÚstrftimeÚdivmod)	rQ   Úlocal_dtÚdeltar\   ÚhoursÚremÚminutesÚdaysÚrels	            r   Ú_format_resetrf   K   s  € Øð ØˆyØ�}Š}‰Œ€HØ•‘”‰O€EÝ˜×+Ò+Ñ-Ô-Ñ.Ô.€MØ˜ÒÐØ@�x×(Ò(Ð)<Ñ=Ô=Ð@Ð@Ð@Ð@Ý˜ tÑ,Ô,�J€Eˆ3Ø�R‰i€GØ�‚{€{Ý˜U BÑ'Ô'‰ˆˆeØ$�DÐ$Ð$˜EÐ$Ð$Ð$ˆˆØ	�ŠˆØ'�EÐ'Ð'˜WÐ'Ð'Ð'ˆˆà�GÐÐÐˆØÐ>Ð>�X×&Ò&Ð':Ñ;Ô;Ð>Ð>Ð>Ð>r   F©ÚmarkdownÚsnapshotúOptional[AccountUsageSnapshot]rh   r3   ú	list[str]c          
     ó  — | sg S d|rdnd› | j         › |rdnd› �}|g}| j        r'|                     d| j        › d| j        › d�¦  «         n|                     d| j        › �¦  «         | j        D ]Ð}|j        €|j        › d�}nqt          dt          d	t          |j        ¦  «        z
  ¦  «        ¦  «        }t          dt          t          |j        ¦  «        ¦  «        ¦  «        }|j        › d
|› d|› d�}|j
        r|dt          |j
        ¦  «        › �z  }n|j        r|d|j        › �z  }|                     |¦  «         ŒÑ| j        D ]}|                     |¦  «         Œ| j        r|                     d| j        › �¦  «         |S )Nu   ðŸ“ˆ z**r<   z
Provider: rZ   rU   z: unavailabler   éd   z: z% remaining (z% used)u    â€¢ resets õ    â€¢ zUnavailable: )r-   r.   Úappendr*   r/   r   r   ÚmaxÚroundrK   r!   rf   r#   r1   r2   )	ri   rh   ÚheaderÚlinesÚwindowÚbaseÚ	remainingÚusedr#   s	            r   Úrender_account_usage_linesrx   _   sá  € Øð Øˆ	ØY˜XÐ-�T�T¨2ÐY¨x¬~ÐYÀxÐ?W¸t¸tÐUWÐYÐY€FØˆH€EØ„}ð 7Ø�ŠÐG (Ô"3ÐGÐG°x´}ÐGÐGÐGÑHÔHÐHÐHà�ŠÐ5 (Ô"3Ð5Ð5Ñ6Ô6Ð6ØÔ"ð ð ˆØÔÐ&Ø”lÐ1Ð1Ð1ˆDˆDå˜A�u S­5°Ô1DÑ+EÔ+EÑ%EÑFÔFÑGÔGˆIÝ�q�%¥ fÔ&9Ñ :Ô :Ñ;Ô;Ñ<Ô<ˆDØ”lÐKÐK iÐKÐK¸dÐKÐKÐKˆDØŒ?ð 	,ØÐC¥=°´Ñ#AÔ#AÐCÐCÑCˆDˆDØŒ]ð 	,ØÐ+˜FœMÐ+Ð+Ñ+ˆDØ�Š�TÑÔÐÐØÔ"ð ð ˆØ�Š�VÑÔÐÐØÔ"ð DØ�ŠÐB XÔ%@ÐBÐBÑCÔCÐCØ€Lr   ÚdrK   c                ó   — d| d›�S )Nú$z,.2fr   )ry   s    r   Ú_fmt_usdr|   {   s   € Øˆqˆ<ˆ<ˆ<Ðr   ÚvúTypeGuard[float]c                óŽ   — t          | t          t          f¦  «        o)t          | t          ¦  «         ot	          j        | ¦  «        S )u"  True iff v is a real numeric value (int or float, not bool, not NaN/Inf).

    Typed as a ``TypeGuard[float]`` so the type checker narrows ``v`` to a real
    number in the positive branch â€” callers can then do arithmetic / pass it to
    ``_fmt_usd`` without a None-operand warning.
    )rI   rJ   rK   r3   ÚmathÚisfinite)r}   s    r   Ú_is_finite_numr‚      s:   € õ �a�#�u˜Ñ&Ô&ÐW­z¸!½TÑ/BÔ/BÐ+BÐWÅtÄ}ÐUVÑGWÔGWÐWr   c                ó.  — 	 ddl m} | �t          | dd¦  «        sdS t          | dd¦  «        }t          | dd¦  «        }g }g }|�ºt          |dd¦  «        }t          |d	d¦  «        }t          |¦  «        r‰|dk    rƒt          |¦  «        rt||k    rn||z
  }t	          d
t          d||z  dz  ¦  «        ¦  «        }	|                     t          d|	t          |¦  «        › dt          |¦  «        › d�¬¦  «        ¦  «         |�Ït          |dd¦  «        }
t          |
¦  «        r%|                     dt          |
¦  «        › �¦  «         t          |dd¦  «        }t          |¦  «        r%|                     dt          |¦  «        › �¦  «         t          |dd¦  «        }t          |¦  «        r%|                     dt          |¦  «        › �¦  «         |�vt          |dd¦  «        }t          |¦  «        r+|dk    r%|                     dt          |¦  «        › �¦  «         t          |dd¦  «        }|r|                     d|› �¦  «         t          | dd¦  «        }|du r|                     d¦  «         |s|sdS |                     d || ¦  «        › �¦  «         |                     d¦  «         |�t          |dd¦  «        nd}t          dd t          ¦   «         d!|t          |¦  «        t          |¦  «        ¬"¦  «        S # t          t          f$ r Y dS w xY w)#a  Map a NousPortalAccountInfo into an AccountUsageSnapshot for /usage.

    Shows dollar magnitudes (subscription / top-up / total) + renewal date + a
    portal CTA. When the portal supplies a subscription denominator
    (``monthly_credits``), also emits a subscription-usage window so the renderer
    shows a real ``% used`` gauge; when it's absent (older portals) the view
    gracefully degrades to magnitudes-only. Returns None when there's no usable
    account info to show (fail-open: caller just shows nothing).
    r   )Únous_portal_topup_urlNÚ	logged_inFÚpaid_service_access_infoÚsubscriptionÚmonthly_creditsÚcredits_remainingç        ç      Y@ÚSubscriptionz of ú left©r   r   r#   Úsubscription_credits_remainingzSubscription credits: Úpurchased_credits_remainingzTop-up credits: Útotal_usable_creditszTotal usable: Úrollover_creditsz
Rollover: Úcurrent_period_endzRenews: Úpaid_service_accessõ-   Status: access depleted â€” top up to restorezTop up: z(or run /topup)r.   Únouszportal-accountúNous credits)r*   r+   r,   r-   r.   r/   r1   )Úhermes_cli.nous_accountr„   Úgetattrr‚   rp   Úminro   r   r|   r)   r   ÚtupleÚAttributeErrorÚ	TypeError)Úaccount_infor„   ÚaccessÚsubr/   r1   rˆ   Úsub_remainingrw   Úused_pctÚsub_creditsÚ	purchasedÚtotal_usableÚrolloverÚ
period_endÚpaidr.   s                    r   Úbuild_nous_credits_snapshotr©   ‰   s   € ðSØAÐAÐAÐAÐAÐAàÐ¥w¨|¸[È%Ñ'PÔ'PÐØ�4å˜Ð'AÀ4ÑHÔHˆÝ�l N°DÑ9Ô9ˆà,.ˆØˆð ˆ?Ý% cÐ+<¸dÑCÔCˆOÝ# CÐ)<¸dÑCÔCˆMå˜Ñ/Ô/ðà# aÒ'Ð'Ý" =Ñ1Ô1ð (à! _Ò4Ð4à&¨Ñ6�Ý˜s¥C¨¨t°oÑ/EÈÑ/MÑ$NÔ$NÑOÔO�Ø—’Ý&Ø,Ø%-Ý"*¨=Ñ"9Ô"9Ð_Ð_½xÈÑ?XÔ?XÐ_Ð_Ð_ðñ ô ñô ð ð ÐÝ! &Ð*JÈDÑQÔQˆKÝ˜kÑ*Ô*ð QØ—’ÐO½ÀÑ8MÔ8MÐOÐOÑPÔPÐPÝ Ð(EÀtÑLÔLˆIÝ˜iÑ(Ô(ð IØ—’ÐGµ(¸9Ñ2EÔ2EÐGÐGÑHÔHÐHÝ" 6Ð+AÀ4ÑHÔHˆLÝ˜lÑ+Ô+ð JØ—’ÐHµ¸Ñ0FÔ0FÐHÐHÑIÔIÐIàˆ?Ý˜sÐ$6¸Ñ=Ô=ˆHÝ˜hÑ'Ô'ð B¨H°qªL¨LØ—’Ð@­H°XÑ,>Ô,>Ð@Ð@ÑAÔAÐAÝ  Ð&:¸DÑAÔAˆJØð 8Ø—’Ð6¨*Ð6Ð6Ñ7Ô7Ð7å�|Ð%:¸DÑAÔAˆØ�5ˆ=ˆ=Ø�NŠNÐJÑKÔKÐKàð 	˜wð 	Ø�4à�ŠÐGÐ"7Ð"7¸Ñ"EÔ"EÐGÐGÑHÔHÐHØ�ŠÐ(Ñ)Ô)Ð)à-0¨_�w�s˜F DÑ)Ô)Ð)À$ˆÝ#ØØ#Ý‘z”zØ ØÝ˜'‘N”NÝ˜'‘N”Nð
ñ 
ô 
ð 	
øõ �IÐ&ð ð ð Øˆtˆtðøøøs   ‚K? �IK? É8BK? Ë?LÌLç      $@)rh   Útimeoutr«   c                óÆ  — 	 ddl m}  |¦   «         }n# t          $ r d}Y nw xY w|� t          |¦  «        }t	          || ¬¦  «        S 	 ddlm}  |d¦  «        pi                      d¦  «        }t          |t          ¦  «        r| 
                    ¦   «         sg S n# t          $ r g cY S w xY w	 ddl}ddlm} |j                             d	¬
¦  «        5 }	|	                     |d¬¦  «                             |¬¦  «        }
ddd¦  «         n# 1 swxY w Y   t%          |
¦  «        }t	          || ¬¦  «        S # t          $ r! t&                               dd¬¦  «         g cY S w xY w)aÖ  Return rendered Nous-credits /usage lines, or [] when there's nothing to show.

    Account-independent of any live agent: gated on "a Nous account is logged in"
    (a cheap local auth-state check), then a wall-clock-bounded portal fetch. Shared
    by the CLI ``_show_usage`` and the TUI ``session.usage`` RPC so both surfaces show
    the same block regardless of session API-call count or resume state. Fail-open:
    any auth/portal hiccup or timeout returns [] (the caller shows nothing).

    Dev override: when HERMES_DEV_CREDITS_FIXTURE selects a fixture state, /usage
    renders from that fixture instead of the real portal (so the block + gauge are
    testable without a live account). Throwaway scaffolding.
    r   )Údev_fixture_credits_stateNrg   ©Úget_provider_auth_stater–   Úaccess_token)Úget_nous_portal_account_infoé   ©Úmax_workersT©Úforce_fresh©r«   u9   credits â–¸ /usage portal fetch/render failed (fail-open)©Úexc_info)Úagent.credits_trackerr­   Ú	ExceptionÚ_snapshot_from_credits_staterx   Úhermes_cli.authr¯   ÚgetrI   r   r@   Úconcurrent.futuresr˜   r±   ÚfuturesÚThreadPoolExecutorÚsubmitÚresultr©   ÚloggerÚdebug)rh   r«   r­   Úfixtureri   r¯   ÚtokÚ
concurrentr±   ÚpoolÚaccounts              r   Únous_credits_linesrË   é   s  € ðØCÐCÐCÐCÐCÐCà+Ð+Ñ-Ô-ˆˆøÝð ð ð ØˆˆˆðøøøàÐÝ/°Ñ8Ô8ˆÝ)¨(¸XÐFÑFÔFÐFðØ;Ð;Ð;Ð;Ð;Ð;à&Ð& vÑ.Ô.Ð4°"×9Ò9¸.ÑIÔIˆÝ˜3¥Ñ$Ô$ð 	¨¯ª©¬ð 	ØˆIð	øåð ð ð Øˆ	ˆ	ˆ	ðøøøðØ!Ð!Ð!Ð!àHÐHÐHÐHÐHÐHàÔ×2Ò2¸qÐ2ÑAÔAð 	&ÀTØ—k’kØ,¸$ð "ñ ô çŠf˜WˆfÑ%Ô%ð ð	&ð 	&ð 	&ñ 	&ô 	&ð 	&ð 	&ð 	&ð 	&ð 	&ð 	&øøøð 	&ð 	&ð 	&ð 	&õ /¨wÑ7Ô7ˆÝ)¨(¸XÐFÑFÔFÐFøÝð ð ð õ 	�ŠÐPÐ[_ˆÑ`Ô`Ð`Øˆ	ˆ	ˆ	ð	øøøsU   ‚ “"¡"ÁAB ÂB)Â(B)Â-%D5 Ã,D
Ã>D5 Ä
DÄD5 ÄDÄ"D5 Ä5(E ÅE c                ó®  — 	 | €dS g }g }t          | dd¦  «        }t          |t          t          f¦  «        r‰t	          j        |¦  «        rut          | dd¦  «        }t          | dd¦  «        }d}|r|r	d|› d|› d�}|                     t          dt          d	t          d
|d
z  ¦  «        ¦  «        |¬¦  «        ¦  «         t          | dd¦  «        }|r|                     d|› �¦  «         t          | dd¦  «        }|r|                     d|› �¦  «         t          | dd¦  «        }|r|                     d|› �¦  «         t          | dd¦  «        du r|                     d¦  «         |s|sdS |                     d¦  «         t          ddt          ¦   «         dt          |¦  «        t          |¦  «        ¬¦  «        S # t          t          f$ r Y dS w xY w)už  Map a header-shaped CreditsState (e.g. a dev fixture) to the /usage snapshot.

    Renders the same magnitudes + monthly-grant % window the portal path produces,
    so HERMES_DEV_CREDITS_FIXTURE can exercise /usage without a live account. The
    *_usd strings are mock display values here (not server balance to compute on);
    the % comes from CreditsState.used_fraction (micros math). Fail-open â†’ None.
    NÚused_fractionÚsubscription_limit_usdÚsubscription_usdr{   ú of $r�   rŒ   rŠ   r‹   rŽ   zSubscription credits: $Úpurchased_usdzTop-up credits: $Úremaining_usdzTotal usable: $Úpaid_accessTFr•   u,   (dev fixture â€” HERMES_DEV_CREDITS_FIXTURE)r–   zdev-fixturer—   )r*   r+   r,   r-   r/   r1   )r™   rI   rJ   rK   r€   r�   ro   r   rp   rš   r)   r   r›   rœ   r�   )	Ústater/   r1   ÚufÚcap_usdÚsub_usdr#   rÑ   rÒ   s	            r   r¼   r¼     s@  € ð/Øˆ=Ø�4à,.ˆØˆå�U˜O¨TÑ2Ô2ˆÝ�b�3¥˜,Ñ'Ô'ð 	­D¬M¸"Ñ,=Ô,=ð 	Ý˜eÐ%=¸tÑDÔDˆGÝ˜eÐ%7¸Ñ>Ô>ˆGØˆFØð :˜7ð :Ø9˜WÐ9Ð9¨7Ð9Ð9Ð9�Ø�NŠNÝ"Ø(Ý!$ S­#¨e°R¸%±ZÑ*@Ô*@Ñ!AÔ!AØ!ðñ ô ñô ð õ ˜%Ð!3°TÑ:Ô:ˆØð 	@Ø�NŠNÐ>°WÐ>Ð>Ñ?Ô?Ð?Ý  ¸Ñ=Ô=ˆØð 	@Ø�NŠNÐ>¨}Ð>Ð>Ñ?Ô?Ð?Ý  ¸Ñ=Ô=ˆØð 	>Ø�NŠNÐ<¨]Ð<Ð<Ñ=Ô=Ð=Ý�5˜-¨Ñ.Ô.°%Ð7Ð7Ø�NŠNÐJÑKÔKÐKàð 	˜wð 	Ø�4à�ŠÐEÑFÔFÐFÝ#ØØ Ý‘z”zØ Ý˜'‘N”NÝ˜'‘N”Nð
ñ 
ô 
ð 	
øõ �IÐ&ð ð ð Øˆtˆtðøøøs   ‚F? †E'F? Å/AF? Æ?GÇGc                  óV   — e Zd ZU dZded<   dZded<   dZded	<   dZded
<   dZded<   dS )ÚCreditsViewuO  Surface-agnostic data for the ``/topup`` balance view.

    One portal fetch, one parse â€” consumed identically by the CLI panel, the
    gateway button, and any other money surface. Fail-open: when not logged in
    or the portal is unreachable, ``logged_in`` is False / ``topup_url`` is None
    and callers degrade gracefully.
    r3   r…   r   r0   Úbalance_linesNr"   Úidentity_lineÚ	topup_urlFÚdepleted)	r$   r%   r&   Ú__doc__r'   rÚ   rÛ   rÜ   rÝ   r   r   r   rÙ   rÙ   U  sk   € € € € € € ðð ð €O€O�OØ%'€MÐ'Ð'Ð'Ñ'Ø#'€MÐ'Ð'Ð'Ñ'Ø#€IÐ#Ð#Ð#Ñ#Ø€HÐÐÐÑÐÐr   rÙ   c                ó  — t          d¬¦  «        }	 ddlm}  |d¦  «        pi                      d¦  «        }t	          |t
          ¦  «        r|                     ¦   «         s|S n# t          $ r |cY S w xY w	 ddl}ddl	m
}m} |j                             d	¬
¦  «        5 }|                     |d¬¦  «                             |¬¦  «        }	ddd¦  «         n# 1 swxY w Y   n.# t          $ r! t                                dd¬¦  «         |cY S w xY w|	�t%          |	dd¦  «        s|S t'          |	¦  «        }
g }|
�t)          |
| ¬¦  «        }d„ |D ¦   «         }t%          |	dd¦  «        }t%          |	dd¦  «        }g }|r"|                     t          |¦  «        ¦  «         |r|                     d|› �¦  «         |rdd                     |¦  «        z   nd}t          dt/          |¦  «        | ||	¦  «        t%          |	dd¦  «        du ¬¦  «        S )u‹  Build the /topup balance view: balance block + identity line + top-up URL.

    Reuses the same account fetch + snapshot + URL builder as the /usage credits
    block, so the numbers always match. The balance block is the rendered
    snapshot MINUS its trailing top-up/command-hint lines (the /topup surface
    supplies its own affordance). Fail-open â†’ ``CreditsView(logged_in=False)``.
    F)r…   r   r®   r–   r°   N)r±   r„   r²   r³   Trµ   r·   u2   credits â–¸ /topup portal fetch failed (fail-open)r¸   r…   rg   c                ó®   — g | ]R}|                      ¦   «                              d ¦  «        °)|                      ¦   «                              d¦  «        °P|‘ŒSS )zTop up:z(or run)ÚlstripÚ
startswith)Ú.0Úlines     r   ú
<listcomp>z&build_credits_view.<locals>.<listcomp>’  sd   € ð 
ð 
ð 
àØ—;’;‘=”=×+Ò+¨IÑ6Ô6ð
ð —K’K‘M”M×,Ò,¨YÑ7Ô7ð	
Øð
ð 
ð 
r   ÚemailÚorg_namezorg zTopping up as ú / r”   )r…   rÚ   rÛ   rÜ   rÝ   )rÙ   r½   r¯   r¾   rI   r   r@   r»   r¿   r˜   r±   r„   rÀ   rÁ   rÂ   rÃ   rÄ   rÅ   r™   r©   rx   ro   Újoinr›   )rh   r«   Únot_logged_inr¯   rÇ   rÈ   r±   r„   rÉ   rÊ   ri   rÚ   Úrenderedræ   rç   ÚwhorÛ   s                    r   Úbuild_credits_viewrí   f  sö  € õ  ¨%Ð0Ñ0Ô0€MðØ;Ð;Ð;Ð;Ð;Ð;à&Ð& vÑ.Ô.Ð4°"×9Ò9¸.ÑIÔIˆÝ˜3¥Ñ$Ô$ð 	!¨¯ª©¬ð 	!Ø Ð ð	!øåð ð ð ØÐÐÐðøøøðØ!Ð!Ð!Ð!ð	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð
 Ô×2Ò2¸qÐ2ÑAÔAð 	ÀTØ—k’kÐ">ÈD�kÑQÔQ×XÒXØð Yñ ô ˆGð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	øøõ ð ð ð Ý�ŠÐIÐTXˆÑYÔYÐYØÐÐÐðøøøð €�g g¨{¸EÑBÔB€ØÐå*¨7Ñ3Ô3€Hð  "€MØÐÝ-¨hÀÐJÑJÔJˆð
ð 
à ð
ñ 
ô 
ˆõ �G˜W dÑ+Ô+€EÝ�w 
¨DÑ1Ô1€HØ€CØð Ø�
Š
•3�u‘:”:ÑÔÐØð &Ø�
Š
Ð$˜(Ð$Ð$Ñ%Ô%Ð%Ø<?ÐIÐ%¨¯
ª
°3©¬Ñ7Ð7ÀT€MåØÝ˜MÑ*Ô*Ø#Ø'Ð'¨Ñ0Ô0Ý˜Ð"7¸Ñ>Ô>À%ÐGðñ ô ð sH   ’AA$ Á$A3Á2A3Á7'C" Â,CÃ
C" ÃCÃC" ÃCÃC" Ã"(DÄDÚbase_urlútuple[str, str, str]c                óè   — | pd                      ¦   «                              d¦  «        }|sd}|                     d¦  «        r|dt          d¦  «         …         }|d|v rdndz   }|d	z   |d
z   |dz   fS )a  Resolve the Codex backend endpoints (usage, reset-credits list, consume).

    Mirrors the Codex CLI's PathStyle split (codex-rs backend-client): base URLs
    containing ``/backend-api`` use the ChatGPT ``/wham/...`` paths; everything
    else uses ``/api/codex/...``.
    r<   ú/z%https://chatgpt.com/backend-api/codexz/codexNz/backend-apiz/whamz
/api/codexz/usagez/rate-limit-reset-creditsz!/rate-limit-reset-credits/consume)r@   ÚrstriprM   Úlen)rî   Ú
normalizedÚprefixs      r   Ú_codex_backend_urlsrö   ¬  sž   € ð �.˜b×'Ò'Ñ)Ô)×0Ò0°Ñ5Ô5€JØð =Ø<ˆ
Ø×Ò˜8Ñ$Ô$ð 2ØÐ 0¥3 x¡=¤= .Ð 0Ô1ˆ
Ø n¸
Ð&BÐ&B˜7˜7ÈÑU€Fà�ÑØÐ,Ñ,ØÐ4Ñ4ðð r   c                ó,   — t          | ¦  «        d         S )Nr   )rö   )rî   s    r   Ú_resolve_codex_usage_urlrø   À  s   € Ý˜xÑ(Ô(¨Ô+Ð+r   Úapi_keyútuple[str, str, Optional[str]]c                ó~  — t          |pd¦  «                             ¦   «         }|r&|t          | pd¦  «                             ¦   «         dfS 	 t          d¬¦  «        }d}	 t          ¦   «         }|                     d¦  «        pi }t          |                     dd¦  «        pd¦  «                             ¦   «         pd}n,# t
          $ r t                               dd¬¦  «         Y nw xY w|d	         t          |                     d
d¦  «        pd¦  «                             ¦   «         |fS # t
          $ r t                               dd¬¦  «         Y nw xY wddlm	}  |d¦  «        }| 
                    ¦   «         }	|	€t          d¦  «        ‚|	j        t          |	j        p| pd¦  «                             ¦   «         dfS )aL  Resolve Codex quota credentials from the native runtime path.

    Prefer explicit live-agent credentials, then the legacy singleton OAuth
    state, then the credential pool.  Hermes's native OAuth setup now stores
    device-code logins in the pool, so quota diagnostics must not depend only
    on the older singleton store.
    r<   NT)Úrefresh_if_expiringÚtokensÚ
account_idu5   codex â–¸ /usage account_id read failed (best-effort)r¸   rù   rî   u@   codex â–¸ /usage runtime resolver returned no creds; trying poolr   )Ú	load_poolúopenai-codexz7No available openai-codex credential in credential pool)r   r@   r   r   r¾   r   rÄ   rÅ   Úagent.credential_poolrÿ   ÚselectÚRuntimeErrorÚruntime_api_keyÚruntime_base_url)
rî   rù   Úexplicit_keyÚcredsrþ   Ú
token_datarý   rÿ   rÉ   Úentrys
             r   Ú _resolve_codex_usage_credentialsr
  Ä  sî  € õ �w�} "Ñ%Ô%×+Ò+Ñ-Ô-€LØð ?Ø�S  ¨RÑ0Ô0×6Ò6Ñ8Ô8¸$Ð>Ð>ð"hÝ1ÀdÐKÑKÔKˆØ$(ˆ
ð	aÝ+Ñ-Ô-ˆJØ—^’^ HÑ-Ô-Ð3°ˆFÝ˜VŸZšZ¨°bÑ9Ô9Ð?¸RÑ@Ô@×FÒFÑHÔHÐPÈDˆJˆJøÝð 	að 	að 	aå�LŠLÐPÐ[_ˆLÑ`Ô`Ð`Ð`Ð`ð	aøøøð �YÔ¥ U§Y¢Y¨z¸2Ñ%>Ô%>Ð%DÀ"Ñ!EÔ!E×!KÒ!KÑ!MÔ!MÈzÐYÐYøÝð hð hð hÝ�ŠÐWÐbfˆÑgÔgÐgÐgÐgðhøøøð 0Ð/Ð/Ð/Ð/Ð/àˆ9�^Ñ$Ô$€DØ�KŠK‰MŒM€EØ€}ÝÐTÑUÔUÐUØÔ ¥# eÔ&<Ð&NÀÐ&NÈBÑ"OÔ"O×"UÒ"UÑ"WÔ"WÐY]Ð]Ð]s8   ÁD+ Á AB? Â>D+ Â?&C(Ã%D+ Ã'C(Ã(AD+ Ä+&EÅEc                óº  — t          | |¦  «        \  }}}d|› �dddœ}|r||d<   t          j        d¬¦  «        5 }|                     t	          |¦  «        |¬¦  «        }|                     ¦   «          d d d ¦  «         n# 1 swxY w Y   |                     ¦   «         pi }|                     d	¦  «        pi }	g }
d
D ]†\  }}|	                     |¦  «        pi }|                     d¦  «        }|€Œ4|
                     t          |t          |¦  «        t          |                     d¦  «        ¦  «        ¬¦  «        ¦  «         Œ‡g }|                     d¦  «        pi }|                     d¦  «        }t          |t          t          f¦  «        rHt          |¦  «        dk    r5t          |¦  «        }|dk    rdnd}|                     d|› d|› d�¦  «         |                     d¦  «        pi }|                     d¦  «        r‚|                     d¦  «        }t          |t          t          f¦  «        r'|                     dt          |¦  «        d›�¦  «         n*|                     d¦  «        r|                     d¦  «         t          ddt          ¦   «         t          |                     d ¦  «        ¦  «        t!          |
¦  «        t!          |¦  «        ¬!¦  «        S )"NúBearer úapplication/jsonú	codex-cli©ÚAuthorizationÚAcceptú
User-AgentúChatGPT-Account-Idç      .@r·   ©ÚheadersÚ
rate_limit))Úprimary_windowÚSession)Úsecondary_windowÚWeeklyr   r!   ©r   r   r!   Úrate_limit_reset_creditsÚavailable_countr   r²   Úsr<   z	You have ú resetz& banked - use /usage reset to activateÚcreditsÚhas_creditsÚbalanceúCredits balance: $ú.2fÚ	unlimitedzCredits balance: unlimitedr   Ú	usage_apiÚ	plan_type)r*   r+   r,   r.   r/   r1   )r
  ÚhttpxÚClientr¾   rø   Úraise_for_statusÚjsonro   r   rK   rR   rI   rJ   r)   r   rC   r›   )rî   rù   ÚtokenÚresolved_base_urlrþ   r  ÚclientÚresponseÚpayloadr  r/   Úkeyr   rt   rw   r1   Úreset_creditsÚbankedÚcountÚpluralr!  r#  s                         r   Ú_fetch_codex_account_usager7  þ  s3  € õ ,LÈHÐV]Ñ+^Ô+^Ñ(€EÐ˜jà* 5Ð*Ð*Ø$Ø!ðð €Gð
 ð 3Ø(2ˆÐ$Ñ%Ý	Œ˜dÐ	#Ñ	#Ô	#ð $ vØ—:’:Õ6Ð7HÑIÔIÐSZ�:Ñ[Ô[ˆØ×!Ò!Ñ#Ô#Ð#ð$ð $ð $ñ $ô $ð $ð $ð $ð $ð $ð $øøøð $ð $ð $ð $ð �mŠm‰oŒoÐ# €GØ—’˜\Ñ*Ô*Ð0¨b€JØ(*€GØUð 
ð 
‰
ˆˆUØ—’ Ñ$Ô$Ð*¨ˆØ�zŠz˜.Ñ)Ô)ˆØˆ<ØØ�ŠÝØÝ" 4™[œ[Ý" 6§:¢:¨jÑ#9Ô#9Ñ:Ô:ðñ ô ñ	
ô 	
ð 	
ð 	
ð €GØ—K’KÐ :Ñ;Ô;ÐA¸r€MØ×ÒÐ0Ñ1Ô1€FÝ�&�3¥˜,Ñ'Ô'ð 
­C°©K¬K¸!ªO¨OÝ�F‘”ˆØ š
˜
��¨ˆØ�ŠØS˜ÐSÐS VÐSÐSÐSñ	
ô 	
ð 	
ð �kŠk˜)Ñ$Ô$Ð*¨€GØ‡{‚{�=Ñ!Ô!ð 9Ø—+’+˜iÑ(Ô(ˆÝ�g¥¥U˜|Ñ,Ô,ð 	9Ø�NŠNÐDµ°g±´ÐDÐDÐDÑEÔEÐEÐEØ�[Š[˜Ñ%Ô%ð 	9Ø�NŠNÐ7Ñ8Ô8Ð8ÝØØÝ‘:”:Ý˜gŸkšk¨+Ñ6Ô6Ñ7Ô7Ý�g‘”Ý�g‘”ðñ ô ð s   º9A?Á?BÂBc                  ó\   — e Zd ZU dZded<   ded<   dZded<   dZded<   edd„¦   «         ZdS )ÚCodexResetRedeemResultz>Outcome of a `/usage reset` attempt against the Codex backend.r   ÚstatusÚmessager   rJ   r  Úwindows_resetr   r3   c                ó   — | j         dk    S )NÚreset)r:  r5   s    r   ÚredeemedzCodexResetRedeemResult.redeemed@  s   € àŒ{˜gÒ%Ð%r   Nr8   )	r$   r%   r&   rÞ   r'   r  r<  r9   r?  r   r   r   r9  r9  6  sn   € € € € € € àHÐHà€K€K�Kà€L€L�LØ€OÐÐÐÑØ€MÐÐÐÑàð&ð &ð &ñ „Xð&ð &ð &r   r9  r‹   )rî   rù   Úforcer@  c                óÒ  — ddl }	 t          | |¦  «        \  }}}n!# t          $ r t          dd¬¦  «        cY S w xY wt	          |¦  «        \  }}}	d|› �ddd	œ}
|r||
d
<   	 t          j        d¬¦  «        5 }|                     ||
¬¦  «        }|                     ¦   «          | 	                    ¦   «         pi }|                     d¦  «        pi }|                     d¦  «        }t          |t          t          f¦  «        rt          |¦  «        nd}|dk    rt          dd¬¦  «        cddd¦  «         S |                     d¦  «        pi }d}dD ]g}|                     |¦  «        pi                      d¦  «        }t          |t          t          f¦  «        rt          |pdt          |¦  «        ¦  «        }Œh|duo
|t          k    }|s?|s=|�d|d›d�nd}|dk    rdnd}t          dd|› d|› d |› d!�|¬"¦  «        cddd¦  «         S |                     |	i |
¥d#di¥d$t!          |                     ¦   «         ¦  «        i¬%¦  «        }|                     ¦   «          | 	                    ¦   «         pi }ddd¦  «         n# 1 swxY w Y   n�# t
          j        $ rI}|j        j        }|d&v rt          dd'|› d(�¬¦  «        cY d}~S t          dd)|› d*�¬¦  «        cY d}~S d}~wt          $ r}t          dd+|› �¬¦  «        cY d}~S d}~ww xY wt!          |                     d,d¦  «        pd¦  «                             ¦   «                              ¦   «         }|                     d-¦  «        }t          |t          t          f¦  «        rt          |¦  «        nd}t          d|dz
  ¦  «        }|dk    rdnd}|d.k    rX	 dd/lm}  |¦   «          n,# t          $ r t2                               d0d1¬2¦  «         Y nw xY wt          d.d3|› d4|› d5�||¬6¦  «        S |d7k    rt          d7d8|¬"¦  «        S |d9k    rt          d9d:¬¦  «        S |d;k    rt          d;d<|¬"¦  «        S t          dd=|›�¬¦  «        S )>uÈ  Redeem one banked Codex rate-limit reset credit (`/usage reset`).

    Flow (mirrors the Codex CLI's reset-credits picker, codex-rs
    ``backend-client``):

    1. ``GET .../usage`` â€” read the current windows + banked credit count.
    2. Guard: zero banked credits â†’ refuse. No window fully used and not
       ``force`` â†’ refuse with a warning (a banked reset restores the WHOLE
       5h + weekly allowance; burning it early wastes it). The backend has
       the same protection (``nothing_to_reset`` doesn't consume the
       credit), but failing fast client-side gives a clearer message.
    3. ``POST .../rate-limit-reset-credits/consume`` with a fresh UUID
       idempotency key (``redeem_request_id``). No ``credit_id`` â€” the
       backend picks the next available credit, exactly like the CLI's
       default "Full reset" option.

    Never raises: every failure mode returns a ``CodexResetRedeemResult``
    with a user-renderable message.
    r   NÚunavailablezWNo Codex credentials available. Run `hermes auth` to sign in with your ChatGPT account.)r:  r;  r  r  r  r  r  r  r·   r  r  r  Úno_credits_bankedu>   No banked reset credits on this account â€” nothing to redeem.r  )r  r  r   rŠ   zyour busiest window is only z.0fz% usedz6your current usage could not be confirmed as exhaustedr²   r  r<   Únot_exhaustedu   âš ï¸� Not redeeming: zl. A banked reset restores your FULL 5h + weekly limits, so spending it now would waste most of it. You have r   z5 banked. Use `/usage reset --force` to redeem anyway.)r:  r;  r  úContent-TypeÚredeem_request_id)r  r,  )i‘  i“  z)Codex backend rejected the request (HTTP ur   ). Reset credits require ChatGPT-account (OAuth) auth â€” run `hermes auth` and sign in with your ChatGPT account.zCodex backend error (HTTP u   ) â€” try again shortly.z#Could not reach the Codex backend: Úcoder<  r>  )Ú clear_codex_pool_quota_cooldownsz;Failed to clear Codex pool cooldowns after reset redemptionTr¸   u:   âœ… Reset redeemed â€” your usage limits have been reset. z banked resetz remaining.)r:  r;  r  r<  Únothing_to_resetu\   Backend reports nothing to reset â€” your limits aren't exhausted. The credit was NOT spent.Ú	no_creditz:Backend reports no available reset credit on this account.Úalready_redeemeduI   This redemption was already processed â€” no additional credit was spent.z,Unexpected response from the Codex backend: )Úuuidr
  r»   r9  rö   r)  r*  r¾   r+  r,  rI   rJ   rK   rp   Ú_CODEX_WINDOW_EXHAUSTED_PERCENTÚpostr   Úuuid4ÚHTTPStatusErrorr0  Ústatus_coder@   Úlowerr½   rH  rÄ   rÅ   )rî   rù   r@  rL  r-  r.  rþ   Ú	usage_urlÚ_credits_urlÚconsume_urlr  r/  Ú
usage_respr1  r3  Ú	raw_countr7   r  Ú
worst_usedr2  rw   Ú	exhaustedÚ
usage_noter6  Úconsume_respÚbodyÚexcrG  r<  rv   rH  s                                  r   Úredeem_codex_reset_creditr^  K  sí  € ð2 €K€K€Kð
Ý/OÐPXÐZaÑ/bÔ/bÑ,ˆÐ  * *øÝð 
ð 
ð 
Ý%Ø Ømð
ñ 
ô 
ð 	
ð 	
ð 	
ð
øøøõ
 ,?Ð?PÑ+QÔ+QÑ(€Iˆ|˜[à* 5Ð*Ð*Ø$Ø!ðð €Gð
 ð 3Ø(2ˆÐ$Ñ%ðB
ÝŒ\ $Ð'Ñ'Ô'ð -	-¨6ØŸš I°w˜Ñ?Ô?ˆJØ×'Ò'Ñ)Ô)Ð)Ø —o’oÑ'Ô'Ð-¨2ˆGà#ŸKšKÐ(BÑCÔCÐIÀrˆMØ%×)Ò)Ð*;Ñ<Ô<ˆIÝ*4°YÅÅeÀÑ*MÔ*MÐT�˜I™œ˜ÐSTˆIØ˜AŠ~ˆ~Ý-Ø.Ø\ðñ ô ð-	-ð -	-ð -	-ð -	-ñ -	-ô -	-ð -	-ð -	-ð !Ÿš \Ñ2Ô2Ð8°bˆJØ*.ˆJØ=ð Eð E�Ø"Ÿš sÑ+Ô+Ð1¨r×6Ò6°~ÑFÔF�Ý˜d¥S­% LÑ1Ô1ð EÝ!$ ZÐ%6°3½¸d¹¼Ñ!DÔ!D�JøØ"¨$Ð.Ð`°:ÕA`Ò3`ˆIØð  Uð ð "Ð-ð J°:ÐIÐIÐIÐIÐIàQð ð
 !*¨Q¢ ˜˜°B�Ý-Ø*ðH°ð Hð Hà$-ðHð Hà5;ðHð Hð Hð
 %.ð	ñ 	ô 	ð9-	-ð -	-ð -	-ð -	-ñ -	-ô -	-ð -	-ð -	-ðN "Ÿ;š;ØØG˜7ÐG NÐ4FÐGÐGØ)­3¨t¯zªz©|¬|Ñ+<Ô+<Ð=ð 'ñ ô ˆLð
 ×)Ò)Ñ+Ô+Ð+Ø×$Ò$Ñ&Ô&Ð,¨"ˆDð[-	-ð -	-ð -	-ñ -	-ô -	-ð -	-ð -	-ð -	-ð -	-ð -	-ð -	-øøøð -	-ð -	-ð -	-ð -	-øøõ\ Ô ð 
ð 
ð 
ØŒ|Ô'ˆØ�:ÐÐÝ)Ø$ðOØðOð Oð Oðñ ô ð ð ð ð ð ð õ &Ø ØO°ÐOÐOÐOð
ñ 
ô 
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
øøøøõ ð 
ð 
ð 
Ý%Ø Ø?¸#Ð?Ð?ð
ñ 
ô 
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
øøøøð
øøøõ ˆt�xŠx˜ Ñ#Ô#Ð) rÑ*Ô*×0Ò0Ñ2Ô2×8Ò8Ñ:Ô:€DØ—H’H˜_Ñ-Ô-€MÝ*4°]ÅSÍ%ÀLÑ*QÔ*QÐX•C˜Ñ&Ô&Ð&ÐWX€MÝ�A�y 1‘}Ñ%Ô%€IØ ’N�NˆSˆS¨€FØˆw‚€ð	ØHÐHÐHÐHÐHÐHà,Ð,Ñ.Ô.Ð.Ð.øÝð 	ð 	ð 	Ý�LŠLØMØð ñ ô ð ð ð ð	øøøõ
 &Øð?Øð?ð ?Ø+1ð?ð ?ð ?ð &Ø'ð
ñ 
ô 
ð 	
ð Ð!Ò!Ð!Ý%Ø%ð,ð &ð
ñ 
ô 
ð 	
ð ˆ{ÒÐÝ%ØØPð
ñ 
ô 
ð 	
ð Ð!Ò!Ð!Ý%Ø%Ø_Ø%ð
ñ 
ô 
ð 	
õ
 "ØØG¸tÐGÐGðñ ô ð s™   † ›9¸9Á J Á5B1I;Ä&J Ä3CI;Ç9J ÈA)I;É/J É;I?É?J ÊI?ÊJ ÊLÊ$KÊ:LË KËLËLË'L Ë:LÌ LÎ7O Ï&O1Ï0O1c                 ó  — t          ¦   «         pd                     ¦   «         } | sd S t          | ¦  «        st          ddt	          ¦   «         d¬¦  «        S d| › �dddd	d
œ}t          j        d¬¦  «        5 }|                     d|¬¦  «        }|                     ¦   «          d d d ¦  «         n# 1 swxY w Y   | 	                    ¦   «         pi }g }d}|D ]­\  }}|                     |¦  «        pi }	|	                     d¦  «        }
|
€Œ4t          |
¦  «        dk    rt          |
¦  «        dz  nt          |
¦  «        }|                     t          ||t          |	                     d¦  «        ¦  «        ¬¦  «        ¦  «         Œ®g }|                     d¦  «        pi }|                     d¦  «        r™|                     d¦  «        }|                     d¦  «        }|                     d¦  «        pd}t          |t          t          f¦  «        r<t          |t          t          f¦  «        r |                     d|d›d|d›d|› �¦  «         t          ddt	          ¦   «         t!          |¦  «        t!          |¦  «        ¬¦  «        S ) Nr<   Ú	anthropicÚoauth_usage_apizMAnthropic account limits are only available for OAuth-backed Claude accounts.)r*   r+   r,   r2   r  r  zoauth-2025-04-20zclaude-code/2.1.0)r  r  rE  zanthropic-betar  r  r·   z)https://api.anthropic.com/api/oauth/usager  ))Ú	five_hourzCurrent session)Ú	seven_dayzCurrent week)Úseven_day_opusz	Opus week)Úseven_day_sonnetzSonnet weekÚutilizationr²   rm   Ú	resets_atr  Úextra_usageÚ
is_enabledÚused_creditsÚmonthly_limitÚcurrencyÚUSDzExtra usage: r%  rè   r>   ©r*   r+   r,   r/   r1   )r   r@   r
   r)   r   r)  r*  r¾   r+  r,  rK   ro   r   rR   rI   rJ   r›   )r-  r  r/  r0  r1  r/   Úmappingr2  r   rt   Úutilrw   r1   Úextrarj  rk  rl  s                    r   Ú_fetch_anthropic_account_usagerr  ï  sö  € Ý$Ñ&Ô&Ð,¨"×3Ò3Ñ5Ô5€EØð ØˆtÝ˜5Ñ!Ô!ð 
Ý#Ø Ø$Ý‘z”zØnð	
ñ 
ô 
ð 	
ð + 5Ð*Ð*Ø$Ø*Ø,Ø)ðð €Gõ 
Œ˜dÐ	#Ñ	#Ô	#ð $ vØ—:’:ÐIÐSZ�:Ñ[Ô[ˆØ×!Ò!Ñ#Ô#Ð#ð$ð $ð $ñ $ô $ð $ð $ð $ð $ð $ð $øøøð $ð $ð $ð $ð �mŠm‰oŒoÐ# €GØ(*€Gð€Gð ð 
ð 
‰
ˆˆUØ—’˜SÑ!Ô!Ð' RˆØ�zŠz˜-Ñ(Ô(ˆØˆ<ØÝ$)¨$¡K¤K°1Ò$4Ð$4�u�T‰{Œ{˜SÑ Ð ½%À¹+¼+ˆØ�ŠÝØØ!Ý" 6§:¢:¨kÑ#:Ô#:Ñ;Ô;ðñ ô ñ	
ô 	
ð 	
ð 	
ð €GØ�KŠK˜Ñ&Ô&Ð,¨"€EØ‡y‚y�ÑÔð Ø—y’y Ñ0Ô0ˆØŸ	š	 /Ñ2Ô2ˆØ—9’9˜ZÑ(Ô(Ð1¨EˆÝ�l¥S­% LÑ1Ô1ð 	µjÀÕQTÕV[ÐP\Ñ6]Ô6]ð 	Ø�NŠNØS ÐSÐSÐS°]ÐSÐSÐSÈÐSÐSñô ð õ  ØØ Ý‘:”:Ý�g‘”Ý�g‘”ðñ ô ð s   Á5,B-Â-B1Â4B1c           	     ó	  — t          d| |¬¦  «        }t          |                     dd¦  «        pd¦  «                             ¦   «         }|sd S t          |                     dd¦  «        pd¦  «                             d¦  «        }|› d�}|› d�}d	|› �d
dœ}t          j        d¬¦  «        5 }|                     ||¬¦  «        }	|	                     ¦   «          |	                     ¦   «         pi                      d¦  «        pi }
	 |                     ||¬¦  «        }|                     ¦   «          |                     ¦   «         pi                      d¦  «        pi }n# t          $ r i }Y nw xY wd d d ¦  «         n# 1 swxY w Y   t          |
                     d¦  «        pd¦  «        }t          |
                     d¦  «        pd¦  «        }dt          d||z
  ¦  «        d›�g}g }|                     d¦  «        }|                     d¦  «        }t          |                     d¦  «        pd¦  «                             ¦   «         }|                     d¦  «        }t          |t          t          f¦  «        ràt          |¦  «        dk    rÍt          |t          t          f¦  «        r±dt          |¦  «        cxk    rt          |¦  «        k    rŠn n‡t          |¦  «        }t          |¦  «        }||z
  |z  dz  }d|d›d|d›d�g}|r|                     d|› �¦  «         |                     t          d|d                      |¦  «        ¬!¦  «        ¦  «         t          |t          t          f¦  «        rßd"t          |¦  «        d›d#�g}|                     d$¦  «        d%f|                     d&¦  «        d'f|                     d(¦  «        d)ffD ]]\  }}t          |t          t          f¦  «        r<t          |¦  «        dk    r)|                     dt          |¦  «        d›d*|› �¦  «         Œ^|                     d                      |¦  «        ¦  «         t#          dd+t%          ¦   «         t'          |¦  «        t'          |¦  «        ¬,¦  «        S )-NÚ
openrouter)Ú	requestedÚexplicit_base_urlÚexplicit_api_keyrù   r<   rî   rñ   z/creditsz/keyr  r  )r  r  rª   r·   r  ÚdataÚtotal_creditsrŠ   Útotal_usager$  r%  ÚlimitÚlimit_remainingÚlimit_resetÚusager   rm   r{   rÐ   z
 remainingzresets zAPI key quotarn   rŽ   zAPI key usage: $z totalÚusage_dailyÚtodayÚusage_weeklyz	this weekÚusage_monthlyz
this monthr>   Úcredits_apirn  )r   r   r¾   r@   rò   r)  r*  r+  r,  r»   rK   rp   rI   rJ   ro   r   ré   r)   r   r›   )rî   rù   Úruntimer-  rô   Úcredits_urlÚkey_urlr  r/  Úcredits_respr!  Úkey_respÚkey_datary  rz  r1   r/   r{  r|  r}  r~  Úlimit_valueÚremaining_valuer   Údetail_partsÚusage_partsr:   r   s                               r   Ú_fetch_openrouter_account_usagerŽ  ,  sþ  € Ý&ØØ"Ø ðñ ô €Gõ
 �—’˜I rÑ*Ô*Ð0¨bÑ1Ô1×7Ò7Ñ9Ô9€EØð ØˆtÝ�W—[’[ ¨RÑ0Ô0Ð6°BÑ7Ô7×>Ò>¸sÑCÔC€JØÐ)Ð)Ð)€KØÐ!Ð!Ð!€Gà* 5Ð*Ð*Ø$ðð €Gõ 
Œ˜dÐ	#Ñ	#Ô	#ð 	 vØ—z’z +°w�zÑ?Ô?ˆØ×%Ò%Ñ'Ô'Ð'Ø×$Ò$Ñ&Ô&Ð,¨"×1Ò1°&Ñ9Ô9Ð?¸Rˆð	Ø—z’z '°7�zÑ;Ô;ˆHØ×%Ò%Ñ'Ô'Ð'Ø Ÿš™œÐ-¨2×2Ò2°6Ñ:Ô:Ð@¸bˆHˆHøÝð 	ð 	ð 	ØˆHˆHˆHð	øøøð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	õ ˜'Ÿ+š+ oÑ6Ô6Ð=¸#Ñ>Ô>€MÝ˜Ÿš MÑ2Ô2Ð9°cÑ:Ô:€KØO¥C¨¨]¸[Ñ-HÑ$IÔ$IÐOÐOÐOÐP€GØ(*€GØ�LŠL˜Ñ!Ô!€EØ—l’lÐ#4Ñ5Ô5€OÝ�h—l’l =Ñ1Ô1Ð7°RÑ8Ô8×>Ò>Ñ@Ô@€KØ�LŠL˜Ñ!Ô!€Eå�5�3¥˜,Ñ'Ô'ð
å�%‰LŒL˜1ÒÐÝ�­­e¨Ñ5Ô5ð à•�Ñ'Ô'Ð7Ð7Ò7Ð7­5°©<¬<Ò7Ð7Ð7Ð7Ð7å˜E‘l”lˆÝ Ñ0Ô0ˆØ$ Ñ6¸+ÑEÈÑLˆØQ˜OÐQÐQÐQ°kÐQÐQÐQÐQÐRˆØð 	9Ø×ÒÐ 7¨+Ð 7Ð 7Ñ8Ô8Ð8Ø�ŠÝØ%Ø)Ø—|’| LÑ1Ô1ðñ ô ñ	
ô 	
ð 	
õ �%�#�u˜Ñ&Ô&ð 	2ØB­%°©,¬,ÐBÐBÐBÐBÐCˆà�\Š\˜-Ñ(Ô(¨'Ð2Ø�\Š\˜.Ñ)Ô)¨;Ð7Ø�\Š\˜/Ñ*Ô*¨LÐ9ð
ð 	Cð 	C‰LˆE�5õ
 ˜%¥#¥u Ñ.Ô.ð Cµ5¸±<´<À!Ò3CÐ3CØ×"Ò"Ð#A¥u¨U¡|¤|Ð#AÐ#AÐ#A¸%Ð#AÐ#AÑBÔBÐBøØ�Š�w—|’| KÑ0Ô0Ñ1Ô1Ð1ÝØØÝ‘:”:Ý�g‘”Ý�g‘”ðñ ô ð s8   Â-AE:ÄAEÅE:ÅE+Å(E:Å*E+Å+E:Å:E>ÆE>©rî   rù   r*   c               ó$  — t          | pd¦  «                             ¦   «                              ¦   «         }|dv rd S 	 |dk    rt          ||¬¦  «        S |dk    rt	          ¦   «         S |dk    rt          ||¦  «        S n# t          $ r Y d S w xY wd S )Nr<   >   r<   ÚautoÚcustomr   r�  r`  rt  )r   r@   rR  r7  rr  rŽ  r»   )r*   rî   rù   rô   s       r   Úfetch_account_usager“  t  s¿   € õ �X�^ Ñ$Ô$×*Ò*Ñ,Ô,×2Ò2Ñ4Ô4€JØÐ+Ð+Ð+ØˆtðØ˜Ò'Ð'Ý-°xÈÐQÑQÔQÐQØ˜Ò$Ð$Ý1Ñ3Ô3Ð3Ø˜Ò%Ð%Ý2°8¸WÑEÔEÐEð &øåð ð ð Øˆtˆtðøøøàˆ4s   ½A? ÁA? Á(A? Á?
BÂB)r   r   )r:   r"   r   r"   )r:   r   r   r    )rQ   r    r   r   )ri   rj   rh   r3   r   rk   )ry   rK   r   r   )r}   r   r   r~   )r   rj   )rh   r3   r«   rK   r   rk   )rh   r3   r«   rK   r   rÙ   )rî   r   r   rï   )rî   r   r   r   )rî   r"   rù   r"   r   rú   )NN)rî   r"   rù   r"   r   rj   )rî   r"   rù   r"   r@  r3   r   r9  )r*   r"   rî   r"   rù   r"   r   rj   )2Ú
__future__r   Úloggingr€   Údataclassesr   r   r   Útypingr   r   r	   r)  Úagent.anthropic_adapterr
   r   r½   r   r   r   Úhermes_cli.runtime_providerr   r   Ú	getLoggerr$   rÄ   r   r   r)   rC   rR   rf   rx   r|   r‚   r©   rË   r¼   rÙ   rí   rö   rø   r
  r7  r9  rM  r^  rr  rŽ  r“  r   r   r   ú<module>r›     s  ðØ "Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø !Ð !Ð !Ð !Ð !Ð !Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ø /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /à €€€à LÐ LÐ LÐ LÐ LÐ LÐ LÐ LØ \Ð \Ð \Ð \Ð \Ð \Ð \Ð \Ð \Ð \Ø @Ð @Ð @Ð @Ð @Ð @àð !Ø Ð Ð Ð Ð Ð à	ˆÔ	˜8Ñ	$Ô	$€ð&ð &ð &ð &ð €�$ÐÑÔð!ð !ð !ð !ð !ñ !ô !ñ Ôð!ð €�$ÐÑÔðRð Rð Rð Rð Rñ Rô Rñ ÔðRð?ð ?ð ?ð ?ðð ð ð ð&?ð ?ð ?ð ?ð( ^cð ð ð ð ð ð ð8ð ð ð ðXð Xð Xð Xð]ð ]ð ]ð ]ð@ ,1À4ð /ð /ð /ð /ð /ð /ðd7ð 7ð 7ð 7ðt €�$ÐÑÔðð ð ð ð ñ ô ñ Ôðð  ,1À4ð Cð Cð Cð Cð Cð CðLð ð ð ð(,ð ,ð ,ð ,ð7^ð 7^ð 7^ð 7^ðv #Ø!ð5ð 5ð 5ð 5ð 5ðp €�$ÐÑÔð&ð &ð &ð &ð &ñ &ô &ñ Ôð&ð" #(Ð ð
 #Ø!Øð	að að að að að aðH:ð :ð :ð :ðzEð Eð Eð EðV #Ø!ð	ð ð ð ð ð ð ð r   