+
    iHàj¼R ã                  óš  a € 0 t $ R t^ RIHt ^ RIHt ^ RIHtHt ^ RI	H
t
 ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHtHtHt ^ RIHtHtHt ^ RIHt ^ R	IHtHtHtHtH t H!t!H"t"H#t# ^ R
I$H%t% ^ RI&H't' ^ RI(H)t*H+t+ ^ RI,H-t- ^ RI.H/t/ ^ RI0H1t1H2t2H3t3 ^ RI4H5t5H6t6H7t7 ^ RI8H9t: ^ RI;H<t< ^ RI8H=t=H>t>H?t?H@t@HAtAHBtBHCtCHDtDHEtEHFtFHGtGHHtHHItIHJtJHKtKHLtLHMtMHNtN ]Pž                  ! ]P4      tQR R ltRR R ltSRtTRtURtV]W! 0 RÁm4      tXRtYRÂtZRt[Rt\Rt]]] R2t^Rt_R t`R!taR"tb]_]`]a]b0tcRÃtdRÄteRÄtf^<tgR#thR$tiR%tjR&tk]W! 0 RÅm4      tlRÆtmR(RR)RR*RR+RR,RR-R/tnR.]oR/&   / ]nCR(]T/CtpR.]oR0&   R1 R2 ltq] ! R3 R44      4       trR5 R6 ltsR7 R8 lttR9 R: ltuR; R< ltvR= R> ltwR?R@R'R/RA RB lltxRC RD ltyRE RF ltzR?R@/RG RH llt{RI RJ lt|RK RL lt}RÇRM RN llt~RO RP ltRQ RR lt€RS RT lt�RÈRU RV llt‚RÇRW RX lltƒRY RZ lt„R[ R\ lt…R] R^ lt†R_ R` lt‡Ra Rb ltˆRc Rd lt‰ReR/Rf Rg lltŠRh Ri lt‹^tŒRj Rk lt�Rl Rm ltŽRn Ro lt�Rp Rq lt�Rr Rs lt‘Rt Ru lt’RvRRwR/Rx Ry llt“RzRRvRRwR/R{ R| llt”R}RÉR~RÊ/t•R]oR€&   ]W! R�R‚0]•m4      t–RËt—Rƒt˜R}R„R~R…/t™R�R†R‚R‡R}R‡R~R‡/tš ! Rˆ R‰]›4      tœ ! RŠ R‹]]4      t�RŒ R� ltžRŽ^ R�^R�^R†^R‘^/tŸR’ R“ lt R” R• lt¡ ! R– R—4      t¢R˜ R™ lt£Rš R› lt¤]¥! 4       t¦Rœ]oR�&   Rž RŸ lt§R  R¡ lt¨R¢ R£ lt©R¤ R¥ ltªR¦ R§ lt«R¨ R© lt¬Rª R« lt­R¬ R­ lt®]¥! 4       t¯Rœ]oR®&   R¯ R° lt°R± R² lt±R³]GR´]H/t²Rµ R¶ lt³R· R¸ lt´R¹Rº/R» R¼ lltµR½ R¾ lt¶R¿ RÀ lt·R# )Ìz<Persistent multi-credential pool for same-provider failover.)Úannotations)ÚCredentialPoolAdminMixin)Ú CredentialPoolModelCooldownMixinÚmodel_cooldown_until)Ú_parse_absolute_timestampN)Ú	dataclassÚfieldsÚreplace)ÚdatetimeÚtimezoneÚUTC)ÚPath)ÚAnyÚCallableÚDictÚIterableÚListÚOptionalÚSetÚTuple)ÚOPENROUTER_BASE_URL)Úload_env)Ú
get_secretÚget_secret_str)Úreset_delay_from_message)Úplugin_refresh_hook)Úapply_plugin_refresh_resultÚplugin_row_is_expiringÚrecover_failed_plugin_refresh)Úfingerprint_secret_valueÚis_borrowed_credential_sourceÚ$sanitize_borrowed_credential_payload)Úowned_profile_reads_root_state)Ú'CODEX_ACCESS_TOKEN_REFRESH_SKEW_SECONDSÚPROVIDER_REGISTRYÚ!SINGLE_USE_REFRESH_POOL_PROVIDERSÚ_auth_store_lockÚ_codex_access_token_is_expiringÚ_decode_jwt_claimsÚ_global_auth_file_pathÚ_load_auth_storeÚ_load_provider_stateÚ _load_provider_state_with_sourceÚ_resolve_kimi_base_urlÚ_resolve_zai_base_urlÚ
_same_pathÚ_save_auth_storeÚ_save_provider_stateÚ_store_provider_stateÚread_credential_poolÚwrite_credential_poolc               ó   € V ^8„  d   QhRR/# )é   ÚreturnúOptional[dict]© )Úformats   "Ú:/home/ubuntu/.hermes/hermes-agent/agent/credential_pool.pyÚ__annotate__r<   :   s   € ÷ 	ñ 	˜>ñ 	ó    c                 ó~   €  ^ RI Hp  ^ RIHp VP	                  4       ;'       g    V ! 4       #   \
         d     R# i ; i)zäRead-only config (``load_config_readonly`` skips the per-row deepcopy), None on any error.
Inside ``frozen_runtime_config`` it is the session's frozen config: a key rotated in config.yaml
must never seed a frozen session's pool.)Úload_config_readonly)Ú_FROZEN_RUNTIME_CONFIGN)Úhermes_cli.configr?   Úhermes_cli.runtime_providerr@   ÚgetÚ	Exception)r?   r@   s     r;   Ú_load_config_saferE   :   s:   € ðÝ:ÝFØ%×)Ñ)Ó+×EÐEÑ/CÓ/EÐEøÜô Úðús   ‚"- ¥- ­<»<c               ó   € V ^8„  d   QhRR/# )r6   r7   zCallable[[str, str], bool]r9   )r:   s   "r;   r<   r<   F   s   € ÷ $ñ $Ð"<ñ $r=   c                 ó<   €  ^ RI Hp  V #   \         d    R u # i ; i)zO``hermes_cli.auth.is_source_suppressed`` (late-bound), or an always-False stub.©Úis_source_suppressedc                ó   € R # )Fr9   )Ú_pÚ_ss   &&r;   Ú<lambda>Ú*_is_source_suppressed_fn.<locals>.<lambda>L   s   € ™er=   )Úhermes_cli.authrI   ÚImportErrorrH   s    r;   Ú_is_source_suppressed_fnrQ   F   s%   € ð$Ý8Ø#Ð#øÜô $Ù#Ò#ð$ús   ‚
 ŠšÚokÚ	exhaustedÚdeadÚcredential_persist_failedÚoauthÚapi_keyÚmanualz:device_codeÚ
fill_firstÚround_robinÚrandomÚ
least_usedÚbillingÚbilling_unverifiedg      N@zcustom:Úfailure_reasonÚlast_statusÚlast_status_atÚlast_error_codeÚlast_error_reasonÚlast_error_messageÚlast_error_reset_atúdict[str, Any]Ú_CLEAR_STATUSÚ_MARK_OKc               ó(   € V ^8„  d   QhRRRRRRRR/# )r6   ÚproviderÚstrÚtokenr   Ú	auth_typer7   r9   )r:   s   "r;   r<   r<   É   s(   € ÷ /ñ /¨ð /°Cð /ÀCð /ÈCñ /r=   c                ó¨   € V R8X  d4   \        V\        4      '       d   VP                  R4      '       d   \        # \        T;'       g    \        4      # )zHInfer pool auth metadata for token formats with one unambiguous meaning.Ú	anthropicz
sk-ant-oat)Ú
isinstancerk   Ú
startswithÚAUTH_TYPE_OAUTHÚAUTH_TYPE_API_KEY)rj   rl   rm   s   &&&r;   Ú_normalize_pool_auth_typert   É   s@   € à�;Ô¤:¨e´S×#9Ò#9¸e×>NÑ>NÈ|×>\Ò>\ÜÐÜˆy×-Ð-Ô-Ó.Ð.r=   c                  óº  € ] tR t^Ðt$ R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   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]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&   ^ tR]R&   R
tR]R&   R
tR ]R!&   R" tR# R$ lt]R% R& l4       tR' R( lt]R) R* l4       t]R+ R, l4       tR-tR
# ).ÚPooledCredentialrk   rj   ÚidÚlabelrm   ÚintÚpriorityÚsourceÚaccess_tokenNúOptional[str]Úrefresh_tokenr`   úOptional[float]ra   úOptional[int]rb   rc   rd   re   Ústatus_cleared_atÚbase_urlÚ
expires_atÚexpires_at_msÚlast_refreshÚinference_base_urlÚ	agent_keyÚagent_key_expires_atÚrequest_countzOptional[dict[str, float]]Úmodel_cooldownsrf   Úextrac                	ó�   € V P                   f   / V n         \        V P                  V P                  V P                  4      V n        R # ©N)r‹   rt   rj   r|   rm   ©Úselfs   &r;   Ú__post_init__ÚPooledCredential.__post_init__ñ   s4   € Ø�:‰:ÒØˆDŒJÜ2°4·=±=À$×BSÑBSÐUY×UcÑUcÓdˆŽr=   c               ó   € V ^8„  d   QhRR/# )r6   Únamerk   r9   )r:   s   "r;   r<   ÚPooledCredential.__annotate__ö   s   € ÷ Zñ Z ñ Zr=   c                	ó˜   € V\         9   d   V P                  P                  V4      # \        R \	        V 4      P
                   RV: 24      h)Ú'z' object has no attribute )Ú_EXTRA_KEYSr‹   rC   ÚAttributeErrorÚtypeÚ__name__)r�   r“   s   &&r;   Ú__getattr__ÚPooledCredential.__getattr__ö   sB   € Ø”;ÔØ—:‘:—>‘> $Ó'Ð'Ü˜q¤ d£×!4Ñ!4Ð 5Ð5OÐPTÉxÐXÓYÐYr=   c               ó$   € V ^8„  d   QhRRRRRR/# )r6   rj   rk   Úpayloadrf   r7   rv   r9   )r:   s   "r;   r<   r”   ü   s"   € ÷ .ñ . ð .¨~ð .ÐBRñ .r=   c                	ó2  € \        V 4       Uu0 uF!  q3P                  R 8w  g   K  VP                  kK#  	  ppV Uu/ uF  qUV9   g   K  WRP                  V4      bK  	  pp\        VP                  R4      \        4      '       d   \        VR,          4      VR&   VP                  4        UUu/ uF  w  rWWT9  g   K  VR 8w  g   K  Vf   K  WWbK   	  uppVR&   VP                  R\        P                  ! 4       P                  R,          4       VP                  RVP                  RV4      4       VP                  R\        4       VP                  R^ 4       VP                  R\        4       VP                  R	R
4       V ! RR V/VB # u upi u upi u uppi )rj   ra   r‹   rw   ºNé   Nrx   r{   rm   rz   r|   Ú r9   )r   r“   rC   rp   rk   r   ÚitemsÚ
setdefaultÚuuidÚuuid4Úhexrs   ÚSOURCE_MANUAL)Úclsrj   rž   ÚfÚfield_namesÚkÚdataÚvs   &&&     r;   Ú	from_dictÚPooledCredential.from_dictû   sM  € ä'-¨c¤{ÓK¡{ !·f±fÀ
Ñ6J”v�q—v”v¡{ˆÐKÙ+6ÓG©; a¸w¹,Ô!�—;‘;˜q“>Ò!©;ˆÐGä�d—h‘hÐ/Ó0´#×6Ò6Ü%>¸tÐDTÕ?UÓ%VˆDÐ!Ñ"ð %Ÿ]™]œ_ô
Ù,‘T�Q°Ñ0DŒDÈÈjÉŒDÐ]^ŒDˆAŠD™_ò
ˆˆW‰ð 	�‰˜œdŸjšj›l×.Ñ.¨rÕ2Ô3Ø�‰˜ §¡¨X°xÓ!@ÔAØ�‰˜Ô%6Ô7Ø�‰˜
 AÔ&Ø�‰˜¤-Ô0Ø�‰˜¨Ô+ÙÑ-˜HÐ-¨Ñ-Ð-ùò' LùÚGùó
s-   ŽF	¥F	»FÁFÂ,
FÂ;FÃFÃ
Fc               ó   € V ^8„  d   QhRR/# )r6   r7   rf   r9   )r:   s   "r;   r<   r”     s   € ÷ Kñ K˜ñ Kr=   c                	óP  € / p\        V 4       FT  pVP                  R9   d   K  \        WP                  4      pVf   VP                  \        9   g   KF  W1VP                  &   KV  	  V P                  P                  4        F  w  rEVf   K  WQV&   K  	  \        WP                  4      # )rj   >   r‹   rj   )r   r“   Úgetattrrg   r‹   r£   r!   rj   )r�   ÚresultÚ	field_defÚvaluer¬   r®   s   &     r;   Úto_dictÚPooledCredential.to_dict  sˆ   € Ø!#ˆÜ žˆIØ�~‰~Ð!6Ô6ÙÜ˜D§.¡.Ó1ˆEØÒ  I§N¡N´mÖ$CØ).�y—~‘~Ó&ñ &ð —J‘J×$Ñ$Ö&‰DˆAØŒ}Ø�q“	ñ 'ô 4°F¿M¹MÓJÐJr=   c               ó   € V ^8„  d   QhRR/# )r6   r7   rk   r9   )r:   s   "r;   r<   r”      s   € ÷ ,ñ , ñ ,r=   c           	     	ó°  € V P                   R 8X  d¨   V P                  V P                  3V P                  V P                  33 Fq  w  r\        V\        4      '       g   K  VP                  4       '       g   K5  \        P                  ! V\        V RR4      VR7      '       g   Ka  VP                  4       u # 	  R# \        V P                  ;'       g    R4      # )ÚnousÚscopeN)r¼   rƒ   r¢   )rj   r‡   rˆ   r|   rƒ   rp   rk   ÚstripÚauth_modÚ_nous_invoke_jwt_is_usabler³   )r�   rl   rƒ   s   &  r;   Úruntime_api_keyÚ PooledCredential.runtime_api_key  s¬   € à�=‰=˜FÔ"ð —‘ ×!:Ñ!:Ð;Ø×"Ñ" D§O¡OÐ4ó&Ñ!�ô
 ˜u¤c×*Ô*ØŸ™ŸœÜ ×;Ò;Ø¤W¨T°7¸DÓ%AÈj÷õ ð !Ÿ;™;›=Ò(ñ&ñ Ü�4×$Ñ$×*Ð*¨Ó+Ð+r=   c               ó   € V ^8„  d   QhRR/# )r6   r7   r}   r9   )r:   s   "r;   r<   r”   4  s   € ÷ ñ  -ñ r=   c                	ó  € V P                   R 8X  d!   V P                  ;'       g    V P                  # V P                   R8X  d>   \        RR4      P	                  4       P                  R4      ;'       g    V P                  # V P                  # )r»   úopenai-codexÚHERMES_CODEX_BASE_URLr¢   Ú/)rj   r†   r‚   r   r½   ÚrstriprŽ   s   &r;   Úruntime_base_urlÚ!PooledCredential.runtime_base_url3  so   € à�=‰=˜FÔ"Ø×*Ñ*×;Ð;¨d¯m©mÐ;Ø�=‰=˜NÔ*ô "Ð"9¸2Ó>×DÑDÓF×MÑMÈcÓR×cÐcÐVZ×VcÑVcÐcØ�}‰}Ðr=   )rm   r‹   ) rš   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__annotations__r~   r`   ra   rb   rc   rd   re   r�   r‚   rƒ   r„   r…   r†   r‡   rˆ   r‰   rŠ   r‹   r�   r›   Úclassmethodr¯   r·   ÚpropertyrÀ   rÈ   Ú__static_attributes__r9   r=   r;   rv   rv   Ð   s3  ‡ àƒMØƒGØƒJØƒNØƒMØƒKØÓØ#'€M�=Ó'Ø!%€K�Ó%Ø&*€N�OÓ*Ø%)€O�]Ó)Ø'+Ð�}Ó+Ø(,Ð˜Ó,Ø+/Ð˜Ó/ð *.Ð�Ó-Ø"€HˆmÓ"Ø $€J�Ó$Ø#'€M�=Ó'Ø"&€L�-Ó&Ø(,Ð˜Ó,Ø#€Iˆ}Ó#Ø*.Ð˜-Ó.Ø€M�3Óð 37€OÐ/Ó6Ø €Eˆ>Ó òeõ
Zð
 ô.ó ð.õ,Kð ô,ó ð,ð& ôó ôr=   rv   c               ó$   € V ^8„  d   QhRRRRRR/# )r6   rl   rk   Úfallbackr7   r9   )r:   s   "r;   r<   r<   ?  s!   € ÷ ñ ˜Cð ¨3ð °3ñ r=   c                óÐ   € \        V 4      pR FT  pVP                  V4      p\        V\        4      '       g   K,  VP	                  4       '       g   KD  VP	                  4       u # 	  V# )Úemail)rÔ   Úpreferred_usernameÚupn)r(   rC   rp   rk   r½   )rl   rÒ   ÚclaimsÚkeyr¶   s   &&   r;   Úlabel_from_tokenrÙ   ?  sM   € Ü Ó&€FÛ5ˆØ—
‘
˜3“ˆÜ�eœS×!Ô! e§k¡k§m¤mØ—;‘;“=Ò ñ 6ð €Or=   c               ó    € V ^8„  d   QhRRRR/# )r6   r|   r   r7   zOptional[tuple[str, str]]r9   )r:   s   "r;   r<   r<   H  s   € ÷ /ñ /¨Cð /Ð4Mñ /r=   c                ó  € \        V 4      p\        V\        4      '       d   VP                  R4      MRp\        V\        4      '       d   VP                  R4      MRp\        V\        4      '       d   VP                  R4      MRp\        V\        4      '       dC   VP                  4       '       d-   \        V\        4      '       d   VP                  4       '       g   R# VP                  4       VP                  4       3# )aŠ  ``(chatgpt_account_id, sub)`` of a Codex access token, or None when either claim is missing.

Decoded without signature verification: this only decides whether two credentials Hermes
already holds belong to the same principal, never whether a token is valid. Both claims are
required because members of one ChatGPT workspace share ``chatgpt_account_id`` yet have their
own subjects and quotas.
zhttps://api.openai.com/authNÚchatgpt_account_idÚsub)r(   rp   ÚdictrC   rk   r½   )r|   r×   Úauth_claimsÚ
account_idÚsubjects   &    r;   Ú_codex_principal_identityrâ   H  s¼   € ô   Ó-€FÜ?IÈ&ÔRV×?WÒ?W�&—*‘*Ð:Ô;Ð]a€KÜ:DÀ[ÔRV×:WÒ:W�—‘Ð!5Ô6Ð]a€JÜ#-¨f´d×#;Ò#;ˆf�j‰j˜ÔÀ€GÜ�z¤3×'Ò'¨J×,<Ñ,<×,>Ò,>Ä:ÈgÔWZ×C[ÒC[Ð`g×`mÑ`m×`oÒ`oÙØ×ÑÓ˜wŸ}™}›Ð.Ð.r=   c               ó$   € V ^8„  d   QhRRRRRR/# )r6   Úentryrv   Úsingleton_tokensrf   r7   Úboolr9   )r:   s   "r;   r<   r<   Y  s(   € ÷ |ñ |Ð)9ð |È^ð |Ð`dñ |r=   c                óÒ   € V P                   R8X  d   R# V P                   \        8w  d   R# \        V P                  4      pVRJ;'       d    V\        VP	                  R4      4      8H  # )uÓ  Whether a Codex pool entry may adopt the auth.json singleton's token pair.

``device_code`` IS the singleton. ``manual:device_code`` is ambiguous: a legacy alias of the
singleton (same account, must follow its rotations) or an independent account added with
``hermes auth add openai-codex`` (must never be overwritten â€” adopting turned two logins into
one account, both hitting the same usage limit). Same principal proves the alias; unknown
identity fails closed.
Údevice_codeTFNr|   )r{   ÚSOURCE_MANUAL_DEVICE_CODErâ   r|   rC   )rä   rå   Úentry_identitys   && r;   Ú_codex_entry_tracks_singletonrë   Y  s^   € ð ‡|�|�}Ô$ÙØ‡|�|Ô0Ô0ÙÜ.¨u×/AÑ/AÓB€NØ Ð%×{Ð{¨.Ô<UÐVf×VjÑVjÐkyÓVzÓ<{Ñ*{Ð{r=   c               ó    € V ^8„  d   QhRRRR/# )r6   Úentriesúlist[PooledCredential]r7   ry   r9   )r:   s   "r;   r<   r<   j  s   € ÷ Fñ FÐ2ð F°sñ Fr=   c                ó8   € \        R  V  4       RR7      ^,           # )c              3  ó8   "  € T F  qP                   x € K  	  R # 5ir�   ©rz   ©Ú.0rä   s   & r;   Ú	<genexpr>Ú!_next_priority.<locals>.<genexpr>k  s   é € Ð4©G 5—–«Gùs   ‚)Údefaultéÿÿÿÿ)Úmax)rí   s   &r;   Ú_next_priorityrù   j  s   € ÜÑ4©GÓ4¸bÔAÀAÕEÐEr=   c               ó    € V ^8„  d   QhRRRR/# )r6   r{   rk   r7   ræ   r9   )r:   s   "r;   r<   r<   n  s   € ÷ Uñ U˜cð U dñ Ur=   c                ó¤   € T ;'       g    R P                  4       P                  4       pV\        8H  ;'       g    VP                  \         R24      # )r¢   Ú:)r½   Úlowerr¨   rq   )r{   Ú
normalizeds   & r;   Ú_is_manual_sourcerÿ   n  sE   € Ø—,�,˜B×%Ñ%Ó'×-Ñ-Ó/€JØœÑ&×TÐT¨*×*?Ñ*?Ä=À/ÐQRÐ@SÓ*TÐTr=   Úsole_credentialFc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r6   Ú
error_coder€   r   ræ   r_   r}   r7   ry   r9   )r:   s   "r;   r<   r<   s  s2   € ÷ ñ Øðð ðð "ð	ð
 	ñr=   c               óö   € V R8X  d   \         # V R8X  d   \        M\        pV\        8X  d   V R8w  d   \	        V\
        4      # V R8H  ;'       g
    V\        8H  pV'       d   V'       g   \	        V\
        4      # V# )a¶  Return cooldown seconds based on the HTTP status that caused exhaustion.

*sole_credential*: the pool has nothing to rotate to, so transient
throttles (429 and the catch-all default covering 403/5xx/unknown) are
capped to a brief cooldown; 401 keeps its own already-short TTL.

*failure_reason* is the classifier verdict: an OpenRouter ``key limit
exceeded`` and an xAI spending block both arrive as 403 but are billing,
and a 60s retry on a spent account just re-fails. Billing keeps the full
bench regardless of status; 402 is billing by definition.
Unverified billing (#82154) gets the short cooldown regardless of pool
size (the credential may be healthy), unless the status is a true 402.
é‘  i­  i’  )ÚEXHAUSTED_TTL_401_SECONDSÚEXHAUSTED_TTL_429_SECONDSÚEXHAUSTED_TTL_DEFAULT_SECONDSÚ!FAILURE_REASON_BILLING_UNVERIFIEDÚminÚ%EXHAUSTED_TTL_SOLE_CREDENTIAL_SECONDSÚFAILURE_REASON_BILLING)r  r   r_   ÚbaseÚ
is_billings   &$$  r;   Ú_exhausted_ttlr  s  sp   € ð& �SÔÜ(Ð(Ø(2°cÔ(9Õ$Ô?\€DØÔ:Ô:¸zÈSÔ?PÜ�4Ô>Ó?Ð?Ø˜sÑ"×NÐN nÔ8NÑ&N€JßŸzÜ�4Ô>Ó?Ð?Ø€Kr=   c               ó$   € V ^8„  d   QhRRRRRR/# )r6   Ústater   rä   rv   r7   ræ   r9   )r:   s   "r;   r<   r<   ‘  s"   € ÷ ñ  Sð Ð1Að Àdñ r=   c                ó°   € \        VP                  4      pVf   R# \        \        V \        4      '       d   V P	                  R4      MR4      pVf   R# W28  # )a0  True only when the auth.json singleton is PROVABLY older than *entry*.

Both sides stamp ``last_refresh`` on every successful rotation. When
either side lacks a parseable stamp this returns False (cannot prove),
which keeps the historical adopt-on-difference behavior (#70111) intact
for legacy writers.
NFr…   )r   r…   rp   rÞ   rC   )r  rä   Úentry_tsÚstate_tss   &&  r;   Ú_singleton_predates_entryr  ‘  sS   € ô )¨×);Ñ);Ó<€HØÒÙÜ(ÄjÐQVÔX\×F]ÒF]¨¯©°>Ô)BÐcgÓh€HØÒÙØÑÐr=   c               ó    € V ^8„  d   QhRRRR/# )r6   Úerror_contextúOptional[dict[str, Any]]r7   rf   r9   )r:   s   "r;   r<   r<   ¢  s   € ÷ ñ Ð,Dð Èñ r=   c                óJ  € \        V \        4      '       g   / # / pR FV  pV P                  V4      p\        V\        4      '       g   K,  VP	                  4       '       g   KD  VP	                  4       W&   KX  	  V P                  R4      ;'       g+    V P                  R4      ;'       g    V P                  R4      p\        V4      pV P                  R4      pVfB   \        V\        4      '       d,   \        V4      pVe   \        P                  ! 4       V,           pVe   WQR&   V# )ÚreasonÚmessageÚreset_atÚ	resets_atÚretry_until)r  r  )rp   rÞ   rC   rk   r½   r   r   Útime)r  rþ   rØ   r¶   r  Úparsed_reset_atr  Úretry_delay_secondss   &       r;   Ú_normalize_error_contextr!  ¢  s   € Ü�m¤T×*Ò*Øˆ	Ø!#€JÛ$ˆØ×!Ñ! #Ó&ˆÜ�eœS×!Ô! e§k¡k§m¤mØ#Ÿk™k›mˆJ‹Oñ %ð
 	×Ñ˜*Ó%÷ 	,ð 	,Ø×Ñ˜[Ó)÷	,ð 	,à×Ñ˜]Ó+ð ô
 0°Ó9€OØ×Ñ 	Ó*€GØÒ¤:¨g´s×#;Ò#;Ü6°wÓ?ÐØÒ*Ü"Ÿiši›kÐ,?Õ?ˆOØÒ"Ø!0�:ÑØÐr=   c               ó$   € V ^8„  d   QhRRRRRR/# )r6   rä   rv   r   ræ   r7   r   r9   )r:   s   "r;   r<   r<   º  s#   € ÷ ñ Ð,ð À$ð ÐSbñ r=   c               óô   € V P                   \        8w  d   R # \        V P                  4      pVe   V# V P                  '       d4   V P                  \        V P                  VV P                  R7      ,           # R # )N)r   r_   )r`   ÚSTATUS_EXHAUSTEDr   re   ra   r  rb   r_   )rä   r   r  s   &$ r;   Ú_exhausted_untilr%  º  so   € Ø×ÑÔ,Ô,ÙÜ(¨×)BÑ)BÓC€HØÒØˆØ××ÐØ×#Ñ#¤nØ×!Ñ!Ø+Ø ×/Ñ/ô'
õ 
ð 	
ñ
 r=   c               ó    € V ^8„  d   QhRRRR/# )r6   r“   rk   r7   r9   )r:   s   "r;   r<   r<   Ì  s   € ÷ 2ñ 2 cð 2¨cñ 2r=   c                ó^   € V P                  4       P                  4       P                  RR4      # )z>Normalize a custom provider name for use as a pool key suffix.Ú Ú-)r½   rý   r	   )r“   s   &r;   Ú_normalize_custom_pool_namer*  Ì  s$   € à�:‰:‹<×ÑÓ×'Ñ'¨¨SÓ1Ð1r=   c               ó    € V ^8„  d   QhRRRR/# )r6   Úurlr   r7   rk   r9   )r:   s   "r;   r<   r<   Ñ  s   € ÷ .ñ .�3ð .˜3ñ .r=   c                óf   € \        T ;'       g    R 4      P                  4       P                  R4      # )r¢   rÆ   )rk   r½   rÇ   )r,  s   &r;   Ú	_norm_urlr.  Ñ  s&   € Üˆs�yˆy�b‹>×ÑÓ!×(Ñ(¨Ó-Ð-r=   c               ó   € V ^8„  d   QhRR/# )r6   Úconfigr8   r9   )r:   s   "r;   r<   r<   Õ  s   € ÷ Dñ D >ñ Dr=   c              #  óH  "  € V f   \        4       p V f   R#  ^ RIHp V! V 4      pT;'       g    R FX  p\	        T\
        4      '       g   K  \	        TP                  R4      \        4      '       g   KB  \        TR,          4      T3x € KZ  	  R#   \         d     R# i ; i5i)zOYield ``(normalized_name, entry)`` from the merged custom-provider config view.N)Úget_compatible_custom_providersr“   r9   )	rE   rA   r2  rD   rp   rÞ   rC   rk   r*  )r0  r2  Úcustom_providersrä   s   &   r;   Ú_iter_custom_providersr4  Õ  s�   é € à‚~Ü"Ó$ˆØ‚~ÙðÝEá:¸6ÓBÐð "×'Ð' RÒ'ˆÜ�eœT×"Ô"¤z°%·)±)¸FÓ2CÄS×'IÔ'IÜ-¨e°F­mÓ<¸eÐCÔCó (øô ô Úðüs8   ‚B"˜B ¦B"¯B"Á"B"Á4B"ÂBÂB"ÂBÂB"c               ó$   € V ^8„  d   QhRRRRRR/# )r6   Ú	norm_namerk   rä   rf   r7   Úsetr9   )r:   s   "r;   r<   r<   æ  s!   € ÷ ñ ¨#ð °nð Èñ r=   c                ó˜   € V 0p\        \        VP                  R 4      ;'       g    R4      4      pV'       d   VP                  V4       V# )Úprovider_keyr¢   )r*  rk   rC   Úadd)r6  rä   Úaliasesr9  s   &&  r;   Ú_custom_entry_name_aliasesr<  æ  s>   € Øˆk€GÜ.¬s°5·9±9¸^Ó3L×3RÐ3RÐPRÓ/SÓT€LßØ�‰�LÔ!Ø€Nr=   c               ó    € V ^8„  d   QhRRRR/# )r6   Úprovider_namerk   r7   r7  r9   )r:   s   "r;   r<   r<   î  s   € ÷ ñ °#ð ¸#ñ r=   c                óä   € \        V 4      pV'       d   V0M	\        4       pVP                  \        4      '       d5   \        V\	        \        4      R  4      pV'       d   VP                  V4       V# r�   )r*  r7  rq   ÚCUSTOM_POOL_PREFIXÚlenr:  )r>  rþ   r;  Úsuffixs   &   r;   Ú_requested_custom_name_aliasesrC  î  sW   € Ü,¨]Ó;€Jß(ˆz‰l¬c«e€GØ×ÑÔ/×0Ò0Ü,¨Z¼Ô<NÓ8OÐ8PÐ-QÓRˆßØ�K‰K˜ÔØ€Nr=   c               ó$   € V ^8„  d   QhRRRRRR/# )r6   r6  rk   rä   rf   r7   ú	list[str]r9   )r:   s   "r;   r<   r<   ø  s!   € ÷ ñ ¨3ð °~ð È)ñ r=   c                ó  € . p\        \        VP                  R4      ;'       g    R4      4      pY0'       d   \         V  2MR3 FD  pVP	                  4       P                  4       pV'       g   K+  WR9  g   K3  VP                  V4       KF  	  V# )zFDurable ``providers.<key>`` slug first, then legacy ``custom:<name>``.r9  r¢   )r*  rk   rC   r@  r½   rý   Úappend)r6  rä   Úkeysr9  rØ   rþ   s   &&    r;   Ú_pool_keys_for_custom_entryrI  ø  sy   € à€DÜ.¬s°5·9±9¸^Ó3L×3RÐ3RÐPRÓ/SÓT€LØÆIÔ!3Ð 4°Y°KÑ@ÐSUÓVˆØ—Y‘Y“[×&Ñ&Ó(ˆ
ß‰:˜*Ö0Ø�K‰K˜
Ö#ñ Wð €Kr=   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r6   r‚   r}   r>  r0  r8   r7   rE  r9   )r:   s   "r;   r<   r<     s2   € ÷ @ñ @Øð@Ø,9ð@ØJXð@àñ@r=   c                óF   € ^ RI Hp V! WV4      pV'       d
   \        V!  # . # )aq  Return pool keys to try for a custom endpoint: the durable ``providers.<key>`` slug
(``hermes auth add <key>``), then legacy ``custom:<display-name>``, so a populated pool is not
skipped for the ``no-key-required`` placeholder. ``config`` is a frozen route's config: ITS
entry owns the endpoint, so a live edit of that entry's URL neither drops nor redirects the pool.
)Úcustom_entry_for_endpoint)Úagent.custom_entry_poolrL  rI  )r‚   r>  r0  rL  Úmatchs   &&&  r;   Ú#custom_provider_pool_key_candidatesrO    s'   € õ BÙ% h¸vÓF€Eß27Ô&¨Ñ.Ð?¸RÐ?r=   c               ó$   € V ^8„  d   QhRRRRRR/# )r6   r‚   r}   r>  r7   r9   )r:   s   "r;   r<   r<     s"   € ÷ 1ñ 1¨=ð 1Èð 1Ðboñ 1r=   c                ó>   € \        W4      pV'       d
   V^ ,          # R# )zÁPreferred pool key for a custom provider: durable slug, else ``custom:<name>``.

When provider_name is given, match by name first so two custom providers
sharing a base_url keep separate keys.
N)rO  )r‚   r>  Ú
candidatess   && r;   Úget_custom_provider_pool_keyrS    s   € ô 5°XÓM€Jß&ˆ:�a�=Ð0¨DÐ0r=   c               ó   € V ^8„  d   QhRR/# )r6   r7   rE  r9   )r:   s   "r;   r<   r<     s   € ÷ ñ  Iñ r=   c                 óD   a € \        R4      o \        V 3R lS  4       4      # )z?Return all 'custom:*' pool keys that have entries in auth.json.Nc              3  óÒ   <"  € T F\  pVP                  \        4      '       g   K   \        SP                  V4      \        4      '       g   KG  SV,          '       g   KX  Vx € K^  	  R # 5ir�   )rq   r@  rp   rC   Úlist)ró   rØ   Ú	pool_datas   & €r;   rô   Ú-list_custom_pool_providers.<locals>.<genexpr>  sN   øé € ð Ù �Ø�>‰>Ô,×-ô 	ä�y—}‘} SÓ)¬4×0ô 	ð �c�N‰N÷ 	Š“yùs   ƒA'¥"A'ÁA'Á
A')r3   Úsorted)rX  s   @r;   Úlist_custom_pool_providersr[    s'   ø€ ä$ TÓ*€IÜô Ù óó ð r=   c               ó    € V ^8„  d   QhRRRR/# )r6   Úpool_keyrk   r7   r  r9   )r:   s   "r;   r<   r<   '  s   € ÷ gñ g¨#ð gÐ2Jñ gr=   c                óž   a€ V P                  \        4      '       g   R# V \        \        4      R o\        V3R l\	        4        4       R4      # )zWReturn the custom_providers config entry matching a pool key like 'custom:together.ai'.Nc              3  ó>   <"  € T F  w  rVS8X  g   K  Vx € K  	  R # 5ir�   r9   )ró   r6  rä   rB  s   &  €r;   rô   Ú._get_custom_provider_config.<locals>.<genexpr>,  s    øé € Ð_Ñ/GÑ+˜9È9ÐX^ÑK^—’Ó/Gùs   ƒ“
)rq   r@  rA  Únextr4  )r]  rB  s   &@r;   Ú_get_custom_provider_configrb  '  sC   ø€ à×ÑÔ1×2Ò2ÙØ”cÔ,Ó-Ð.Ð/€FÜÔ_Ô/EÔ/GÓ_ÐaeÓfÐfr=   c               ó    € V ^8„  d   QhRRRR/# )r6   rj   rk   r7   r9   )r:   s   "r;   r<   r<   /  s   € ÷ Vñ V ð V¨ñ Vr=   c                ó,  € \        4       pV'       d   VP                  R4      MRp\        V\        4      '       g   \        # \        VP                  V R4      ;'       g    R4      P                  4       P                  4       pV\        9   d   V# \        # )z8Return the configured selection strategy for a provider.Úcredential_pool_strategiesNr¢   )	rE   rC   rp   rÞ   ÚSTRATEGY_FILL_FIRSTrk   r½   rý   ÚSUPPORTED_POOL_STRATEGIES)rj   r0  Ú
strategiesÚstrategys   &   r;   Úget_pool_strategyrj  /  ss   € äÓ €Fß=C�—‘Ð8Ô9È€JÜ�j¤$×'Ò'Ü"Ð"Ü�:—>‘> (¨BÓ/×5Ð5°2Ó6×<Ñ<Ó>×DÑDÓF€HØÔ#<Ô<ˆ8ÐUÔBUÐUr=   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r6   Úpool_providerrk   Úprovider_normr‚   r}   r7   ræ   r9   )r:   s   "r;   r<   r<   9  s0   € ÷ ñ Øðàðð ðð 
ñ	r=   c                ó  € \        V4      pV'       g   R#  \        4        FÎ  w  rE\        \        VP	                  R4      ;'       g    R4      4      pW`8w  d   K:  \        WE4      pVP                  \         V 24       V'       d   VP                  \         V 24       \        VP	                  R4      4      pVR8X  d   W88H  u # \        V4      p	\        W—,          4      ;'       d    W88H  u # 	  R#   \         d     R# i ; i)zDMatch a durable ``providers.<key>`` pool against runtime identities.Fr9  r¢   r‚   Úcustom)r.  r4  r*  rk   rC   r<  r:  r@  rC  ræ   rD   )
rl  rm  r‚   Úruntime_urlÚnormalized_namerä   r9  r;  Úconfigured_urlÚruntime_aliasess
   &&&       r;   Ú_keyed_custom_pool_matchesrt  9  sï   € ô ˜HÓ%€KßÙðÜ&<Ö&>Ñ"ˆOÜ6´s¸5¿9¹9À^Ó;T×;ZÐ;ZÐXZÓ7[Ó\ˆLØÔ,ÙÜ0°ÓHˆGØ�K‰KÔ-Ð.¨Ð.?Ð@ÔAßØ—‘Ô1Ð2°<°.ÐAÔBÜ& u§y¡y°Ó'<Ó=ˆNØ Ô(Ø"Ñ4Ò4Ü<¸]ÓKˆOÜ˜Õ1Ó2×TÐT°{Ñ7TÒTñ '?ñ øô ô Úðús   —B/C5 Ã)C5 Ã1C5 Ã5DÄDc               ó(   € V ^8„  d   QhRRRRRRRR/# )r6   rl  rk   rm  rp  r7   ræ   r9   )r:   s   "r;   r<   r<   U  s0   € ÷ ñ Øðàðð ðð 
ñ	r=   c           	     óÌ  €  \        4        EFA  w  r4\         V 2V 8w  d   K  V0pVP                  R4      VP                  R4      3 Fz  p\        \	        T;'       g    R4      4      pV'       g   K+  VP                  V4       VP                  \        4      '       g   KY  VP                  V\        \        4      R 4       K|  	  \        VP                  R4      4      p\        V4      0p	VP                  \        4      '       d+   V	P                  \        V\        \        4      R 4      4       \        W•,          4      ;'       d    W(8H  u # 	  R#   \         d     R# i ; i)zGMatch a legacy ``custom:<name>`` pool against a named runtime identity.r“   r9  r¢   Nr‚   F)r4  r@  rC   r*  rk   r:  rq   rA  r.  ræ   rD   )
rl  rm  rp  rq  rä   r;  r¶   Úaliasrr  rs  s
   &&&       r;   Ú_legacy_custom_pool_matchesrx  U  s1  € ðÜ&<×&>Ñ"ˆOÜ$Ð% oÐ%6Ð7¸=ÔHÙØ&Ð'ˆGØŸ)™) FÓ+¨U¯Y©Y°~Ó-FÓG�Ü3´C¸¿¸ÀÓ4DÓE�ß‘5Ø—K‘K Ô&Ø×'Ñ'Ô(:×;Ô;ØŸ™ E¬#Ô.@Ó*AÐ*BÐ$CÖDñ Hô ' u§y¡y°Ó'<Ó=ˆNÜ:¸=ÓIÐJˆOØ×'Ñ'Ô(:×;Ò;Ø×#Ñ#Ô$?ÀÌcÔRdÓNeÐNfÐ@gÓ$hÔiÜ˜Õ1Ó2×TÐT°{Ñ7TÒTñ '?ñ" øô ô Úðús+   ‚A,E Á3)E Â!B'E Å	E ÅE ÅE#Å"E#c               ó$   € V ^8„  d   QhRRRRRR/# )r6   rä   r   r‚   r7   ræ   r9   )r:   s   "r;   r<   r<   p  s&   € ÷ Uñ U°ð UÀð UÈñ Ur=   c                óô   € \        V\        4      '       d	   V'       g   R# \        V RR4      ;'       g    \        V RR4      p\        V\        4      '       d	   V'       g   R# ^ RIHp V! V4      V! V4      8H  # )u   Whether a pooled credential may be bound to a session running at ``base_url``. ``_swap_credential``
adopts the entry's base_url too, so a same-provider entry for another endpoint (public OpenAI vs. an
Azure resource) would send the session's requests â€” and the entry's key â€” to the wrong host (#68237).
Entries or sessions without endpoint metadata (legacy adapters, test doubles) cannot rebind and are accepted.TrÈ   Nr‚   )Únormalize_route_base_url)rp   rk   r³   Úhermes_cli.route_identityr{  )rä   r‚   Ú	entry_urlr{  s   &&  r;   Ú%credential_pool_entry_serves_endpointr~  p  sb   € ô
 �h¤×$Ò$¯HÙÜ˜Ð1°4Ó8×\Ð\¼GÀEÈ:ÐW[Ó<\€IÜ�i¤×%Ò%¯YÙÝBÙ# IÓ.Ñ2JÈ8Ó2TÑTÐTr=   r‚   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r6   Úpool_or_providerr   rj   r}   r‚   r7   ræ   r9   )r:   s   "r;   r<   r<   ~  s6   € ÷ ,Rñ ,RØð,Ràð,Rð ð	,Rð
 
ñ,Rr=   c               óT  € \        V RR4      pVf   \        V \        4      '       g   R# T p\        T;'       g    R4      P                  4       P	                  4       p\        T;'       g    R4      P                  4       P	                  4       pV'       d	   V'       g   R# VP                  \        4      '       g   WE8X  d   R# \        WEV4      # VR8X  d�    \        T;'       g    R4      p\        T;'       g    R4      P                  4       P	                  4       V8X  d   R# \        T;'       g    R4      pYG Uu0 uF*  p\        T4      P                  4       P	                  4       kK,  	  up9   # \        V4      p	V	'       g   R# \        WEV	4      #   \         d     R# i ; iu upi )a)  Return whether a pool belongs to the requested runtime provider.

Named custom endpoints may use three identities: the live agent can retain
the configured name/provider key, newer runtime paths normalize it to
``custom``, and the pool may be keyed as the durable ``providers.<key>``
slug or as legacy ``custom:<name>``. Accept those aliases only when the
runtime endpoint belongs to the same configured custom provider. Empty
identities fail closed. Legacy pool adapters without a ``provider``
attribute remain compatible; production pools are scoped.
rj   NTr¢   Fro  )r³   rp   rk   r½   rý   rq   r@  rt  rS  rO  rD   r.  rx  )
r€  rj   r‚   Úraw_pool_providerrl  rm  Úmatched_poolrR  rØ   rp  s
   &&$       r;   Ú credential_pool_matches_providerr„  ~  sd  € ô   Ð 0°*¸dÓCÐØÒ ÜÐ*¬C×0Ò0ñ Ø,ÐÜÐ)×/Ð/¨RÓ0×6Ñ6Ó8×>Ñ>Ó@€MÜ˜Ÿ˜ BÓ'×-Ñ-Ó/×5Ñ5Ó7€Mß§ÙØ×#Ñ#Ô$6×7Ò7ØÔ)ÙÜ)¨-ÈÓQÐQØ˜Ô ð	Ü7¸¿¸ÀBÓGˆLÜ�<×%Ð% 2Ó&×,Ñ,Ó.×4Ñ4Ó6¸-ÔGÙÜ<¸X¿^¸^ÈÓLˆJð ÀZÓ PÁZ¸c¤ S£§¡Ó!1×!7Ñ!7Ö!9ÁZÑ PÑPÐPä˜HÓ%€KßÙÜ& }À[ÓQÐQøô ô 	Úð	üâ Ps0   ÃF Ã%F Ã:(F Ä$F Ä2F Ä=0F%ÆF"Æ!F"c               ó$   € V ^8„  d   QhRRRRRR/# )r6   rj   r}   r‚   r7   rk   r9   )r:   s   "r;   r<   r<   ­  s"   € ÷ ñ  }ð Àð ÐRUñ r=   c                óÐ  aa€ \        T ;'       g    R4      P                  4       P                  4       oS'       g   R# R VV3R llp SR8X  dK   \        S4      pV'       d6   V! V4      '       d(   \        V4      P                  4       P                  4       # S# \	        4        F+  w  rE\        WE4       F  pV! V4      '       g   K  Vu u # 	  K-  	   S#   \         d     S# i ; i)a~  Resolve the credential-pool key for a runtime provider identity.

Named custom runtimes retain their configured alias while their pool may
be stored under the durable ``providers.<key>`` slug or legacy
``custom:<name>``. Return that scoped key only when the canonical
provider/endpoint boundary accepts it; otherwise preserve the normalized
runtime identity so callers fail closed.
r¢   c               ó    € V ^8„  d   QhRRRR/# )r6   Ú	candidaterk   r7   ræ   r9   )r:   s   "r;   r<   Ú.resolve_runtime_pool_key.<locals>.__annotate__º  s   € ÷ ]ñ ]˜Cð ] Dñ ]r=   c                ó    <€ \        V SSR 7      # )©r‚   )r„  )rˆ  r‚   rm  s   &€€r;   Ú_acceptsÚ*resolve_runtime_pool_key.<locals>._acceptsº  s   ø€ Ü/°	¸=ÐS[Ô\Ð\r=   ro  )rk   r½   rý   rS  r4  rI  rD   )rj   r‚   rŒ  rˆ  rq  rä   rm  s   &f    @r;   Úresolve_runtime_pool_keyrŽ  ­  sØ   ù€ ô ˜Ÿ˜ BÓ'×-Ñ-Ó/×5Ñ5Ó7€MßÙ÷]ñ ]ðØ˜HÔ$Ü4°XÓ>ˆIß™X i×0Ò0Ü˜9“~×+Ñ+Ó-×3Ñ3Ó5Ð5ð Ðô +AÖ*BÑ&�Ü!<¸_Ö!T�IÙ 	×*Ô*Ø(Ô(ó "Uò +Cð Ðøô ô ØØÐðús*   Á	'C Á1&C Â(C ÃC ÃC ÃC%Ã$C%c               ó    € V ^8„  d   QhRRRR/# )r6   Úglobal_pathúOptional[Path]r7   r9   )r:   s   "r;   r<   r<   Õ  s   € ÷ ñ  nð ¸ñ r=   c                ó  € V f   R# \         P                  P                  R4      '       dÃ   \         P                  P                  RR4      pV'       d›   \        V4      R,          R,          p \         P                  P                  \         P                  P                  V 4      4      \         P                  P                  \         P                  P                  V4      4      8X  d   R#  V # V #   \         d     R# i ; i)a‚  Apply the pytest seat belt to a resolved global-root auth.json path.

``None`` means classic mode (profile == root) or "refuse": under pytest,
never write the real user's ``~/.hermes/auth.json`` even when HERMES_HOME
points at a profile path (mirrors the read-side guard in
``_load_global_auth_store``). Uses the unmodified HOME env, not
``Path.home()`` which fixtures may monkeypatch.
NÚPYTEST_CURRENT_TESTÚHOMEr¢   z.hermesz	auth.json)ÚosÚenvironrC   r   ÚpathÚnormcaseÚabspathrD   )r�  Úreal_home_envÚ	real_roots   &  r;   Ú_guarded_global_rootrœ  Õ  sÁ   € ð ÒÙÜ	‡z�z‡~�~Ð+×,Ò,ÜŸ
™
Ÿ™ v¨rÓ2ˆßÜ˜]Ó+¨iÕ7¸+ÕEˆIðä—7‘7×#Ñ#¤B§G¡G§O¡O°KÓ$@ÓAÄRÇWÁW×EUÑEUÔVX×V]ÑV]×VeÑVeÐfoÓVpÓEqÔqÙð rð Ðˆ;Ðøô ô Úðús   Á.A;C0 Ã0C?Ã>C?c               ó$   € V ^8„  d   QhRRRRRR/# )r6   Úprovider_idrk   r  rf   r7   ÚNoner9   )r:   s   "r;   r<   r<   í  s)   € ÷ cñ cØðcØ+ðcà	ñcr=   c                ó  €  \        \        P                  ! 4       4      pTf   R#  \        P                  ! YTRR7       R#   \         d     R# i ; i  \         d"   p\
        P                  RY4        Rp?R# Rp?ii ; i)u1  Persist a rotated OAuth ``state`` into the global-root auth.json.

Best-effort write-through for the multi-profile rotation hazard: nous,
openai-codex, and xai-oauth rotate the refresh_token on refresh, so when
a profile pool refresh rotates a grant it resolved from the root fallback,
the rotated chain must land back in root. Otherwise root keeps a revoked
refresh token and every other profile dies with ``refresh_token_reused``
/ ``invalid_grant`` once its access token expires.

Only updates ``providers.<provider_id>`` in the root store; never touches
the profile store (the caller already saved that). Swallows all errors â€”
a failed write-through degrades to root-stale and must never break the
profile's own successful save. Mirrors
``hermes_cli.auth._write_through_xai_oauth_to_global_root``.

See #48415.
NF©Ú
set_activez8%s pool refresh: write-through to global root failed: %s)rœ  r¾   r)   rD   Ú _persist_provider_state_to_storeÚloggerÚdebug)rž  r  r�  Úexcs   &&  r;   Ú,_write_through_provider_state_to_global_rootr§  í  sx   € ð(Ü*¬8×+JÒ+JÓ+LÓMˆð ÒÙðcÜ×1Ò1°+ÀkÐ^c×døô ô Úðûô ô cÜ�‰ÐOÐQ\×bÒbûðcús(   ‚A §A ÁAÁAÁB ÁA;Á;B c               ó$   € V ^8„  d   QhRRRRRR/# )r6   ÚpoolÚCredentialPoolrä   rv   r7   r‘  r9   )r:   s   "r;   r<   r<     s#   € ÷ ñ  nð Ð=Mð ÐR`ñ r=   c                ó    € VP                   R8w  g   VP                  \        V RR4      9  d   R#  ^ RIHp V! 4       #   \
         d     R# i ; i)zURoot ``.anthropic_oauth.json`` when *entry* is a borrowed hermes_pkce row, else None.Úhermes_pkceÚ_borrowed_root_idsN)Ú_root_hermes_oauth_filer9   )r{   rw   r³   Úagent.anthropic_credentialsr®  rD   )r©  rä   r®  s   && r;   Ú_singleton_target_for_entryr°    sJ   € à‡|�|�}Ô$¨¯©¼ÀÐFZÐ\^Ó8_Ô(_ÙðÝGÙ&Ó(Ð(øÜô Úðús   ±> ¾AÁAc               ó$   € V ^8„  d   QhRRRRRR/# )r6   Ú
auth_storerf   rj   rk   r7   ræ   r9   )r:   s   "r;   r<   r<     s!   € ÷ 7ñ 7¨.ð 7ÀCð 7ÈDñ 7r=   c                ó¼   € V P                  R4      p\        V\        4      '       d   VP                  V4      MRp\        V\        4      ;'       d    \	        V4      # )zITrue when an already-loaded *auth_store* has its own rows for *provider*.Úcredential_poolN)rC   rp   rÞ   rW  ræ   )r²  rj   r©  rí   s   &&  r;   Ú_store_owns_pool_providerrµ    sF   € à�>‰>Ð+Ó,€DÜ$.¨t´T×$:Ò$:ˆd�h‰h�xÔ À€GÜ�gœtÓ$×6Ð6¬¨g«Ð6r=   c               ó    € V ^8„  d   QhRRRR/# )r6   rj   rk   r7   ræ   r9   )r:   s   "r;   r<   r<     s   € ÷ ;ñ ;¨#ð ;°$ñ ;r=   c                ó„   € \         P                  ! 4       f   R#  \        4       p\	        Y4      #   \         d     R# i ; i)z¾True when the ACTIVE auth.json has its own rows for *provider*.

Named profiles with no local rows read the provider through the
``read_credential_pool`` global-root fallback ("borrowing").
T)r¾   r)   r*   rD   rµ  )rj   r²  s   & r;   Ú_profile_owns_pool_providerr¸    sD   € ô ×&Ò&Ó(Ò0ÙðÜ%Ó'ˆ
ô % ZÓ:Ð:øô ô Úðús   ›
0 °?¾?c               ó   € V ^8„  d   QhRR/# )r6   r7   r‘  r9   )r:   s   "r;   r<   r<   0  s   € ÷ 	ñ 	¨ñ 	r=   c                 óN   €  \        \        4       4      #   \         d     R# i ; i)zÙGlobal-root auth.json when persisting a BORROWED single-use pool, else None.

``None`` means "persist to the active store as usual": classic mode
(profile == root), or the profile owns its own rows for this provider.
N)rœ  r)   rD   r9   r=   r;   Ú_borrowed_single_use_pool_rootr»  0  s(   € ðÜ#Ô$:Ó$<Ó=Ð=øÜô Úðús   ‚ •$£$Ústatus_cleared_idsÚtoken_basesc               ó0   € V ^8„  d   QhRRRRRRRRR	R
RR/# )r6   rj   rk   Úpayloadsúlist[dict[str, Any]]r�  r   r¼  úOptional[Iterable[str]]r½  ú$Optional[dict[str, tuple[Any, Any]]]r7   r9   )r:   s   "r;   r<   r<   <  s@   € ÷ )ñ )Øð)Ø1ð)Ø@Dð)à2ð)ð 6ð)ð ñ	)r=   c               óT  € \        VR7      ;_uu_ 4        \        V4      pVP                  R4      p\        V\        4      '       g   / pWeR&   VP                  V 4      p\        V\
        4      '       d   TM. p\        P                  ! V4      p	T;'       g    R U
u0 uF  qª'       g   K  V
kK  	  pp
T;'       g    / p. pRpV F¤  p\        V\        4      '       d   VP                  R4      MRpV'       d   V	P                  V4      MRpVf   VP                  V4       K^  \        P                  ! VWðVP                  V4      VV9   R7      pVV8w  d   RpVP                  V4       K¦  	  V'       d   WÖV &   \        WRR7       VuuRRR4       # u up
i   + '       g   i     R# ; i)	us  UPDATE-ONLY merge of *payloads* into the root store's rows for *provider*.

A borrower may refresh the root's rows (rotation, cooldown state) but
never add or delete them â€” the root owns their lifecycle. In particular a
profile's singleton-prune (it has no ``.anthropic_oauth.json`` of its own)
must not delete the root grant, so ``removed_ids`` is ignored by callers.
)Útarget_pathr´  Frw   N)Ú	base_pairÚstatus_clearedTr9   )r&   r*   rC   rp   rÞ   rW  r¾   Ú
_entry_idsrG  Ú_merge_pool_row_generationr0   )rj   r¿  r�  r¼  r½  Ústorer©  ÚexistingÚexisting_listÚincoming_by_idÚcidÚclearedÚbasesÚmergedÚchangedÚ
disk_entryÚdidÚincomingÚupdateds   &&&$$              r;   Ú_update_root_pool_rowsrÖ  <  sq  € ô 
 k×	2Ö	2Ü  Ó-ˆØ�y‰yÐ*Ó+ˆÜ˜$¤×%Ò%ØˆDØ'+Ð#Ñ$Ø—8‘8˜HÓ%ˆÜ$.¨x¼×$>Ò$>™ÀBˆÜ!×,Ò,¨XÓ6ˆØ#5×#;Ð#;¸Ð#;ÓDÑ#;˜3Ã—3�3Ñ#;ˆÐDØ×!Ð!˜rˆØ')ˆØˆÛ'ˆJÜ*4°ZÄ×*FÒ*F�*—.‘. Ô&ÈDˆCß25�~×)Ñ)¨#Ô.¸4ˆHØÒØ—‘˜jÔ)ÙÜ×9Ò9Ø˜*ØŸ)™) C›.¸À¹ôˆGð ˜*Ô$Ø�Ø�M‰M˜'Ö"ñ (÷ Ø#�‰NÜ˜UÕ<Ø÷; 
3Ò	2ùò E÷ 
3×	2Ð	2ús=   •BFÂFÂ	FÂ+FÂ1
FÂ<<FÃ9A;FÅ5FÆFÆF'	Úremoved_idsc               ó0   € V ^8„  d   QhRRRRRRRRRR	R
R/# )r6   rj   rk   r¿  rÀ  r×  rÁ  r¼  r½  rÂ  r7   zOptional[list[dict[str, Any]]]r9   )r:   s   "r;   r<   r<   h  sD   € ÷ 'ñ 'Øð'à"ð'ð )ð	'ð
 0ð'ð 6ð'ð $ñ'r=   c               óî   € V \         9   d/   \        V 4      '       g   \        4       pVe    \        WVW4R7      # \        WW#VR7      #   \         d"   p\
        P                  RY4        Rp?R# Rp?ii ; i)a.  Persist a provider's pool rows to the store that OWNS them.

A named profile that sees a single-use-refresh provider (see
``SINGLE_USE_REFRESH_POOL_PROVIDERS``) only through the global-root fallback must not
materialize a local ``credential_pool.<provider>`` copy: that copy forks
the single-use refresh token, the first profile to rotate commits the new
pair only to its own file, and root plus every sibling die with
``invalid_grant`` (#100339). Such rows are written back to the root store
(under the root lock); everything else goes to the active store.
N)r¼  r½  za%s pool: write-through of borrowed root grant failed (%s); not materializing a profile-local copy©r×  r¼  r½  )r%   r¸  r»  rÖ  rD   r¤  Úwarningr4   )rj   r¿  r×  r¼  r½  r�  r¦  s   &&$$$  r;   Úpersist_pool_entriesrÜ  h  sŠ   € ð$ Ô4Ô4Ô=XÐYa×=bÒ=bÜ4Ó6ˆØÒ"ðÜ-Ø¨Ø'9ôð ô !Ø¨Øôð øô ô ô —‘ð=à÷ð ñ
 ûðús   ¬A ÁA4ÁA/Á/A4rÄ   ú	xai-oauthz$dict[str, tuple[str, str, str, str]]Ú_TOKENS_SINGLETON_PROVIDERSro   r»   g      à?Ú$HERMES_CODEX_REFRESH_TIMEOUT_SECONDSÚ"HERMES_XAI_REFRESH_TIMEOUT_SECONDSÚclaude_coderè   c                  ó2   a € ] tR tRtRtR V 3R lltRtV ;t# )Ú_RefreshDonei¾  z\Raised inside a provider refresher to short-circuit ``_refresh_entry_impl`` with ``result``.c               ó   € V ^8„  d   QhRR/# )r6   r´   úOptional[PooledCredential]r9   )r:   s   "r;   r<   Ú_RefreshDone.__annotate__Á  s   € ÷ ñ Ð9ñ r=   c                	ó0   <€ \         SV `  4        Wn        R # r�   )ÚsuperÚ__init__r´   )r�   r´   Ú	__class__s   &&€r;   ré  Ú_RefreshDone.__init__Á  s   ø€ Ü‰ÑÔØŽr=   )r´   )rš   rÊ   rË   rÌ   Ú__doc__ré  rÐ   Ú__classcell__)rê  s   @r;   rã  rã  ¾  s   ø† Ùf÷ö r=   rã  c            
      óL  € ] tR tRtR R ltR R ltRR/R R	 lltRR/R
 R lltRR/R R lltR R lt	R R lt
R R ltR R ltR R ltR€R R lltR R ltRRRR/R R lltR R!/R" R# lltR$ R% ltR& R' ltR€R R!R(R/R) R* llltR+ R, ltR- R. lt]tR/ R0 ltR1 R2 ltR3 R4 ltR5 R6 ltR7 R8 ltR9 tR: R; ltR< R= ltR> R? lt R@ RA lt!RB RC lt"RD RE lt#RF RG lt$RH RI lt%RJ RK lt&RL RM lt'RN RO lt(RP RQ lt)RR/RR RS llt*RR/RT RU llt+RV RW lt,RX RY lt-RZ R[ lt.R\R]R^R]RR/R_ R` llt/Ra Rb lt0R^R!RcR!RR/Rd Re llt1Rf Rg lt2RR/Rh Ri llt3Rj Rk lt4Rl Rm lt5RnRRoRRpRR(RRR/Rq Rr llt6R€Rs Rt llt7Ru Rv lt8Rw Rx lt9Ry Rz lt:R�R{ R| llt;R} R~ lt<Rt=R# )‚rª  iÆ  c               ó    € V ^8„  d   QhRRRR/# ©r6   rj   rk   rí   rî   r9   )r:   s   "r;   r<   ÚCredentialPool.__annotate__Ç  s   € ÷ 1ñ 1 ð 1Ð/Eñ 1r=   c                	ó  € Wn         \        VR  R7      V n        RV n        \	        4       V n        / V n        \        V4      V n        \        P                  ! 4       V n        / V n        \        V n        RV n        ^ V n        R# )c                ó   € V P                   # r�   rñ   ©rä   s   &r;   rM   Ú)CredentialPool.__init__.<locals>.<lambda>É  s   € ¸%¿.º.r=   ©rØ   N)rj   rZ  Ú_entriesÚ_current_idr7  r­  Ú_persisted_token_pairsrj  Ú	_strategyÚ	threadingÚRLockÚ_lockÚ_active_leasesÚ%DEFAULT_MAX_CONCURRENT_PER_CREDENTIALÚ_max_concurrentÚ_last_no_entries_log_atÚ_unmatched_rotation_streak©r�   rj   rí   s   &&&r;   ré  ÚCredentialPool.__init__Ç  sr   € Ø ŒÜ˜wÑ,HÔIˆŒØ*.ˆÔô -0«EˆÔØBDˆÔ#Ü*¨8Ó4ˆŒô
 —_’_Ó&ˆŒ
Ø.0ˆÔÜDˆÔð 9=ˆÔ$ð 01ˆÖ'r=   c               ó   € V ^8„  d   QhRR/# ©r6   r7   ræ   r9   )r:   s   "r;   r<   rñ  ä  s   € ÷ 'ñ ' ñ 'r=   c                	ó’   € V P                   ;_uu_ 4        \        V P                  4      uuR R R 4       #   + '       g   i     R # ; ir�   )rý  ræ   r÷  rŽ   s   &r;   Úhas_credentialsÚCredentialPool.has_credentialsä  ó#   € Ø�Z�Z‹ZÜ˜Ÿ™Ó&÷ �Z�Z‹Zúó	   •5µA	ÚmodelNc               ó    € V ^8„  d   QhRRRR/# ©r6   r  r}   r7   ræ   r9   )r:   s   "r;   r<   rñ  è  s   € ÷ 	#ñ 	# mð 	#¸tñ 	#r=   c               ó¦   € V P                   ;_uu_ 4        V P                  VR7      w  r#\        V4      uuRRR4       #   + '       g   i     R# ; i)a  True if at least one entry is not currently in exhaustion cooldown.

``_available_entries`` is not read-only (it prunes aged-out DEAD
manual entries and persists), so it must run under ``self._lock``
like every other caller or a probe can race a concurrent rotation.
©r  N©rý  Ú_available_entriesræ   ©r�   r  Ú	availableÚ_pendings   &$  r;   Úhas_availableÚCredentialPool.has_availableè  s6   € ð �Z�Z‹ZØ"&×"9Ñ"9ÀÐ"9Ó"FÑˆIÜ˜	“?÷ �Z�Z‹Zús	   •?¿A	c               ó    € V ^8„  d   QhRRRR/# r  r9   )r:   s   "r;   r<   rñ  ó  s   € ÷ #ñ #°ð #Èñ #r=   c               ó¨   € V P                   ;_uu_ 4        V P                  RVR7      w  r#\        V4      uuRRR4       #   + '       g   i     R# ; i)zàClear cooldowns that have elapsed or (Codex) reopened early, then report availability.

The lift ``select()`` performs, without leasing an entry. ``has_available`` and
``next_available_at`` never run the early-reopen probe.
T)Úclear_expiredr  Nr  r  s   &$  r;   Úlift_reopened_cooldownsÚ&CredentialPool.lift_reopened_cooldownsó  s9   € ð �Z�Z‹ZØ"&×"9Ñ"9ÈÐTYÐ"9Ó"ZÑˆIÜ˜	“?÷ �Z�Z‹Zús   • A Á A	c               ó    € V ^8„  d   QhRRRR/# )r6   r  r}   r7   r   r9   )r:   s   "r;   r<   rñ  ý  s   € ÷  ;ñ  ;¨-ð  ;À?ñ  ;r=   c               ó®  aa€ V P                   ;_uu_ 4        V P                  SR7      w  r#V'       d    RRR4       R# V P                  4       oV3R lV P                   4        Uu. uF  pVf   K	  VNK  	  ppVP	                  V3R lV P                   4       4       V'       d   \        V4      MRuuRRR4       # u upi   + '       g   i     R# ; i)aI  Earliest epoch time (seconds) any entry re-enters rotation.

``None`` when an entry is available now, or when no exhausted entry
carries a usable recovery time (empty pool, or only ``STATUS_DEAD``
entries). Callers must treat ``None`` as "no wait information".
Runs under ``self._lock`` for the same reason as ``has_available``.
r  Nc              3  ól   <"  € T F)  pVP                   \        8X  g   K  \        VSR 7      x € K+  	  R# 5i)©r   N)r`   r$  r%  )ró   rä   r   s   & €r;   rô   Ú3CredentialPool.next_available_at.<locals>.<genexpr>  s5   øé € ð á!.˜Ø×(Ñ(Ô,<Ñ<ô MÔ$ U¸O×LÑLÛ!.ùs   ƒ4Ÿ4c              3  óz   <"  € T F0  pVP                   \        8w  g   K  \        VS4      pVf   K,  Vx € K2  	  R # 5ir�   )r`   ÚSTATUS_DEADr   )ró   rä   Úuntilr  s   &  €r;   rô   r!    s>   øé € ð á*�EØ×$Ñ$¬Ñ3ô ô 3°5¸%Ó@�EØ÷	 ’Û*ùs   ƒ;Ÿ;±
;)rý  r  Ú_is_sole_credentialr÷  Úextendr	  )r�   r  r  r  r$  rR  r   s   &d    @r;   Únext_available_atÚ CredentialPool.next_available_atý  s¾   ù€ ð �Z�Z‹ZØ"&×"9Ñ"9ÀÐ"9Ó"FÑˆIßØ÷ ‰Zð #×6Ñ6Ó8ˆOôà!%§¢ôóñ�Eð
 ÷ �ñð ð ð ×Ñô à!Ÿ]š]óô ÷ '1”3�z”?°d÷1 ŠZùò÷ �ZˆZús(   —C¿(CÁ'B>Á2B>Á8;CÂ>CÃC	c               ó   € V ^8„  d   QhRR/# )r6   r7   rî   r9   )r:   s   "r;   r<   rñ    s   € ÷ 'ñ 'Ð/ñ 'r=   c                	ó’   € V P                   ;_uu_ 4        \        V P                  4      uuR R R 4       #   + '       g   i     R # ; ir�   )rý  rW  r÷  rŽ   s   &r;   rí   ÚCredentialPool.entries  r
  r  c               ó   € V ^8„  d   QhRR/# r  r9   )r:   s   "r;   r<   rñ  #  s   € ÷ Rñ R Tñ Rr=   c                ó@   € \        R V P                   4       4      ^8*  # )zWDEAD entries never re-enter rotation, so <=1 non-DEAD entry means nothing to rotate to.c              3  óR   "  € T F  qP                   \        8w  g   K  ^x € K  	  R# 5i)é   N)r`   r#  )ró   Úes   & r;   rô   Ú5CredentialPool._is_sole_credential.<locals>.<genexpr>%  s   é € ÐL™m˜¯}©}ÄÑ/K—1’1›mùs   ‚'�
')Úsumr÷  rŽ   s   &r;   r%  Ú"CredentialPool._is_sole_credential#  s   € äÑL˜dŸmšmÓLÓLÐPQÑQÐQr=   c               ó    € V ^8„  d   QhRRRR/# )r6   Ú	predicatez"Callable[[PooledCredential], bool]r7   rå  r9   )r:   s   "r;   r<   rñ  '  s    € ÷ Fñ FÐAð FÐF`ñ Fr=   c                	óD   a€ \        V3R  lV P                   4       R4      # )c              3  óH   <"  € T F  pS! V4      '       g   K  Vx € K  	  R # 5ir�   r9   )ró   r0  r5  s   & €r;   rô   Ú'CredentialPool._find.<locals>.<genexpr>(  s   øé € Ð>¡˜1±¸1·—Q’Q£ùs   ƒ"˜
"N)ra  r÷  )r�   r5  s   &fr;   Ú_findÚCredentialPool._find'  s   ø€ ÜÔ> §¢Ó>ÀÓEÐEr=   c               ó   € V ^8„  d   QhRR/# ©r6   r7   rå  r9   )r:   s   "r;   r<   rñ  *  s   € ÷ >ñ >Ð#=ñ >r=   c                	óV   a € S P                   '       g   R # S P                  V 3R l4      # )Nc                ó6   <€ V P                   SP                  8H  # r�   )rw   rø  )r0  r�   s   &€r;   rM   Ú2CredentialPool._current_unlocked.<locals>.<lambda>-  s   ø€  A§D¡D¨D×,<Ñ,<Ò$<r=   )rø  r9  rŽ   s   fr;   Ú_current_unlockedÚ CredentialPool._current_unlocked*  s"   ø€ Ø××ÐÙØ�z‰zÔ<Ó=Ð=r=   c               ó   € V ^8„  d   QhRR/# r<  r9   )r:   s   "r;   r<   rñ  /  s   € ÷ ,ñ ,Ð3ñ ,r=   c                	óˆ   € V P                   ;_uu_ 4        V P                  4       uuR R R 4       #   + '       g   i     R # ; ir�   )rý  r@  rŽ   s   &r;   ÚcurrentÚCredentialPool.current/  s#   € Ø�Z�Z‹ZØ×)Ñ)Ó+÷ �Z�Z‹Zúó	   •0°A	c               ó    € V ^8„  d   QhRRRR/# )r6   Úapi_key_hintr   r7   r}   r9   )r:   s   "r;   r<   rñ  3  s   € ÷ @ñ @°ð @Àñ @r=   c                ó²  € V P                   ;_uu_ 4        V P                  4       pVe,   Ve   VP                  V8X  d   VP                  uuRRR4       # Vf    RRR4       R# V P                   Uu. uF  q3P                  V8X  g   K  VNK  	  pp\        V4      ^8X  d   V^ ,          P                  MRuuRRR4       # u upi   + '       g   i     R# ; i)z¶Stable id for the runtime credential in use.

Prefer the current selection when it still supplies ``api_key_hint``;
if the cursor was cleared, fall back to an unambiguous key match.
N)rý  r@  rÀ   rw   r÷  rA  )r�   rH  rD  r0  Úmatchess   &&   r;   Úentry_id_for_api_keyÚ#CredentialPool.entry_id_for_api_key3  sª   € ð �Z�Z‹ZØ×,Ñ,Ó.ˆGØÒ"¨Ò(<À×@WÑ@WÐ[gÔ@gØ—z‘z÷ ŠZð Ò#Ø÷ ‰Zð #'§-¢-ÓU¡-˜Q×3DÑ3DÈÑ3T—q�q¡-ˆGÐUÜ$'¨£L°AÔ$5�7˜1•:—=’=¸4÷ ŠZùò V÷ �ZˆZús/   •5CÁCÁ$CÁ2C Â	C Â&CÃ CÃC	c               ó$   € V ^8„  d   QhRRRRRR/# )r6   Úoldrv   Únewr7   rŸ  r9   )r:   s   "r;   r<   rñ  D  s#   € ÷ ñ Ð"2ð Ð9Ið Èdñ r=   c                ó  € V P                   ;_uu_ 4        \        V P                  4       F9  w  r4VP                  VP                  8X  g   K"  W P                  V&    RRR4       R# 	  RRR4       R#   + '       g   i     R# ; i)u×   Swap an entry in-place by id, preserving sort order.

Self-locking (RLock) so the deferred refresh path â€” which runs outside
the pool lock â€” cannot tear ``self._entries`` against a concurrent
select()/rotation.
N)rý  Ú	enumerater÷  rw   )r�   rN  rO  Úidxrä   s   &&&  r;   Ú_replace_entryÚCredentialPool._replace_entryD  sR   € ð �Z�Z‹ZÜ'¨¯©Ö6‘
�Ø—8‘8˜sŸv™vÖ%Ø),—M‘M #Ñ&Ø÷	 ‰ZÙ6÷ �Z�ZŠZús   •3A2ÁA2Á&A2Á2B	r×  r¼  c               ó$   € V ^8„  d   QhRRRRRR/# )r6   r×  zOptional[list[str]]r¼  r7   rŸ  r9   )r:   s   "r;   r<   rñ  Q  s/   € ÷ _ñ _ð )ð_ð 0ð	_ð
 
ñ_r=   c          
     	óü  € V P                   ;_uu_ 4        V P                   Uu. uF  q3P                  4       NK  	  pp\        V P                  VVVV P
                  R 7      pVf    RRR4       R# \        P                  ! V4      p\        P                  ! V4      V n        V P                   F©  pVP                  VP                  4      pV P
                  P                  VP                  R4      pVe   \        V4      '       g   K[  WƒP                  VP                  38w  g   Ky  V P                  V\        P!                  V P                  V4      4       K«  	  RRR4       R# u upi   + '       g   i     R# ; i)rÚ  N©NN)rý  r÷  r·   rÜ  rj   rù  r¾   rÇ  Ú_token_pairs_by_idrC   rw   Úanyr|   r~   rS  rv   r¯   )	r�   r×  r¼  rä   r¿  ÚwrittenÚrowsÚrowÚpairs	   &$$      r;   Ú_persistÚCredentialPool._persistQ  s  € ð �Z�Z‹ZØ59·]²]ÓC±]¨EŸ™ž±]ˆHÐCÜ*Ø—‘˜xØ'Ø#5Ø ×7Ñ7ô	ˆGð ŠØ÷ ‰Zô ×&Ò& wÓ/ˆDÜ*2×*EÒ*EÀgÓ*NˆDÔ'ØŸœ�Ø—h‘h˜uŸx™xÓ(�Ø×2Ñ2×6Ñ6°u·x±xÀÓN�ð ’;¤c¨$§i¢iÙð ×.Ñ.°×0CÑ0CÐDÖDØ×'Ñ'¨Ô/?×/IÑ/IÈ$Ï-É-ÐY\Ó/]Ö^ñ '÷ ‰ZùÚC÷ �ZˆZús(   •E*¤E%¼+E*Á1B1E*Ä'4E*Å%E*Å*E;	ÚpersistTc               ó(   € V ^8„  d   QhRRRRRRRR/# )r6   rä   rv   r`  ræ   Úupdatesr   r7   r9   )r:   s   "r;   r<   rñ  q  s+   € ÷ 	ñ 	Ð,ð 	¸$ð 	ÐRUð 	ÐZjñ 	r=   c               ó²   a€ \        V3/ VB oV P                  VS4       V'       d0   V P                  4        V P                  V3R l4      ;'       g    S# S# )zI``replace(entry, **updates)``, swap it into the pool, optionally persist.c                ó6   <€ V P                   SP                   8H  # r�   ©rw   )r0  rÕ  s   &€r;   rM   Ú'CredentialPool._adopt.<locals>.<lambda>y  s   ø€ ¨¯©°·
±
Ò(:r=   )r	   rS  r^  r9  )r�   rä   r`  rb  rÕ  s   &&$,@r;   Ú_adoptÚCredentialPool._adoptq  sM   ø€ ä˜%Ñ+ 7Ñ+ˆØ×Ñ˜E 7Ô+ßØ�M‰MŒOð —:‘:Ô:Ó;×FÐF¸wÐFØˆr=   c               ó$   € V ^8„  d   QhRRRRRR/# )r6   rä   rv   Úsourcesúset[str]r7   rŸ  r9   )r:   s   "r;   r<   rñ  |  s#   € ÷ 3ñ 3Ð)9ð 3ÀHð 3ÐQUñ 3r=   c                ó¸  € V P                   ;_uu_ 4        V P                   Uu. uF!  q3P                  V9   g   K  VP                  NK#  	  ppV P                   Uu. uF  q3P                  V9  g   K  VNK  	  upV n        V P                  VP                  8X  d   RV n        V P                  VR7       RRR4       R# u upi u upi   + '       g   i     R# ; i)zîDrop every entry seeded from *sources* and persist the removal.

Atomic read-modify-write of ``self._entries``: this runs on the
DEFERRED refresh path (outside the pool lock), so take the RLock here;
still-locked callers re-enter safely.
N©r×  )rý  r÷  r{   rw   rø  r^  )r�   rä   rj  Úitemr×  s   &&&  r;   Ú_quarantine_sourcesÚ"CredentialPool._quarantine_sources|  s™   € ð �Z�Z‹ZØ/3¯}ª}ÓW©} tÇÁÈwÑ@Vœ7˜4Ÿ7œ7©}ˆKÐWØ.2¯mªmÓZ©m d¿{¹{ÐRYÑ?YŸT˜T©mÑZˆDŒMØ×Ñ 5§8¡8Ô+Ø#'�Ô Ø�M‰M kˆMÔ2÷ ‰ZùÚWùÚZ÷ �ZˆZús3   •C¤B>»B>ÁCÁCÁ2CÁ8<CÂ>
CÃC	c               ó$   € V ^8„  d   QhRRRRRR/# )r6   Ústatus_coder€   Únormalized_errorrf   r7   ræ   r9   )r:   s   "r;   r<   rñ  Œ  s-   € ÷ Gñ Gà"ðGð )ðGð 
ñ	Gr=   c                óÖ   € VP                  R4      p\        V\        4      '       d   VP                  4       P	                  4       MRpV\
        8X  d   R# VR8H  ;'       d
    V\        9   # )a–  Detect upstream-permanent OAuth failures that won't recover on TTL.

Only 401s whose reason is a known terminal OAuth state count;
token_expired (refreshable) and reason-less 401s (possible glitch)
stay transient, as do 429/402. The one status-independent case is
``CREDENTIAL_PERSIST_FAILED_REASON``: no upstream response is involved,
the rotated pair never became durable and only a re-auth recovers it.
r  r¢   Tr  )rC   rp   rk   r½   rý   Ú CREDENTIAL_PERSIST_FAILED_REASONÚ_TERMINAL_AUTH_REASONS)r�   rr  rs  Ú
raw_reasonr  s   &&&  r;   Ú_is_terminal_auth_failureÚ(CredentialPool._is_terminal_auth_failureŒ  s_   € ð &×)Ñ)¨(Ó3ˆ
Ü/9¸*Äc×/JÒ/J�×!Ñ!Ó#×)Ñ)Ô+ÐPRˆØÔ5Ô5ÙØ˜cÑ!×FÐF fÔ0FÑ&FÐFr=   r_   c               ó0   € V ^8„  d   QhRRRRRRRRR	R
RR/# )r6   rä   rv   rr  r€   r  r  r`  ræ   r_   r}   r7   r9   )r:   s   "r;   r<   rñ  Ÿ  sF   € ÷ !
ñ !
àð!
ð #ð!
ð 0ð	!
ð ð!
ð &ð!
ð 
ñ!
r=   c               	ó°  € \        V4      pVP                  \        8H  ;'       g    V P                  W&4      p\	        VP
                  4      pV'       d   WXR &   MVP                  R R4       T P                  TTV'       d   \        M\        \        P                  ! 4       VVP                  R4      VP                  R4      VP                  R4      VR7	      # )r_   Nr  r  r  )r`  r`   ra   rb   rc   rd   re   r‹   )r!  r`   r#  rx  rÞ   r‹   Úpoprg  r$  r  rC   )	r�   rä   rr  r  r`  r_   rs  ÚterminalÚupdated_extras	   &&&&$$   r;   Ú_mark_exhaustedÚCredentialPool._mark_exhaustedŸ  s¿   € ô 4°MÓBÐð
 ×$Ñ$¬Ñ3×tÐt°t×7UÑ7UÐVaÓ7tˆô ˜UŸ[™[Ó)ˆßØ.<Ð*Ò+à×ÑÐ.°Ô5Ø�{‰{ØØß'/�Ô5EÜŸ9š9›;Ø'Ø.×2Ñ2°8Ó<Ø/×3Ñ3°IÓ>Ø 0× 4Ñ 4°ZÓ @Øð ó 

ð 
	
r=   c               ó    € V ^8„  d   QhRRRR/# ©r6   rä   rv   r7   r9   )r:   s   "r;   r<   rñ  Ê  s   € ÷ ñ ÐAQð ÐVfñ r=   c                óÞ  € V P                   R8w  g   VP                  R8w  d   V#  ^ RIHp V! 4       pV'       g   V# VP	                  RR4      pVP	                  RR4      pV'       g	   V'       dÎ   V'       d   YQP
                  ;'       g    R8w  g#   V'       d¤   YAP                  ;'       g    R8w  dŠ   \        P                  RVP                  4       V P                  ! V3RT;'       g    VP
                  R	T;'       g    VP                  R
VP	                  R^ 4      ;'       g    VP                  /\        B # V#   \         d"   p\        P                  RT4        Rp?T# Rp?ii ; i)zKSync a claude_code entry from ~/.claude/.credentials.json if tokens differ.ro   rá  )Úread_claude_code_credentialsÚrefreshTokenr¢   ÚaccessTokenzDPool entry %s: syncing tokens from credentials file (tokens changed)r|   r~   r„   Ú	expiresAtz(Failed to sync from credentials file: %sN)rj   r{   r¯  r„  rC   r|   r~   r¤  r¥  rw   rg  r„   rg   rD   )r�   rä   r„  ÚcredsÚfile_refreshÚfile_accessr¦  s   &&     r;   Ú+_sync_anthropic_entry_from_credentials_fileÚ:CredentialPool._sync_anthropic_entry_from_credentials_fileÊ  sA  € à�=‰=˜KÔ'¨5¯<©<¸=Ô+HØˆLð	JÝPÙ0Ó2ˆEßØ�Ø Ÿ9™9 ^°RÓ8ˆLØŸ)™) M°2Ó6ˆK÷ Ÿ|ß ×1CÑ1C×1IÐ1IÀrÔ!Jß  \×6IÑ6I×6OÐ6OÈRÔ%Pä—‘ÐcÐej×emÑemÔnØ—{’{Øñà!,×!BÐ!B°×0BÑ0Bðð #/×"EÐ"E°%×2EÑ2Eðð #(§)¡)¨K¸Ó";×"RÐ"R¸u×?RÑ?Rð	ô
 $ñð ð ˆøô ô 	JÜ�L‰LÐCÀS×IÐIØˆûð	JúsW   ¦E  »E  ½+E  Á)E  Á1E  Á9E  ÂE  ÂE  Â.>E  Ã-E  Ä%E  Ä)E  Å E,ÅE'Å'E,c               ó    € V ^8„  d   QhRRRR/# r‚  r9   )r:   s   "r;   r<   rñ  è  s   € ÷ .ñ .Ð1Að .ÐFVñ .r=   c                ó\  a€ V P                   R
9  d   \        V P                   4      f   S# V P                   R8H  pV P                   R8H  pRRRR/P                  V P                   V P                   4      pV'       d)   \        SP                  V P                   4      '       d   S#  \        V3R l\        V P                   4       4       R4      p\        V\        4      '       g   S# \        P                  ! V4      V P                  SP                  &   \        P                  V P                   V4      pV'       gW   VP                  ;'       g    RP!                  4       '       g-   VP"                  ;'       g    RP!                  4       '       g   S# VP                  SP                  8w  g   VP"                  SP"                  8w  d6   \$        P'                  RSP                  V4       V P)                  SV4       V#  S#   \*         d"   p\$        P'                  R	YG4        Rp?S# Rp?ii ; i)uì  Adopt a token pair rotated by another pool instance (anthropic, xai-oauth).

Re-reads the exact persisted row from the credential-pool store while
the shared cross-process auth-store lock is held. Direct integrations
load a fresh ``CredentialPool`` per request, so in-memory locks cannot
protect a single-use refresh token across requests or processes.

Anthropic borrowed sources (``claude_code``) are excluded: they are
reference-only rows whose secrets are stripped before reaching
auth.json, so re-reading yields empty tokens that would be adopted as
a "rotation" â€” blanking a usable credential. The singleton file, not
the pool store, is token authority for those sources; a row with no
token material at all is refused for the same reason.
ro   rÝ  NÚ	AnthropicÚxAIc              3  óœ   <"  € T FA  p\        V\        4      '       g   K  VP                  R 4      SP                  8X  g   K=  Vx € KC  	  R# 5i©rw   N©rp   rÞ   rC   rw   ©ró   Úprä   s   & €r;   rô   Ú=CredentialPool._sync_entry_from_pool_store.<locals>.<genexpr>   s<   øé € ÐsÑ?�qÄ:ÈaÔQU×CV”Ð[\×[`Ñ[`ÐaeÓ[fÐjo×jrÑjrÑ[r—’Ó?ùó   ƒA AÁ
Ar¢   zHPool entry %s: adopting %s OAuth tokens rotated by another pool instancez6Failed to sync %s OAuth entry from credential pool: %s)ro   rÝ  )rj   r   rC   r    r{   ra  r3   rp   rÞ   r¾   Ú_credential_token_pairrù  rw   rv   r¯   r|   r½   r~   r¤  r¥  rS  rD   )r�   rä   Úis_anthropicÚis_xaiÚdisplayÚ	persistedÚstoredr¦  s   &f      r;   Ú_sync_entry_from_pool_storeÚ*CredentialPool._sync_entry_from_pool_storeè  sÌ  ø€ ð �=‰=Ð :Ô:Ô?RÐSW×S`ÑS`Ó?aÒ?iØˆLØ—}‘}¨Ñ3ˆØ—‘ +Ñ-ˆØ ¨[¸%Ð@×DÑDÀTÇ]Á]ÐTX×TaÑTaÓbˆßÔ9¸%¿,¹,ÈÏÉ×VÒVØˆLð	aÜÜsÔ0°·±Ô?ÓsØóˆIô ˜i¬×.Ò.Ø�ô 5=×4SÒ4SÐT]Ó4^ˆD×'Ñ'¨¯©Ñ1Ü%×/Ñ/°·±¸yÓIˆF÷  6×#6Ñ#6×#<Ð#<¸"×"CÑ"C×"EÒ"EÈv×OcÑOc×OiÐOiÐgi×NpÑNp×NrÒNrØ�Ø×"Ñ" e×&8Ñ&8Ô8¸F×<PÑ<PÐTY×TgÑTgÔ<gÜ—‘Ø^Ø—H‘H˜gôð ×#Ñ# E¨6Ô2Ø�ð =hð ˆøô ô 	aÜ�L‰LÐQÐSZ×`Ð`Øˆûð	aúsE   Â%A G? Ã&AG? Ä;G? ÅG? Å%G? Å8G? ÆG? ÆA*G? Ç?H+È
H&È&H+c               ó    € V ^8„  d   QhRRRR/# r‚  r9   )r:   s   "r;   r<   rñ    s    € ÷ Nñ NÐ1Að NÐFVñ Nr=   c                óú  € \         P                  V P                  4      pVf   V# V^ ,          pV P                  R8H  pV'       d   RMRpVP                  V9  d   V#  \	        4       ;_uu_ 4        \        \        4       V P                  4      pRRR4       \        X\        4      '       d   VP                  R4      MRp\        V\        4      '       g   V# V'       d   \        W4      '       g   V# VP                  RR4      pVP                  RR4      p	VP                  ;'       g    Rp
\        V4      ;'       d/    Y�P                  ;'       g    R8g  ;'       g    T	;'       d    Wš8g  pV'       gA   V'       d9   V	'       d1   Wš8w  d+   V'       g#   \        P                  RVP                  4       RpV'       dg   \!        Wa4      '       dV   \        P                  R	VP                  \        V\        4      '       d   VP                  R
4      MRVP"                  4       RpV'       dŒ   \        P%                  RVP                  V4       RT;'       g    VP                  RT	;'       g    VP                  /\&        CpVP                  R
4      '       d   VR
,          VR
&   V P(                  ! V3/ VB #  V#   + '       g   i     EL4; i  \*         d"   p\        P%                  RY=4        Rp?T# Rp?ii ; i)uÀ  Sync a Codex / xAI device_code entry from auth.json ``providers.<id>.tokens``.

A fresh ``hermes model`` / ``hermes auth`` login writes new tokens
under ``_auth_store_lock`` while the pool entry may sit frozen behind
a ``last_error_reset_at`` hours in the future; without this sync every
request fails with "no available entries" despite fresh credentials on
disk. Only singleton-seeded entries apply â€” env/API-key rows have no
auth.json shadow.
NrÄ   Útokensr|   r¢   r~   z~Pool entry %s: auth.json has newer refresh_token but no access_token; adopting refresh_token to avoid replaying consumed tokenTzšPool entry %s: auth.json singleton predates this entry's rotation (last_refresh %s < %s); keeping pool chain to avoid replaying the consumed refresh tokenr…   FzNPool entry %s: syncing %s tokens from auth.json (refreshed by another process)z*Failed to sync %s entry from auth.json: %s)rè   úmanual:device_code)rè   )rÞ  rC   rj   r{   r&   r+   r*   rp   rÞ   rë   r~   ræ   r|   r¤  Úinforw   r  r…   r¥  rg   rg  rD   )r�   rä   Úspecr›  Úis_codexrj  r  r¢  Ústore_accessÚstore_refreshÚentry_refreshÚshould_adoptÚfield_updatesr¦  s   &&            r;   Ú_sync_entry_from_auth_storeÚ*CredentialPool._sync_entry_from_auth_store  s�  € ô +×.Ñ.¨t¯}©}Ó=ˆØŠ<ØˆLØ�q•'ˆØ—=‘= NÑ2ˆß;CÑ7ÐIYˆØ�<‰<˜wÔ&ØˆLð;	UÜ!×#Õ#Ü,Ô-=Ó-?ÀÇÁÓO�÷ $ä,6°u¼d×,CÒ,C�U—Y‘Y˜xÔ(ÈˆFÜ˜f¤d×+Ò+Ø�ßÔ =¸e× LÒ LØ�Ø!Ÿ:™: n°bÓ9ˆLØ"ŸJ™J ¸Ó;ˆMØ!×/Ñ/×5Ð5°2ˆMô   Ó-÷ ð Ø×!3Ñ!3×!9Ð!9°rÑ:÷ Fð FØ!×DÐD mÑ&Dð ÷  §H·À=ÔCa×jvô —‘ð5ð —H‘Hô	ð  $�ßÔ 9¸%× GÒ Gô —‘ðAð —H‘HÜ1;¸EÄ4×1HÒ1H�E—I‘I˜nÔ-ÈdØ×&Ñ&ôð  %�ßÜ—‘ØdØ—H‘H˜gôð
 # L×$FÐ$F°E×4FÑ4FØ# ]×%IÐ%I°e×6IÑ6Ið1ô $ð1�ð
 —9‘9˜^×,Ò,Ø49¸.Õ4I�M .Ñ1Ø—{’{ 5Ñ:¨MÑ:Ð:ð ð ˆ÷w $×#Ð#ûôr ô 	UÜ�L‰LÐEÀw×TÐTØˆûð	Uús˜   ÁK Á0J:ÂAK ÃK Ã K Ã36K Ä*K Ä?K ÅK Å	K Å)K Å6K Å>K ÆK Æ)K Æ>A-K È,*K ÉK É-*K ÊK Ê:K	Ë	K ËK:ËK5Ë5K:c               ó    € V ^8„  d   QhRRRR/# r‚  r9   )r:   s   "r;   r<   rñ  j  s   € ÷ !ñ !Ð6Fð !ÐK[ñ !r=   c                ó  a€ V P                   R8w  g   SP                  R8w  d   S#  \        4       ;_uu_ 4        \        \	        4       R4      pRRR4       X'       g   S# R
 Uu/ uF  pW2P                  V4      bK  	  pp\        ;QJ d-    V3R lVP                  4        4       F  '       g   K   RM"	  RM! V3R lVP                  4        4       4      '       g   S# \        P                  RSP                  4       \        \        4      pTP                  VP                  4        UUu/ uF  w  rgV'       g   K  WgbK  	  upp4       \        SP                  4      pTP                  \         Uu/ uF   qbP                  V4      f   K  WbV,          bK"  	  up4       V P                   ! S3RV/VB #   + '       g   i     ELo; iu upi u uppi u upi   \"         d"   p	\        P                  R	T	4        Rp	?	S# Rp	?	ii ; i)a  Sync a Nous device_code entry from auth.json ``providers.nous`` if state differs.

Another process refreshing via ``resolve_nous_runtime_credentials``
writes fresh tokens under ``_auth_store_lock``; adopting them avoids a
"refresh token reuse" revocation on the Nous Portal.
r»   rè   Nc              3  ób   <"  € T F$  w  rVR9  ;'       d    \        SVR 4      V8g  x € K&  	  R # 5i)N)Nr¢   )r³   )ró   r¬   r®   rä   s   &  €r;   rô   ÚBCredentialPool._sync_nous_entry_from_auth_store.<locals>.<genexpr>  s5   øé € ÐkÑXjÑPTÐPQ�q 
Ñ*×KÐK¬w°u¸aÀÓ/FÈ!Ñ/KÔKÓXjùs   ƒ,/TFz0Pool entry %s: syncing Nous state from auth.jsonr‹   z,Failed to sync Nous entry from auth.json: %s)r|   r~   rƒ   r‡   rˆ   r†   )rj   r{   r&   r+   r*   rC   rY  r£   r¤  r¥  rw   rÞ   rg   Úupdater‹   Ú_NOUS_EXTRA_STATE_KEYSrg  rD   )
r�   rä   r  rØ   Ú
comparabler«  r¬   r®   Úextra_updatesr¦  s
   &f        r;   Ú _sync_nous_entry_from_auth_storeÚ/CredentialPool._sync_nous_entry_from_auth_storej  s©  ø€ ð �=‰=˜FÔ" e§l¡l°mÔ&CØˆLð	NÜ!×#Õ#Ü,Ô-=Ó-?ÀÓH�÷ $çØ�ñóñ�Cð —Y‘Y˜s“^Ò#ñð ð ÷ “3ÔkÐXb×XhÑXhÔXjÓk—3—3’3ÔkÐXb×XhÑXhÔXjÓk×kÒkØ�Ü�L‰LÐKÈUÏXÉXÔVÜ,0´Ó,?ˆMØ× Ñ °:×3CÑ3CÔ3EÔ!KÑ3E©4¨1Ì¤$ !¢$Ñ3EÒ!KÔLÜ  §¡Ó-ˆMØ× Ñ Ý&<ÓYÑ&< Ç	Á	È!Ã”�˜!•H’Ñ&<ÑYôð —;’;˜uÑK¨MÐK¸]ÑKÐK÷) $×#Ð#üòùó "Lùò Zøô ô 	NÜ�L‰LÐGÈ×MÐMØˆûð	Nús}   §G ¹F4ÁG ÁG Á G Á$GÁ>/G Â0+G ÃG ÃAG Ä+G
Ä<G
Å0G Å2GÆGÆG Æ4G	Æ?G ÇHÇ#G?Ç?Hc               ó    € V ^8„  d   QhRRRR/# )r6   rä   rv   r7   rŸ  r9   )r:   s   "r;   r<   rñ  �  s    € ÷ )dñ )dÐ;Kð )dÐPTñ )dr=   c           	     óê  € VP                   R8w  g   V P                  R.\        O59  d   R#  \        4       ;_uu_ 4        \	        4       p\        W P                  4      w  r4\        V\        4      '       g    RRR4       R# \        4       p\        VRJ;'       d    VRJ;'       d    \        WE4      4      pV P                  W4      '       g    RRR4       R# V'       d   \        V P                  V4       M#\        W P                  VRR7       \        V4       RRR4       R#   + '       g   i     R# ; i  \         d-   p\         P#                  RT P                  T4        Rp?R# Rp?ii ; i)u³  Write refreshed pool entry tokens back to auth.json ``providers.<id>``.

Otherwise the next ``load_pool()`` re-seeds the stale singleton state
over the fresh entry â€” potentially a consumed single-use refresh
token. Applies to Nous, OpenAI Codex and xAI OAuth singletons.

``set_active=False`` everywhere: a sync-back is a token-rotation side
effect, not the user choosing a provider; ``_save_provider_state``
would flip ``active_provider`` to whichever provider refreshed last.

#74339: decide the root write-through on WHERE the state resolved
from (``_load_provider_state_with_source``), not on whether the
profile has a ``providers.<id>`` key â€” ``_store_provider_state``
creates that key unconditionally, which self-sealed the check after
the first refresh. When the grant came from the global root, write
back to root ONLY and skip the profile store so it never accrues a
shadowing key that blocks both the fallback and the write-through.
rè   r»   NFr¡  z3Failed to sync %s pool entry back to auth store: %s)r{   rj   rÞ  r&   r*   r,   rp   rÞ   r)   ræ   r/   Ú_apply_entry_to_singleton_stater§  r2   r0   rD   r¤  r¥  )r�   rä   r²  r  Úsource_pathÚglobal_rootÚis_from_rootr¦  s   &&      r;   Ú%_sync_device_code_entry_to_auth_storeÚ4CredentialPool._sync_device_code_entry_to_auth_store�  s)  € ð* �<‰<˜=Ô(¨D¯M©MÀ&ÐAgÔKfÑAgÔ,gÙð	dÜ!×#Õ#Ü-Ó/�
Ü%EÀj×R_ÑR_Ó%`Ñ"�Ü! %¬×.Ò.Ø÷	 $Ñ#ô
 5Ó6�Ü#Ø tÐ+×pÐp°À4Ð0G×pÐpÌJÐWbÓLpó �ð ×;Ñ;¸E×IÒIØ÷ $Ñ#÷  Ü@ÀÇÁÐPUÕVä)¨*·m±mÀUÐW\Õ]Ü$ ZÔ0÷ $×#×#Ò#ûô  ô 	dÜ�L‰LÐNÐPT×P]ÑP]Ð_b×cÒcûð	dús_   ®D; Á 9D'Á9D; ÂD'ÂD'Â)(D'ÃD; ÃD'Ã#:D'ÄD; Ä'D8	Ä2D; Ä8D; Ä;E2Å!E-Å-E2c               ó$   € V ^8„  d   QhRRRRRR/# )r6   rä   rv   r  rf   r7   ræ   r9   )r:   s   "r;   r<   rñ  ¸  s#   € ÷ ñ Ð5Eð Ènð Ðaeñ r=   c                ó6  € V P                   R8X  dŽ   VP                  VR&   R	 F#  p\        W4      '       g   K  \        W4      W#&   K%  	  \         F(  pVP                  P                  V4      pVf   K$  WRV&   K*  	  VP                  '       d   VP                  VR&   R# VP                  R4      p\        V\        4      '       g   R# VP                  VR&   VP                  '       d   VP                  VR&   VP                  '       d   VP                  VR&   R# )
zGCopy *entry*'s tokens into the provider's auth.json ``state`` in place.r»   r|   r~   r†   Tr¢  Fr…   )r~   rƒ   r‡   rˆ   )rj   r|   r³   r³  r‹   rC   r†   rp   rÞ   r~   r…   )r�   rä   r  rØ   Ú	extra_keyÚvalr¢  s   &&&    r;   rº  Ú.CredentialPool._apply_entry_to_singleton_state¸  sö   € à�=‰=˜FÔ"Ø$)×$6Ñ$6ˆE�.Ñ!Û[�Ü˜5×&Ô&Ü!(¨Ó!4�E“Jñ \÷ 4�	Ø—k‘k—o‘o iÓ0�Ø”?Ø'*˜)Ó$ñ 4ð ×'×'Ð'Ø.3×.FÑ.F�Ð*Ñ+ÙØ—‘˜8Ó$ˆÜ˜&¤$×'Ò'ÙØ!&×!3Ñ!3ˆˆ~ÑØ××ÐØ&+×&9Ñ&9ˆF�?Ñ#Ø××ÐØ$)×$6Ñ$6ˆE�.Ñ!Ùr=   c               ó$   € V ^8„  d   QhRRRRRR/# ©r6   rä   rv   Úforceræ   r7   rå  r9   )r:   s   "r;   r<   rñ  Ò  s(   € ÷ *Añ *AÐ$4ð *AÀð *AÐIcñ *Ar=   c          	     	ó˜  € VP                   \        8w  g   VP                  '       g   V'       d   V P                  VR 4       R # V P                  \
        9  d*   \        V P                  4      f   V P                  WR7      # \        V P                  4       R7      ;_uu_ 4        V P                  R8X  d^   V P                  V4      pW1Jd,   V'       g$   V P                  V4      '       g   VuuR R R 4       # V P                  W2R7      uuR R R 4       # V P                  V4      pV P                  R8X  d“   VP                  R8X  d‚   V P                  4       ;_uu_ 4        V P                  V4      pVP                  VP                  8w  d   VuuR R R 4       uuR R R 4       # V P                  W2R7      uuR R R 4       uuR R R 4       # VP                   VP                   8w  g   VP                  VP                  8w  d   VuuR R R 4       # V P                  W2R7      uuR R R 4       #   + '       g   i     Ln; i  + '       g   i     R # ; i)N©rÇ  )Útimeout_secondsrÄ   ro   rá  )rm   rr   r~   r  rj   Ú_SINGLE_USE_REFRESH_PROVIDERSr   Ú_refresh_entry_implr&   Ú _single_use_refresh_lock_timeoutr¬  Ú_entry_needs_refreshrž  r{   Ú_claude_code_credentials_lockr‹  r|   )r�   rä   rÇ  Úsynceds   &&$ r;   Ú_refresh_entryÚCredentialPool._refresh_entryÒ  sÕ  € Ø�?‰?œoÔ-°U×5H×5HÐ5HßØ×$Ñ$ U¨DÔ1Ùð �=‰=Ô =Ô=ÔBUÐVZ×VcÑVcÓBdÒBlØ×+Ñ+¨EÐ+Ó?Ð?ô ¨d×.SÑ.SÓ.U×VÖVØ�}‰} Ô.Ø×9Ñ9¸%Ó@�ØÓ&¯u¸T×=VÑ=VÐW]×=^Ò=^Ø!÷	 WÒVð
 ×/Ñ/°Ð/ÓD÷ WÒVð ×5Ñ5°eÓ<ˆFØ�}‰} Ô+°·±ÀÔ0Nð ×7Ñ7×9Õ9Ø!×MÑMÈfÓU�FØ×+Ñ+¨u×/BÑ/BÔBØ%÷ :Ñ9÷# WÒVð*  ×3Ñ3°FÐ3ÓH÷	 :Ñ9÷# WÒVð, ×"Ñ" e×&8Ñ&8Ô8¸F×<PÑ<PÐTY×TgÑTgÔ<gØ÷/ WÒVð0 ×+Ñ+¨FÐ+Ó@÷1 WÒV÷" :×9ú÷# W×VÐVúsU   Â$/H8ÃH8Ã+H8Ã7H8ÄAH8Å.H%	Æ
H8Æ!H%	Æ2
H8Ç7H8È	H8È%H5È0H8È8I		c                óN   € ^ RI Hp \        V P                  4       V! 4       R7      # )zÊCross-process lock keyed to the shared claude_code credentials file.

Unlike the per-profile ``_auth_store_lock()`` this serializes every
profile and process that might refresh a ``claude_code`` entry.
)Úclaude_code_credentials_path)rÊ  rÄ  )r¯  rÔ  r&   rÍ  )r�   rÔ  s   & r;   rÏ  Ú,CredentialPool._claude_code_credentials_lockþ  s'   € õ 	MäØ ×AÑAÓCÙ4Ó6ô
ð 	
r=   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r6   rä   rv   r¦  ÚBaseExceptionrÉ  rk   r7   rŸ  r9   )r:   s   "r;   r<   rñ    s2   € ÷ 1
ñ 1
àð1
ð ð1
ð
 ð1
ð 
ñ1
r=   c               óJ  € \         P                  RVP                  W24        ^ RIHpHp V! VP                  VP                  V! VP                  4      R7       V P                  VRR\        R	R
V RV 2/4       R#   \         d    \         P                  RRR7        LGi ; i)uS  Quarantine an entry whose rotated pair never reached its store.

For ``claude_code`` / ``hermes_pkce`` the singleton file â€” not
auth.json â€” is authoritative: ``_seed_from_singletons()`` re-reads it
on every ``load_pool()``. When the refresh POST succeeded but the
singleton write failed, the replacement pair exists only in memory
while the consumed pair survives on disk and would be re-seeded over
any row we persisted; the next refresh would replay the spent token.
So never expose or persist the rotated pair; mark the entry terminally
so it surfaces as an explicit re-auth requirement.
u£   Anthropic %s refresh rotated the single-use token but could not commit it to %s (%s) â€” failing closed and quarantining the credential; re-authenticate to recover)Ú"mark_rotation_consumed_uncommittedÚspent_rotation_source_path©r»  z/Failed to record consumed rotation fingerprintsT©Úexc_infoNr  r  z.rotated credential was not durably written to z: )r¤  Úerrorr{   r¯  rÙ  rÚ  r|   r~   rD   r¥  r  ru  )r�   rä   r¦  rÉ  rÙ  rÚ  s   &&&$  r;   Ú!_fail_closed_unpersisted_rotationÚ0CredentialPool._fail_closed_unpersisted_rotation  s¯   € ô$ 	�‰ð)ð �L‰L˜%ô		
ð	[÷ñ /Ø×"Ñ"Ø×#Ñ#Ù6°u·|±|ÓDõð 	×ÑØØàÔ:ØÐKÈEÈ7ÐRTÐUXÐTYÐZðö	
øô ô 	[Ü�L‰LÐJÐUYˆLÖZð	[ús   £7A= Á="B"Â!B"c               ó   € V ^8„  d   QhRR/# )r6   r7   Úfloatr9   )r:   s   "r;   r<   rñ  >  s   € ÷ dñ d°%ñ dr=   c                óÖ   € \         P                  V P                  R4      p\        P                  ! V^4      p\        \        \        P                  4      \        V4      R,           4      # )z^Configured refresh POST timeout plus margin, so a slow token endpoint cannot starve the flock.Ú(HERMES_ANTHROPIC_REFRESH_TIMEOUT_SECONDSg      @)Ú_REFRESH_TIMEOUT_ENV_VARSrC   rj   r¾   Ú	env_floatrø   râ  ÚAUTH_LOCK_TIMEOUT_SECONDS)r�   Úenv_varÚrefresh_timeout_secondss   &  r;   rÍ  Ú/CredentialPool._single_use_refresh_lock_timeout>  sP   € ä+×/Ñ/°·±Ð?iÓjˆÜ"*×"4Ò"4°W¸bÓ"AÐÜ”5œ×;Ñ;Ó<¼eÐD[Ó>\Ð_bÕ>bÓcÐcr=   c               ó$   € V ^8„  d   QhRRRRRR/# )r6   rä   rv   Ú	refreshedrf   r7   rŸ  r9   )r:   s   "r;   r<   rñ  D  s)   € ÷ añ aØ%ðaØ2@ðaà	ñar=   c           	     ó¢  € VP                   R8X  d   RpMVP                   R8X  d   RpMR#  ^ RIHp VR,          VR,          VR	,          3pVP                   R8X  d)   VP                  ! TR
VP                  ;'       g    R/  R# VP
                  ! VR\        W4      /  R#   \         d"   p\        T P                  YTR7      4      hRp?ii ; i)añ  Write a rotated Anthropic pair to its authoritative singleton, or fail closed.

claude_code -> ~/.claude/.credentials.json (so the fallback resolver
and other profiles see it). hermes_pkce -> ~/.hermes/.anthropic_oauth.json
(``_seed_from_singletons`` re-seeds it every load; a borrowed row commits
to the ROOT's file, never a new profile-local copy, #100339). Not
``endswith``: manual:hermes_pkce is pool-owned and a singleton for it
would be a second authority for the same refresh-token family.
rá  z~/.claude/.credentials.jsonr¬  z~/.hermes/.anthropic_oauth.jsonN)Úanthropic_credentialsr|   r~   r„   Úspent_refresh_tokenr¢   Útarget©rÉ  )
r{   Úagentrî  Ú_write_claude_code_credentialsr~   Ú_write_hermes_oauth_credentialsr°  rD   rã  rß  )r�   rä   rì  rÉ  ÚacÚargsÚwexcs   &&&    r;   Ú_commit_anthropic_rotationÚ)CredentialPool._commit_anthropic_rotationD  sÆ   € ð �<‰<˜=Ô(Ø1‰EØ�\‰\˜]Ô*Ø5‰Eáð	aÝ9Ø˜nÕ-¨y¸Õ/IÈ9ÐUdÕKeÐfˆDØ�|‰|˜}Ô,Ø×1Ò1°4ÐgÈU×M`ÑM`×MfÐMfÐdfÔgà×2Ò2°DÐjÔA\Ð]aÓAiÔjøÜô 	aô ˜t×EÑEÀeÐY^ÐEÓ_Ó`Ð`ûð		aús$   ¬AB" Á>B" ÂB" Â"CÂ-C	Ã	Cc               ó    € V ^8„  d   QhRRRR/# r‚  r9   )r:   s   "r;   r<   rñ  c  s   € ÷ ñ Ð(8ð Ð=Mñ r=   c           
     óÜ  € ^ RI HpHpHp V! VP                  4      pV! VP
                  VR7      '       g   V! VP                  VR7      '       d:   \        T P                  T\        R4      \        T;'       g    R4      R7      4      hV! VP
                  VP                  P                  R4      R7      p\        VVR,          VR	,          VR
,          R7      pV P                  W4       V# )z\POST the Anthropic refresh, commit to the singleton, return the rotated (unpersisted) entry.)Ú is_rotation_consumed_uncommittedÚrefresh_anthropic_oauth_purerÚ  rÛ  zpcredential pair was rotated by another process but the rotation never committed (spent-rotation sidecar verdict)zcredential storerñ  r¬  ©Úuse_jsonr|   r~   r„   )r|   r~   r„   )r¯  rü  rý  rÚ  r{   r~   r|   rã  rß  ÚRuntimeErrorrk   Úendswithr	   rø  )r�   rä   rü  rý  rÚ  r»  rì  rÕ  s   &&      r;   Ú_refresh_anthropicÚ!CredentialPool._refresh_anthropicc  sä   € ÷	
ñ 	
ñ 1°·±Ó>ˆÙ+¨E×,?Ñ,?È[×YÓYÙ,¨U×-?Ñ-?È[×YÓYä˜t×EÑEØÜðPóô ˜+×;Ð;Ð);Ó<ð  Fó  ó ð ñ 1°×1DÑ1DÈuÏ|É|×OdÑOdÐerÓOsÔtˆ	ÜØØ" >Õ2Ø# OÕ4Ø# OÕ4ô	
ˆð 	×'Ñ'¨Ô9Øˆr=   c               ó    € V ^8„  d   QhRRRR/# r‚  r9   )r:   s   "r;   r<   rñ  ƒ  s   € ÷ 	
ñ 	
Ð*:ð 	
Ð?Oñ 	
r=   c                óì   € \         V P                  ,          ^,          p\        \        V4      ! VP                  VP
                  4      p\        VVR,          VR,          VP                  R4      R7      # )zICodex / xAI: POST the refresh and return the rotated (unpersisted) entry.r|   r~   r…   ©r|   r~   r…   )rÞ  rj   r³   r¾   r|   r~   r	   rC   )r�   rä   Úrefresh_fn_namerì  s   &&  r;   Ú_post_tokens_refreshÚ#CredentialPool._post_tokens_refreshƒ  s`   € ä5°d·m±mÕDÀQÕGˆÜœH oÔ6°u×7IÑ7IÈ5×K^ÑK^Ó_ˆ	ÜØØ" >Õ2Ø# OÕ4Ø"Ÿ™ ~Ó6ô	
ð 	
r=   c               ó$   € V ^8„  d   QhRRRRRR/# rÆ  r9   )r:   s   "r;   r<   rñ  Ž  s#   € ÷ .ñ .Ð)9ð .ÀTð .ÐNhñ .r=   c               	ó†  €  V P                   R 8X  d   V P                  V4      pEMXV P                   \        9   d%   V P                  V4      pV P	                  V4      pEM\        V P                   4      ;pe(   V! V4      pV'       g   \        R4      h\        W4      pMßV P                   R8X  dÍ   VP                  ;'       g!    VP                  ;'       g    VP                  pV P                  V4      pWqJdP   TpV'       dF   VP                  '       d4   VP                  V8w  d#   \        P                  RVP                  4       V# \        P                   ! Y&;'       g    RR7       V P                  V4      pMV# \+        V3/ \,        B pV P/                  W4       V P1                  VP                  .R7       V P3                  V4       V#   \"         d   pTP$                  u Rp?# Rp?i\&         dH   p	\        P                  RT P                   TP                  T	4       T P)                  Y4      u Rp	?	# Rp	?	ii ; i)ro   Nz6provider refresh_credential returned no rotated fieldsr»   z<Nous entry %s: adopting peer-rotated token, skipping refresh)Úforce_refreshÚstale_access_tokenz'Credential refresh failed for %s/%s: %s)r¼  )rj   r  rÞ  r¬  r  r   r   r   rÀ   r‡   r|   r¶  r¤  r¥  rw   r¾   Ú resolve_nous_runtime_credentialsrã  r´   rD   Ú_recover_failed_refreshr	   rh   rS  r^  r¾  )
r�   rä   rÇ  rÕ  Úplugin_refreshÚrotatedÚ	stale_keyrÐ  Údoner¦  s
   &&$       r;   rÌ  Ú"CredentialPool._refresh_entry_implŽ  sÙ  € ð	<Ø�}‰} Ô+Ø×1Ñ1°%Ó8’Ø—‘Ô"=Ô=Ø×8Ñ8¸Ó?�Ø×3Ñ3°EÓ:’Ü$7¸¿¹Ó$FÐF�.ÒSÙ(¨Ó/�ßô 'Ð'_Ó`Ð`Ü5°eÓE‘Ø—‘ &Ô(Ø!×1Ñ1×ZÐZ°U·_±_×ZÐZÈ×HZÑHZ�	Ø×>Ñ>¸uÓE�ØÓ&Ø"�E÷  ×!6×!6Ð!6¸5×;PÑ;PÐT]Ô;]ÜŸ™Ð%cÐej×emÑemÔnØ$˜Ü×9Ò9È×bsÐbsÐosÕtØ×?Ñ?ÀÓF‘à�ô ˜'Ñ.¤XÑ.ˆØ×Ñ˜EÔ+ð 	�‰¨'¯*©*¨ˆÔ6ð 	×2Ñ2°7Ô;Øˆøô ô 	Ø—;‘;ÕûÜô 	<Ü�L‰LÐBÀDÇMÁMÐSX×S[ÑS[Ð]`ÔaØ×/Ñ/°Ó;Õ;ûð	<úsv   ‚"G ¦7G Á(G ÂG Â#G ÃG Ã,G ÄG Ä2G Å	G Å"G Å<G ÇI ÇG+Ç%I Ç+I Ç8I Ç9<H;È5I È;I c               ó$   € V ^8„  d   QhRRRRRR/# )r6   rä   rv   r¦  rD   r7   rå  r9   )r:   s   "r;   r<   rñ  ¾  s(   € ÷ iñ iÐ-=ð iÀIð iÐRlñ ir=   c           
     ó	  € V P                   R8X  Edµ   VP                  R8X  dç   V P                  V4      pVP                  VP                  8w  dŒ   \        P                  R4        ^ RIHp V! VP                  VP                  P                  R4      R7      pV P                  W54       V P                  VVR,          VR,          VR	,          \        R
R
R7      # V P                  V4      '       g   \        P                  R4       V# MXV P!                  V4      pVP                  VP                  8w  d-   \        P                  R4       V P                  ! V3/ \"        B # ^ RIHp V! V4      '       dP   \        P'                  RVP(                  ;'       g    VP*                  R,          V4       V P-                  W4       R
# EMaV P                   \.        9   dê   \.        V P                   ,          w  ršr›V P1                  V4      pVP                  VP                  8w  d.   \        P                  RV
4       V P                  ! V3/ \"        B # \3        \4        V4      ! V4      '       dY   \        P'                  RW¢V P                   4       V P7                  W4       V P9                  VR04       V P-                  W4       R
# EMcV P                   R8X  Ed#   V P;                  V4      pVP                  VP                  8w  d@   \        P                  R4       V P                  ! V3/ \"        B pV P=                  V4       V# \?        V\@        4      '       d   \        P                  R4       V# \4        PB                  ! V4      '       dn   \        P'                  RV4       V PE                  W4       V P9                  V\4        PF                  R\4        PF                   204       V P-                  W4       R
# M/\I        V P                   4      e   \K        WV4      w  rÞV'       d   V# V PM                  VR
4       R
#   \         d   pTP                  u R
p?# R
p?i\         d"   p\        P                  RT4        R
p?EL R
p?ii ; i)a  After a failed refresh POST: adopt a peer's rotation, quarantine a dead grant, or bench.

Another process may have consumed the refresh token between our
pre-POST sync and the HTTP call; re-read the provider's token
authority once more and adopt fresher tokens before giving up.
ro   rá  z8Retrying refresh with synced token from credentials file)rý  r¬  rþ  r|   r~   r„   N)r|   r~   r„   r`   ra   rb   zRetry refresh also failed: %sz7Credentials file has valid token, using without refreshuK   Anthropic OAuth refresh failed but pool store has newer tokens â€” adopting)Ú#is_terminal_anthropic_refresh_errorz•Anthropic OAuth refresh token for %s is terminally invalid (%s); the credential leaves rotation. Re-run 'hermes auth add anthropic' to sign in again.ºNé   NuC   %s OAuth refresh failed but auth.json has newer tokens â€” adoptingz|%s OAuth refresh token is terminally invalid (%s); clearing local token state. Re-run 'hermes auth add %s' to sign in again.rè   r»   u?   Nous refresh failed but auth.json has newer tokens â€” adoptingz>Nous refresh skipped: auth store lock busy; not benching entryzzNous refresh token is terminally invalid (%s); clearing local token state. Re-run 'hermes auth add nous' to sign in again.zmanual:)'rj   r{   r‹  r~   r¤  r¥  r¯  rý  r  rø  rg  Ú	STATUS_OKrã  r´   rD   rÎ  rž  rh   r  rÛ  rx   rw   Ú_mark_dead_refresh_grantrÞ  r¬  r³   r¾   Ú_clear_terminal_tokens_statero  r¶  r¾  rp   ÚTimeoutErrorÚ_is_terminal_nous_refresh_errorÚ_clear_terminal_nous_stateÚNOUS_DEVICE_CODE_SOURCEr   r   r  )r�   rä   r¦  rÐ  rý  rì  r  Ú	retry_excr  Ú_r›  Úterminal_fn_namerÕ  Úhandledr´   s   &&&            r;   r  Ú&CredentialPool._recover_failed_refresh¾  s×  € ð �=‰=˜KÕ'Ø�|‰|˜}Ô,Ø×IÑIÈ%ÓP�Ø×'Ñ'¨5×+>Ñ+>Ô>Ü—L‘LÐ![Ô\ðQÝ\Ù$@Ø"×0Ñ0¸6¿=¹=×;QÑ;QÐR_Ó;`ô%˜	ð ×7Ñ7¸ÔJØ#Ÿ{™{Ø"Ø)2°>Õ)BØ*3°OÕ*DØ*3°OÕ*DÜ(1Ø+/Ø,0ð  +ó  ð ð ×2Ñ2°6×:Ò:Ü—L‘LÐ!ZÔ[Ø!�Mð ;ð ×9Ñ9¸%Ó@�Ø×'Ñ'¨5×+>Ñ+>Ô>Ü—L‘LÐ!nÔoØŸ;š; vÑ:´Ñ:Ð:ÝWÙ2°3×7Ò7ô —‘ð\à—K‘K×/Ð/ 5§8¡8¨B¥<°ô6ð ×-Ñ-¨eÔ9Ùñ 8ð �]‰]Ô9Ô9Ü.IÈ$Ï-É-Õ.XÑ+ˆA˜Ø×5Ñ5°eÓ<ˆFØ×#Ñ# u×':Ñ':Ô:Ü—‘ÐbÐdkÔlØ—{’{ 6Ñ6¬XÑ6Ð6ô
 ”xÐ!1Ô2°3×7Ò7ô —‘ðDØELÐSW×S`ÑS`ôbð ×1Ñ1°%Ô=Ø×(Ñ(¨°°Ô@Ø×-Ñ-¨eÔ9Ùñ 8ð �]‰]˜fÕ$Ø×:Ñ:¸5ÓAˆFØ×#Ñ# u×':Ñ':Ô:Ü—‘Ð^Ô_ØŸ+š+ fÑ9´Ñ9�Ø×:Ñ:¸7ÔCØ�Ü˜#œ|×,Ò,ô
 —‘Ð]Ô^Ø�Ü×7Ò7¸×<Ò<Ü—‘ðFØGJôLð ×/Ñ/°Ô;Ø×(Ñ(ØÜ×5Ñ5¸Ä×AaÑAaÐ@bÐ7cÐdôð ×-Ñ-¨eÔ9Ùð =ô ! §¡Ó/Ò;Ü;¸DÈÓM‰OˆGßØ�Ø×Ñ˜U DÔ)ÙøôW (ô +Ø#Ÿ{™{Õ*ûÜ$ô QÜŸ™Ð%DÀi×PÒPûðQús1   Á&A4P< Ð<RÑQÑRÑRÑ%RÑ&RÒRc               ó$   € V ^8„  d   QhRRRRRR/# ©r6   rä   rv   r¦  rD   r7   rŸ  r9   )r:   s   "r;   r<   rñ  )  s#   € ÷ ñ Ð.>ð ÀYð ÐSWñ r=   c                óœ  a€ V P                   ;_uu_ 4        \        V3R lV P                   4       R4      pVe   VP                  \        8X  d    RRR4       R# T P                  T\        \        P                  ! 4       R\        \        VRR4      ;'       g    R4      \        V4      R7       RRR4       R#   + '       g   i     R# ; i)a“  Mark a row whose refresh token was terminally rejected DEAD, if the quarantine kept it.

``_quarantine_sources`` drops only singleton-seeded rows; an independent ``manual:*`` login
(``hermes auth add``) survives, and an unmarked survivor re-enters rotation and re-fires the
terminal WARNING on every later refresh attempt. DEAD leaves rotation until a write-side
re-auth sync clears it (never via TTL).
c              3  ó`   <"  € T F#  qP                   SP                   8X  g   K  Vx € K%  	  R # 5ir�   re  )ró   rn  rä   s   & €r;   rô   Ú:CredentialPool._mark_dead_refresh_grant.<locals>.<genexpr>2  s    øé € ÐR©] T¿g¹gÈÏÉÑ>QŸDšD«]ùs   ƒ.¤
.NÚcodeÚinvalid_grant)r`   ra   rb   rc   rd   )	rý  ra  r÷  r`   r#  rg  r  rk   r³   )r�   rä   r¦  rD  s   &f& r;   r  Ú'CredentialPool._mark_dead_refresh_grant)  s’   ø€ ð �Z�Z‹ZÜÔR¨T¯]ª]ÓRÐTXÓYˆGØŠ '×"5Ñ"5¼Ô"DØ÷ ‰Zð �K‰KØÜ'Ü#Ÿyšy›{Ø $Ü"%¤g¨c°6¸4Ó&@×&SÐ&SÀOÓ"TÜ#& s£8ð ô ÷	 �Z�ZŠZús   –;B:Á>B:ÂB:Â:C	c               ó$   € V ^8„  d   QhRRRRRR/# r'  r9   )r:   s   "r;   r<   rñ  >  s(   € ÷ \ñ \Ð2Bð \Èð \ÐW[ñ \r=   c                óú  € \         V P                  ,          ^,          p \        4       ;_uu_ 4        \        4       p\	        W@P                  4      ;'       g    / p\        V\        4      '       d   VP                  R4      ;'       g    / MRp\        V\        4      '       Ed   \        VP                  R4      ;'       g    R4      P                  4       pV'       d3   T\        VP                  ;'       g    R4      P                  4       8X  dŸ   VP                  RR4       VP                  RR4       WeR&   RV P                  R\        VRR4      R	\        V4      R
RRRR\        P                  ! \        4      P!                  4       /VR&   \#        W@P                  V4       \%        V4       RRR4       R#   + '       g   i     R# ; i  \&         d"   p\(        P+                  RY84        Rp?R# Rp?ii ; i)zSDrop the dead Codex/xAI token pair from auth.json unless a peer already rotated it.r¢  Nr~   r¢   r|   rj   r+  Úunknownr  r  Úcredential_pool_refresh_failureÚrelogin_requiredTÚatÚlast_auth_errorz+Failed to clear terminal %s OAuth state: %s)rÞ  rj   r&   r*   r+   rp   rÞ   rC   rk   r½   r~   r|  r³   r
   Únowr   Ú	isoformatr1   r0   rD   r¤  r¥  )	r�   rä   r¦  r›  r²  r  r¢  r¨  Ú	clear_excs	   &&&      r;   r  Ú+CredentialPool._clear_terminal_tokens_state>  s~  € ä-¨d¯m©mÕ<¸QÕ?ˆð	\Ü!×#Õ#Ü-Ó/�
Ü,¨Z¿¹ÓG×MÐMÈ2�Ü8BÀ5Ì$×8OÒ8O˜%Ÿ)™) HÓ-×3Ð3°øÐUY�Ü˜f¤d×+Ó+Ü$'¨¯
©
°?Ó(C×(IÐ(IÀrÓ$J×$PÑ$PÓ$R�Mß(¨M¼SÀ×ATÑAT×AZÐAZÐXZÓ=[×=aÑ=aÓ=cÔ,cØŸ
™
 >°4Ô8ØŸ
™
 ?°DÔ9Ø*0˜h™à&¨¯©Ø"¤G¨C°¸Ó$CØ%¤s¨3£xØ$Ð&GØ.°Ø ¤(§,¢,¬sÓ"3×"=Ñ"=Ó"?ð4˜Ð/Ñ0ô -¨Z¿¹ÈÔNÜ(¨Ô4÷' $×#×#Ò#ûô( ô 	\Ü�L‰LÐFÈ×[Ò[ûð	\úsN    G ²AF:Â
8F:ÃF:Ã F:Ã9B7F:Æ0G Æ:G	ÇG ÇG ÇG:ÇG5Ç5G:c               ó$   € V ^8„  d   QhRRRRRR/# r'  r9   )r:   s   "r;   r<   rñ  Y  s(   € ÷ Uñ UÐ0@ð UÀyð UÐUYñ Ur=   c                	óü  €  \        4       ;_uu_ 4        \        4       p\        VR 4      ;'       gK    RVP                  RVP                  RVP
                  RVP                  RVP                  RVP                  /p\        VP                  R4      ;'       g    R4      P                  4       pV'       d3   T\        VP                  ;'       g    R4      P                  4       8X  dI   \        P                  ! WBR	R
7       \        P                  ! W2R	R
7       \!        VR V4       \#        V4       RRR4       R#   + '       g   i     R# ; i  \$         d"   p\&        P)                  RT4        Rp?R# Rp?ii ; i)r»   Ú	client_idÚportal_base_urlr†   Ú
token_typer¼   Útlsr~   r¢   r1  )r  Nz-Failed to clear terminal Nous OAuth state: %s)r&   r*   r+   r;  r<  r†   r=  r¼   r>  rk   rC   r½   r~   r¾   Ú_quarantine_nous_oauth_stateÚ_quarantine_nous_pool_entriesr1   r0   rD   r¤  r¥  )r�   rä   r¦  r²  r  r¨  r7  s   &&&    r;   r  Ú)CredentialPool._clear_terminal_nous_stateY  s(  € ð	UÜ!×#Õ#Ü-Ó/�
Ü,¨Z¸Ó@÷ ð Ø §¡Ø% u×'<Ñ'<Ø(¨%×*BÑ*BØ  %×"2Ñ"2Ø˜UŸ[™[Ø˜5Ÿ9™9ðE�ô !$ E§I¡I¨oÓ$>×$DÐ$DÀ"Ó E× KÑ KÓ M�ß$¨¼¸U×=PÑ=P×=VÐ=VÐTVÓ9W×9]Ñ9]Ó9_Ô(_Ü×9Ò9¸%ÐMnÕoÜ×:Ò:¸:ÐStÕuÜ(¨°V¸UÔCÜ$ ZÔ0÷ $×#×#Ò#ûô  ô 	UÜ�L‰LÐHÈ)×TÒTûð	UúsH   ‚E ”BD;ÂD;Â7D;ÃA!D;Ä1E Ä;E	ÅE ÅE ÅE;ÅE6Å6E;c               ó    € V ^8„  d   QhRRRR/# ©r6   rä   rv   r7   ræ   r9   )r:   s   "r;   r<   rñ  n  s   € ÷ 'ñ 'Ð4Dð 'Èñ 'r=   c                óö  € V P                   R8w  g   VP                  \        8w  d   R# \        P                  ! VP
                  VP                  VP                  4      '       g   R# VP                  ;'       g    RpV'       g   R#  \        P                  ! W!P                  4      pV'       dm   T P                  YR,          VR,          VP                  R4      ;'       g    VP                  R7      pV P                  V4       VP                  ;'       g    Tp^ RIHp \#        \        P$                  ! W$! VP&                  4      R	7      4      #   \(         d    \*        P-                  R
RR7        R# i ; i)uw  Live-check whether an exhausted Codex entry's quota reset early.

A Codex 429 persists a ``last_error_reset_at`` that can be days out
(weekly windows), but the window can reopen before then (redeemed
reset, plan upgrade, OpenAI reset) â€” issue #43747. Only fires for
429/quota-shaped errors; the probe is throttled per token (5 min) so
it is safe on the hot selection path.
rÄ   Fr¢   r|   r~   r…   r  )Ú_codex_pool_route_base_urlr‹  z!Codex quota-restored probe failedTrÜ  )rj   r`   r$  r¾   Ú_is_codex_rate_limit_shapedrb   rc   rd   r|   Ú"_refresh_expired_codex_probe_tokenr~   rg  rC   r…   r¾  Úhermes_cli.auth_codexrE  ræ   Ú_probe_codex_quota_restoredr‚   rD   r¤  r¥  )r�   rä   rl   ÚfreshrE  s   &&   r;   Ú_codex_quota_restored_upstreamÚ-CredentialPool._codex_quota_restored_upstreamn  s?  € ð �=‰=˜NÔ*¨e×.?Ñ.?ÔCSÔ.SÙÜ×3Ò3Ø×!Ñ! 5×#:Ñ#:¸E×<TÑ<T÷
ò 
ñ Ø×"Ñ"×(Ð( bˆßÙð	ô ×?Ò?À×GZÑGZÓ[ˆEßð
 Ÿ™Ø¨nÕ(=ÈUÐSbÕMcØ!&§¡¨>Ó!:×!PÐ!P¸e×>PÑ>Pð $ó �ð ×:Ñ:¸5ÔAØ×*Ñ*×3Ð3¨e�åHÜœ×<Ò<ØÐ :¸5¿>¹>Ó JôLó Mð Møäô 	Ü�L‰LÐ<ÀtˆLÔLÚð	ús   ÂAE Ã#5E Ä8E Å"E8Å7E8c               ó    € V ^8„  d   QhRRRR/# rC  r9   )r:   s   "r;   r<   rñ  —  s   € ÷ ñ Ð*:ð ¸tñ r=   c                	ó�  € VP                   \        8w  d   R # V P                  R8X  g   \        V P                  4      e   \	        V4      # V P                  R8X  d   \        VP                  \        4      # V P                  R8X  d@   \        P                  ! VP                  \        P                  ! VP                  4      4      # R # )Fro   rÄ   rÝ  )rm   rr   rj   r   r   r'   r|   r#   r¾   Ú_xai_access_token_is_expiringÚ#_xai_proactive_refresh_skew_seconds)r�   rä   s   &&r;   rÎ  Ú#CredentialPool._entry_needs_refresh—  s˜   € Ø�?‰?œoÔ-ÙØ�=‰=˜KÔ'Ô+>¸t¿}¹}Ó+MÒ+YÜ)¨%Ó0Ð0Ø�=‰=˜NÔ*Ü2°5×3EÑ3EÔGnÓoÐoØ�=‰=˜KÔ'Ü×9Ò9Ø×"Ñ"¤H×$PÒ$PÐQV×QcÑQcÓ$dóð ñ
 r=   c               ó    € V ^8„  d   QhRRRR/# )r6   r  r}   r7   rå  r9   )r:   s   "r;   r<   rñ  ¨  s   € ÷ 	ñ 	˜}ð 	Ð8Rñ 	r=   c               	ó¦   € V P                  VR 7      w  r#V'       d*   V P                  V4       Vf   V P                  VR 7      w  r$Ve   ^ V n        V# )r  )Ú_select_under_lockÚ_refresh_pending_entriesr  )r�   r  rä   Úpending_refreshr"  s   &$   r;   ÚselectÚCredentialPool.select¨  sV   € Ø!%×!8Ñ!8¸uÐ!8Ó!EÑˆßØ×)Ñ)¨/Ô:àŠ}Ø×2Ñ2¸Ð2Ó?‘�ØÒØ./ˆDÔ+Øˆr=   c               ó    € V ^8„  d   QhRRRR/# )r6   r  r}   r7   ú9tuple[Optional[PooledCredential], list[PooledCredential]]r9   )r:   s   "r;   r<   rñ  ³  s   € ÷ 6ñ 6¨=ð 6ÐD}ñ 6r=   c               	óŒ   € V P                   ;_uu_ 4        V P                  VR 7      uuRRR4       #   + '       g   i     R# ; i)r  N)rý  Ú_select_unlocked)r�   r  s   &$r;   rT  Ú!CredentialPool._select_under_lock³  s(   € Ø�Z�Z‹ZØ×(Ñ(¨uÐ(Ó5÷ �Z�Z‹Zús	   •2²A	c               ó    € V ^8„  d   QhRRRR/# )r6   Úpendingrî   r7   rŸ  r9   )r:   s   "r;   r<   rñ  ·  s   € ÷ 4ñ 4Ð0Fð 4È4ñ 4r=   c                ó˜   € \        V4       F:  w  r#V'       d   \        P                  ! \        4       V P	                  VRR7       K<  	  R# )u^  Refresh deferred single-use-token entries OUTSIDE the pool lock.

Each refresh takes the cross-process ``_auth_store_lock`` (20+ s
possible) and merges into the pool through the self-locking mutation
primitives; failures are silently skipped.

Entries are refreshed one at a time with a lock-free spacing window
between consecutive holds: ``_refresh_entry`` legitimately keeps the
store lock across its POST (single-use-token safety â€” sync -> POST ->
write-back must be atomic across processes), so a back-to-back chain
of N holds can starve a waiter on the same profile's auth.json whose
timeout is shorter (a Desktop assistant start, AUTH_LOCK_TIMEOUT_SECONDS
= 15s, vs the holder's max(15s, refresh_timeout + 5s)) for the whole
sweep (#124533). A short window between holds lets the waiter's
50ms poll cadence interleave; the chain still finishes promptly.
FrÉ  N)rQ  r  ÚsleepÚ_REFRESH_SWEEP_SPACING_SECONDSrÑ  )r�   r_  Úindexrä   s   &&  r;   rU  Ú'CredentialPool._refresh_pending_entries·  s8   € ô" & gÖ.‰LˆEßÜ—
’
Ô9Ô:Ø×Ñ ¨UÐÖ3ó /r=   c               ó    € V ^8„  d   QhRRRR/# )r6   rä   rv   r7   r   r9   )r:   s   "r;   r<   rñ  Í  s   € ÷ 	Xñ 	XÐ*:ð 	X¸ñ 	Xr=   c                ób  a€  \        V3R l\        V P                  4       4       R4      p\        T;'       g    / P	                  R4      4      pT'       d   TSP                  ;'       g    R8”  d   T# R#   \
         d-   p\        P                  RSP                  T4        Rp?R# Rp?ii ; i)z`Epoch of a ``hermes auth reset`` persisted by another process AFTER *entry*'s status, else None.c              3  óœ   <"  € T FA  p\        V\        4      '       g   K  VP                  R 4      SP                  8X  g   K=  Vx € KC  	  R# 5ir’  r“  r”  s   & €r;   rô   Ú6CredentialPool._reset_cleared_after.<locals>.<genexpr>Ð  s>   øé € ð LÑ#F˜aÜ% a¬×.ô Ø34·5±5¸³;À%Ç(Á(Ñ3J÷ šÓ#Fùr—  Nr�   z.Pool entry %s: could not read reset marker: %sg        )
ra  r3   rj   r   rC   rD   r¤  r¥  rw   ra   )r�   rä   r\  rÎ  r¦  s   &f   r;   Ú_reset_cleared_afterÚ#CredentialPool._reset_cleared_afterÍ  s˜   ø€ ð	Üô LÔ#7¸¿¹Ô#Fó LØMQóSˆCä/°·°¸·±Ð@SÓ0TÓUˆG÷ " g°×1EÑ1E×1LÐ1LÈÔ&MˆwÐWÐSWÐWøô ô 	Ü�L‰LÐIÈ5Ï8É8ÐUXÔYÝûð	ús   ƒ6A7 ºA7 Á7B.Â!B)Â)B.c               ó    € V ^8„  d   QhRRRR/# r‚  r9   )r:   s   "r;   r<   rñ  Ø  s   € ÷ 7ñ 7Ð)9ð 7Ð>Nñ 7r=   c                óª  € VP                   \        \        09  d   V# V P                  V4      pVe   V P                  ! V3RR/\
        BRV/B # VP                  \        P                  V P                  4      8w  d   V# V P                  R8X  d   V P                  V4      # V P                  R8X  d   V P                  V4      # V P                  V4      # )a®  Re-read an exhausted/DEAD singleton-seeded entry from its token authority.

The user may have re-authed (``hermes model`` / ``hermes auth``, the
Claude Code CLI, another profile) leaving fresh tokens on disk while
the pool entry is frozen behind ``last_error_reset_at``. A ``hermes auth
reset`` run from another process while this pool is live is honoured the
same way (#89415): the in-memory cooldown would otherwise outlive it.
r`  Fr�   ro   r»   )r`   r$  r#  ri  rg  rh   r{   Ú_RESYNC_SOURCErC   rj   r‹  r¶  r¬  )r�   rä   Ú
cleared_ats   && r;   Ú_resync_stale_entryÚ"CredentialPool._resync_stale_entryØ  s½   € ð ×ÑÔ%5´{Ð$CÔCØˆLØ×.Ñ.¨uÓ5ˆ
ØÒ!Ø—;’;˜uÑ^¨eÐ^´xÑ^ÐS]Ò^Ð^Ø�<‰<œ>×-Ñ-¨d¯m©mÓ<Ô<ØˆLØ�=‰=˜KÔ'Ø×CÑCÀEÓJÐJØ�=‰=˜FÔ"Ø×8Ñ8¸Ó?Ð?Ø×/Ñ/°Ó6Ð6r=   r  FÚrefreshc               ó(   € V ^8„  d   QhRRRRRRRR/# )r6   r  ræ   rq  r  r}   r7   z5tuple[list[PooledCredential], list[PooledCredential]]r9   )r:   s   "r;   r<   rñ  î  s2   € ÷ T*ñ T*Ø $ðT*Ø7;ðT*ØLYðT*à	>ñT*r=   c               ón  € \         P                   ! 4       pRp. p. p. pV P                  4       p	V P                   EF�  p
V
P                  \        8X  d   V
P
                  '       g   K-  V P                  V
4      pWºJd   Tp
RpV
P                  \        8X  dÔ   \        V
P                  4      '       d¶   V
P                  ;'       g    ^ pV'       d˜   WL,
          \        8”  d‡   \        P                  RV
P                  ;'       g    V
P                   R,          V
P"                  ;'       g    RWL,
          R,          V P$                  4       VP'                  V
P                   4       RpEK/  \)        W£4      e   EK?  V
P                  \*        8X  d…   \-        W©R7      pVe)   WM8  d#   V'       d   V P/                  V
4      '       g   EKŒ  V'       dE   V P1                  V
P                   3R l4      ;'       g    T
p
V P2                  ! V
3R	R/\4        B p
RpV'       d]   V P7                  V
4      '       dF   V P$                  \8        9   d   VP'                  V
4       EK   V P;                  V
RR
7      pVf   EK:  Tp
V
P                  \<        8X  d.   V
P>                  ;'       g    RPA                  4       '       g   EK~  VP'                  V
4       EK’  	  V'       d@   \C        V4      pV P                   Uu. uF  pVP                   V9  g   K  VNK  	  upV n        V'       d   V PE                  VR7       Wx3# u upi )uÊ  Return (available, pending_refresh) for entries not in cooldown.

*clear_expired* resets elapsed cooldowns to STATUS_OK and persists.
*refresh* refreshes entries needing a token refresh (skipped on
failure) â€” except single-use-token providers (openai-codex,
xai-oauth), which are returned as *pending_refresh* so the caller
refreshes them outside the lock instead of stalling every pool
consumer during cross-process flock acquisition + OAuth network I/O.
FTuh   credential pool: pruning DEAD manual entry %s (reason=%s, age=%.1fh) â€” re-add via `hermes auth add %s`r  r0  g      ¬@r   c                ó    € V P                   V8H  # r�   re  )r0  Úis   &&r;   rM   Ú3CredentialPool._available_entries.<locals>.<lambda>,  s   € ¸Q¿T¹TÀQºYr=   r`  rÉ  r¢   rm  )#r  r%  r÷  rm   rs   rÀ   ro  r`   r#  rÿ   r{   ra   ÚDEAD_MANUAL_PRUNE_TTL_SECONDSr¤  rÛ  rx   rw   rc   rj   rG  r   r$  r%  rK  r9  rg  rh   rÎ  rÞ  rÑ  rr   r|   r½   r7  r^  )r�   r  rq  r  r5  Úcleared_anyÚentries_to_pruner  rV  r   rä   rÐ  Údead_atÚexhausted_untilrì  Ú
pruned_idsr0  s   &$$$             r;   r  Ú!CredentialPool._available_entriesî  s˜  € ô �iŠi‹kˆØˆØ&(ÐØ,.ˆ	Ø24ˆØ×2Ñ2Ó4ˆØ—]•]ˆEð �‰Ô"3Ô3¸E×<Q×<QÐ<QÙØ×-Ñ-¨eÓ4ˆFØÓ"Ø�Ø"�Ø× Ñ ¤KÔ/ô
 % U§\¡\×2Ò2Ø#×2Ñ2×7Ð7°a�Gß 3¥=Ô3PÔ#PÜŸ™ðYà!ŸK™K×7Ð7¨5¯8©8°B­<Ø!×3Ñ3×@Ð@°yØ �]¨fÕ4Ø ŸM™Môð )×/Ñ/°·±Ô9Ø&*˜ÚÜ# EÓ1Ò=ÚØ× Ñ Ô$4Ô4Ü"2°5Ô"Z�ð $Ò/ØÔ-ß*¨t×/RÑ/RÐSX×/YÒ/Yâß ð !ŸJ™J°5·8±8Ó'FÓG×PÐPÈ5�EØ ŸKšK¨ÑI°uÐIÄÑI�EØ"&�Kß˜4×4Ñ4°U×;Ò;Ø—=‘=Ô$?Ô?Ø#×*Ñ*¨5Ô1ÚØ ×/Ñ/°¸UÐ/ÓC�	ØÒ$ÚØ!�Ø�‰¤/Ô1¸5×;MÑ;M×;SÐ;SÐQS×:ZÑ:Z×:\Ò:\ò Ø×Ñ˜U×#ñy #÷z ÜÐ-Ó.ˆJØ(,¯ªÓP© 1¸¿¹ÀZÑ9OŸQ˜Q©ÑPˆDŒMßØ�M‰MÐ&6ˆMÔ7ØÐ)Ð)ùò Qs   Ë/L2ÌL2c               ó   € V ^8„  d   QhRR/# ©r6   r7   rŸ  r9   )r:   s   "r;   r<   rñ  D  s   € ÷ Vñ V¨4ñ Vr=   c                ó¬   € \         P                  ! 4       pV P                  pVe   W,
          \        8  d   R# Wn        \        P                  R4       R# )z?Emit the empty-pool INFO line at most once per throttle window.Nz>credential pool: no available entries (all exhausted or empty))r  Ú	monotonicr  Ú)NO_AVAILABLE_ENTRIES_LOG_THROTTLE_SECONDSr¤  r¤  )r�   r5  Úlasts   &  r;   Ú_log_no_available_entriesÚ(CredentialPool._log_no_available_entriesD  s?   € ä�nŠnÓˆØ×+Ñ+ˆØÒ ¥Ô/XÔ XÙØ'*Ô$Ü�‰ÐTÖUr=   Úcountc               ó(   € V ^8„  d   QhRRRRRRRR/# )r6   rq  ræ   r†  r  r}   r7   rZ  r9   )r:   s   "r;   r<   rñ  M  s,   € ÷ $&ñ $&Øð$&Ø.2ð$&ØBOð$&à	Bñ$&r=   c          	     óÌ  a	€ V P                  RWR7      w  rEV'       g   RV n        V P                  4        RV3# RV n        V P                  \
        8X  d   \        P                  ! V4      o	M=V P                  \        8X  d    \        V4      ^8”  d   \        VR R7      o	M	V^ ,          o	V'       d&   V P                  S	RS	P                  ^,           R7      o	V P                  \        8X  dÛ   \        V4      ^8”  dË   V P                   Uu. uF!  qfP                  S	P                  8w  g   K  VNK#  	  ppVP!                  \#        S	\        V P                  4      ^,
          R7      4       \%        V4       UUu. uF  w  r†\#        WhR7      NK  	  uppV n        V P'                  4        V P)                  V	3R	 l4      ;'       g    S	o	S	P                  V n        S	V3# u upi u uppi )
zÐSelect the best available entry; returns ``(entry, pending_refresh)``.

``count=False`` skips the ``request_count`` bump for selections that are
not going to serve a request (a forced-refresh target lookup).
T©r  rq  r  Nc                ó   € V P                   # r�   )r‰   )r0  s   &r;   rM   Ú1CredentialPool._select_unlocked.<locals>.<lambda>b  s   € °·²r=   rö  F)r`  r‰   rñ   c                ó6   <€ V P                   SP                   8H  # r�   re  )rˆ  rä   s   &€r;   rM   r‹  o  s   ø€ °·±ÀÇÁÒ1Ir=   )r  rø  r„  r  rú  ÚSTRATEGY_RANDOMr[   ÚchoiceÚSTRATEGY_LEAST_USEDrA  r	  rg  r‰   ÚSTRATEGY_ROUND_ROBINr÷  rw   rG  r	   rQ  r^  r9  )
r�   rq  r†  r  r  rV  rˆ  r  rR  rä   s
   &$$$     @r;   r\  ÚCredentialPool._select_unlockedM  s  ø€ ð &*×%<Ñ%<È4ÐY`Ð%<Ó%nÑ"ˆ	ßØ#ˆDÔØ×*Ñ*Ô,Ø˜Ð(Ð(ð (,ˆÔ$à�>‰>œ_Ô,Ü—M’M )Ó,‰EØ�^‰^Ô2Ô2´s¸9³~ÈÔ7IÜ˜	Ñ'@ÔA‰Eà˜a•LˆE÷ Ø—K‘K ¨uÀE×DWÑDWÐZ[ÕD[�KÓ\ˆEØ�>‰>Ô1Ô1´c¸)³nÀqÔ6HØ26·-²-Ó\±- YÇ<Á<ÐSX×S[ÑS[ÑC[—y�y±-ˆGÐ\Ø�N‰Nœ7 5´3°t·}±}Ó3EÈÕ3IÔJÔKÜT]Ð^eÔTfÔgÑTfÁ.À#œW Y×=ÑTfÒgˆDŒMØ�M‰MŒOØ—J‘JÔIÓJ×SÐSÈeˆEØ Ÿ8™8ˆÔØ�oÐ%Ð%ùò ]ùãgs   Ä
GÄ+GÅ7G c               ó   € V ^8„  d   QhRR/# r<  r9   )r:   s   "r;   r<   rñ  s  s   € ÷ 7ñ 7Ð0ñ 7r=   c                	óò   € V P                   ;_uu_ 4        V P                  4       pVe   VuuR R R 4       # V P                  4       w  r#V'       d
   V^ ,          MR uuR R R 4       #   + '       g   i     R # ; ir�   )rý  r@  r  )r�   rD  r  r  s   &   r;   ÚpeekÚCredentialPool.peeks  sS   € Ø�Z�Z‹ZØ×,Ñ,Ó.ˆGØÒ"Ø÷ ŠZð #'×"9Ñ"9Ó";ÑˆIß#,�9˜Q–<°$÷ �Z�Z‹Zús   •A%¶$A%Á%A6	c               ó$   € V ^8„  d   QhRRRRRR/# )r6   Úcredential_idrk   r  r}   r7   rå  r9   )r:   s   "r;   r<   rñ  {  s'   € ÷ 
Kñ 
K Sð 
K°Mð 
KÐMgñ 
Kr=   c               ó8  a€ V P                   ;_uu_ 4        V P                  RRVR7      w  r4RRR4       \        ;QJ d    V3R lX 4       F  '       g   K   RM	  RM! V3R lX 4       4      '       dg   T P                  V Uu. uF  qUP                  S8X  g   K  VNK  	  up4       V P                   ;_uu_ 4        V P                  RRVR7      w  r6RRR4       \        V3R lX 4       R4      #   + '       g   i     LÌ; iu upi   + '       g   i     L>; i)zñEntry *credential_id* once its cooldown has lifted (cleared and token-refreshed the way
``select`` would), else ``None``. Never bumps ``request_count`` or round-robin order: a
live session asking "may I go back?" every turn is not a request.Tr‰  Nc              3  ó@   <"  € T F  qP                   S8H  x € K  	  R # 5ir�   re  ©ró   r0  r—  s   & €r;   rô   Ú)CredentialPool.reclaim.<locals>.<genexpr>�  s   øé € Ð6©g¨�t‰t�}Ö$«gùs   ƒFc              3  óL   <"  € T F  qP                   S8X  g   K  Vx € K  	  R # 5ir�   re  rš  s   & €r;   rô   r›  …  s   øé € ÐC¡	˜1¯T©T°]Ñ-B—Q’Q£	ùs   ƒ$š
$)rý  r  rY  rU  rw   ra  )r�   r—  r  r  r_  r0  r  s   &f$    r;   ÚreclaimÚCredentialPool.reclaim{  sÈ   ø€ ð �Z�Z‹ZØ!%×!8Ñ!8ÀtÐUYÐafÐ!8Ó!gÑˆI÷ ç‹3Ô6©gÓ6�3�3Š3Ô6©gÓ6×6Ò6Ø×)Ñ)±gÓ*W±g°ÇÁÈÑAV¯1¨1±gÑ*WÔXØ——“Ø&*×&=Ñ&=ÈDÐZ^ÐfkÐ&=Ó&lÑ#�	÷ äÔC¡	ÓCÀTÓJÐJ÷ �Züò +Xß—ús#   –C1ÂDÂDÂ<D	Ã1D	Ä	D	c               ó$   € V ^8„  d   QhRRRRRR/# )r6   r—  r}   rH  r7   rå  r9   )r:   s   "r;   r<   rñ  ‰  s$   € ÷ ñ Ø*ðØ:Gðà	#ñr=   c                ó¼  aa€ RpS'       d¯   V P                  V3R l4      pVe–   S'       dŽ   VP                  S8w  d}   V P                  V3R l4      pVeb   \        P                  RVP                  ;'       g    VP
                  R,          VP                  ;'       g    VP
                  R,          4       TpVf   S'       d   V P                  V3R l4      pV# )zJResolve the entry that issued a failed request from its supplied identity.Nc                ó"   <€ V P                   S8H  # r�   re  ©r0  r—  s   &€r;   rM   Ú7CredentialPool._identify_failed_entry.<locals>.<lambda>�  ó   ø€ ¨¯©°Ò)>r=   c                ó"   <€ V P                   S8H  # r�   ©rÀ   ©r0  rH  s   &€r;   rM   r£  •  s   ø€ °!×2CÑ2CÀ|Ò2Sr=   z‡credential pool: credential_id %s runtime key does not match api_key_hint; attributing failure to key-matched entry %s instead (#79156)r  c                ó"   <€ V P                   S8H  # r�   r¦  r§  s   &€r;   rM   r£  ¥  s   ø€ ¨×):Ñ):¸lÒ)Jr=   )r9  rÀ   r¤  r¤  rx   rw   )r�   r—  rH  rä   Ú
hint_entrys   &ff  r;   Ú_identify_failed_entryÚ%CredentialPool._identify_failed_entry‰  s±   ù€ ð ˆßØ—J‘JÔ>Ó?ˆEð
 Ò §\°e×6KÑ6KÈ|Ô6[Ø!ŸZ™ZÔ(SÓT�
ØÒ)Ü—K‘KðCð Ÿ™×4Ð4¨¯©°­Ø#×)Ñ)×>Ð>¨Z¯]©]¸2Õ->ôð #�ØŠ=Ÿ\ð —J‘JÔJÓKˆEØˆr=   c               ó   € V ^8„  d   QhRR/# r<  r9   )r:   s   "r;   r<   rñ  ¨  s   € ÷ %ñ %Ð#=ñ %r=   c                ó  € V ;P                   ^,          un         \        V P                  4       ^ ,          4      pV P                   \        V^4      8”  d=   \        P                  RV P                  V P                   V4       ^ V n         RV n        R# \        P                  RV P                  4       RV n        V P                  RR7      w  r#Ve6   \        V P                  4       ^ ,          4      ^8X  d   ^ V n         RV n        R# V# )a   Rotate without marking anything when the failed identity matches no entry.

Falling through to current()/_select_unlocked() would bench an
innocent healthy key for the full TTL. But this must be BOUNDED
(#70401): with OAuth-token auth the 401's key hint never matches any
``runtime_api_key``, so every retry lands here, nothing is marked, and
the caller retries the same dead token forever (~6/sec, starving the
event loop). Cap consecutive no-mark rotations at one lap of the
available entries, then surface the error; no cooldown is written.
u�   credential pool: failed credential identity matched no %s entry for %d consecutive rotations (pool size %d) â€” surfacing the error instead of rotating againNzrcredential pool: failed credential identity matched no %s entry; rotating without marking any credential exhaustedF©rq  )
r  rA  r  rø   r¤  rÛ  rj   rø  r¤  r\  )r�   Úavailable_countÚ
next_entryr  s   &   r;   Ú_rotate_unmatchedÚ CredentialPool._rotate_unmatched¨  sð   € ð 	×'Ò'¨1Õ,Õ'Ü˜d×5Ñ5Ó7¸Õ:Ó;ˆØ×*Ñ*¬S°À!Ó-DÔDÜ�N‰Nð@ð —‘˜t×>Ñ>Àô	ð /0ˆDÔ+Ø#ˆDÔÙÜ�‰ðGà�M‰Mô	
ð
  ˆÔØ#×4Ñ4¸UÐ4ÓCÑˆ
ØÒ!¤c¨$×*AÑ*AÓ*CÀAÕ*FÓ&GÈ1Ô&Lð /0ˆDÔ+Ø#ˆDÔÙØÐr=   r  rH  r—  c               ó4   € V ^8„  d   QhRRRRRRRRRRR	RR
R/# )r6   rr  r€   r  r  rH  r}   r—  r_   r  r7   rå  r9   )r:   s   "r;   r<   rñ  Ï  s[   € ÷ Lñ Lð #ðLð 0ð	Lð
 $ðLð %ðLð &ðLð ðLð 
$ñLr=   c               	ó^  a€ V P                   ;_uu_ 4        \        T;'       g    T4      pV P                  WC4      oSf#   V'       d   V P                  4       uuR R R 4       # ^ V n        Sf2   V P                  4       ;'       g    V P                  RR7      ^ ,          oSf    R R R 4       R # SP                  ;'       g    SP                  R,          pV P                  WV4      '       dS   V P                  SWbVR7       \        P                  RW†4       R V n        V P                  RVR7      w  ršV	uuR R R 4       # V P                  SWVR7       SP                  pV'       d‰   V'       d�   V P                    Uu. uF4  qÌP                  SP                  8w  g   K  VP                  V8X  g   K2  VNK6  	  ppV F  pV P                  WáVRVR7       K  	  V'       d   V P#                  4        V P%                  V3R l4      ;'       g    SpVP&                  \(        8X  d-   \        P+                  R	Y�VP,                  ;'       g    R
4       M\        P                  RW�4       R V n        V P                  RR7      w  ršV	eD   V	P                  SP                  8X  d)   \        P+                  RV4       R V n         R R R 4       R # V	'       d<   \        P                  RV	P                  ;'       g    V	P                  R,          4       V	uuR R R 4       # u upi   + '       g   i     R # ; i)NFr®  r  )r_   zIcredential pool: %s unavailable for model %s; other models stay available)rq  r  )r`  r_   c                ó6   <€ V P                   SP                   8H  # r�   re  )r0  rä   s   &€r;   rM   Ú:CredentialPool.mark_exhausted_and_rotate.<locals>.<lambda>	  s   ø€ °·±¸¿¹Ò1Ar=   ux   credential pool: marking %s DEAD (status=%s, reason=%s) â€” permanently failed, will NOT re-enter rotation until re-authr0  z;credential pool: marking %s exhausted (status=%s), rotatinguo   credential pool: rotation returned the just-marked entry %s â€” treating as no-recovery so the failure surfaceszcredential pool: rotated to %s)rý  ræ   rª  r±  r  r@  r\  rx   rw   Ú_is_model_scoped_failureÚ_cool_down_modelr¤  r¤  rø  r  rÀ   r÷  r^  r9  r`   r#  rÛ  rc   )r�   rr  r  rH  r—  r_   r  Úidentity_suppliedÚ_labelr°  r  Úfailed_runtime_keyÚsÚsiblingsÚsiblingÚupdated_entryrä   s   &$$$$$$         @r;   Úmark_exhausted_and_rotateÚ(CredentialPool.mark_exhausted_and_rotateÏ  s½  ø€ ð �Z�Z‹ZÜ $ ]×%BÐ%B°lÓ CÐØ×/Ñ/°ÓLˆEØŠ}×!2Ø×-Ñ-Ó/÷	 ŠZð /0ˆDÔ+ØŠ}Ø×.Ñ.Ó0×[Ð[°D×4IÑ4IÐRWÐ4IÓ4XÐYZÕ4[�ØŠ}Ø÷ ‰Zð —[‘[×0Ð0 E§H¡H¨R¥LˆFØ×,Ñ,¨[À×PÒPð ×%Ñ% e¨UÐR`Ð%ÔaÜ—‘ÐgÐioÔwØ#'�Ô Ø'+×'<Ñ'<ÀUÐRWÐ'<Ó'XÑ$�
Ø!÷) ŠZð* × Ñ  ¨ÐSaÐ Ôbð "'×!6Ñ!6Ðß ×%7à#Ÿ}š}óÙ,˜!·±¸¿¹Ñ0@”AÀQ×EVÑEVÐZlÑEl—A�A™}ð ð ó  (�GØ×(Ñ(Ø¨mÀUÐ[ið )ö ñ  (÷ Ø—M‘M”Oà ŸJ™JÔ'AÓB×KÐKÀeˆMØ×(Ñ(¬KÔ7Ü—‘ðSà¨×)HÑ)H×)UÐ)UÈIõô —‘ÐYÐ[aÔoØ#ˆDÔØ#'×#8Ñ#8ÀÐ#8Ó#GÑ ˆJØÒ%¨*¯-©-¸5¿8¹8Ô*Cô —‘ðFØGMôð $(�Ô Ø÷ ‰Z÷@ Ü—‘Ð<¸j×>NÑ>N×>cÐ>cÐR\×R_ÑR_Ð`bÕRcÔdØ÷E ŠZùò<÷= �ZˆZúsy   –2LÁ	LÁ#!LÂLÂ.LÃA3LÄ?/LÅ/LÅ=LÆLÆ1LÆ7'LÇ+LÈ;LÉA6LËLË"LË2LÌLÌL,	c               ó    € V ^8„  d   QhRRRR/# )r6   r—  r}   r7   r9   )r:   s   "r;   r<   rñ  	  s   € ÷ ñ ¨=ð ÀMñ r=   c                óŒ   € V P                  V4      w  r#V'       d)   V P                  V4       Vf   V P                  V4      w  r$V# )a  Acquire a soft lease on a credential.

With *credential_id*, lease that entry directly. Otherwise prefer the
least-leased available credential (priority as tie-breaker); when
every credential is at the soft cap, still return the least-leased
one instead of blocking.
)Ú_acquire_lease_under_lockrU  )r�   r—  Ú	chosen_idrV  r"  s   &&   r;   Úacquire_leaseÚCredentialPool.acquire_lease	  sH   € ð &*×%CÑ%CÀMÓ%RÑ"ˆ	ßØ×)Ñ)¨/Ô:ð Ò Ø#×=Ñ=¸mÓL‘�	ØÐr=   c               ó    € V ^8„  d   QhRRRR/# )r6   r—  r}   r7   z,tuple[Optional[str], list[PooledCredential]]r9   )r:   s   "r;   r<   rñ  1	  s   € ÷ .ñ .Ø*ð.à	5ñ.r=   c           	     	óð  a € S P                   ;_uu_ 4        V'       dF   S P                  P                  V^ 4      ^,           S P                  V&   VS n        V. 3uuRRR4       # S P	                  RRR7      w  r#V'       g   RV3uuRRR4       # V Uu. uF<  pS P                  P                  VP
                  ^ 4      S P                  8  g   K:  VNK>  	  pp\        T;'       g    TV 3R lR7      pS P                  P                  VP
                  ^ 4      ^,           S P                  VP
                  &   VP
                  S n        VP
                  V3uuRRR4       # u upi   + '       g   i     R# ; i)é    NT)r  rq  c                óh   <€ SP                   P                  V P                  ^ 4      V P                  3# )rÊ  )rþ  rC   rw   rz   )rä   r�   s   &€r;   rM   Ú:CredentialPool._acquire_lease_under_lock.<locals>.<lambda>A	  s%   ø€  4×#6Ñ#6×#:Ñ#:¸5¿8¹8ÀQÓ#GÈÏÉÑ"Xr=   rö  )rý  rþ  rC   rø  r  rw   r   r	  )r�   r—  r  rV  r0  Ú	below_capÚchosens   f&     r;   rÄ  Ú(CredentialPool._acquire_lease_under_lock1	  s7  ø€ ð �Z�Z‹ZßØ59×5HÑ5H×5LÑ5LÈ]Ð\]Ó5^ÐabÕ5b�×#Ñ# MÑ2Ø#0�Ô Ø$ bÐ(÷	 ŠZð *.×)@Ñ)@ÈtÐ]aÐ)@Ó)bÑ&ˆIßØ˜_Ð,÷ ŠZñ %.Ói¡I˜q°×1DÑ1D×1HÑ1HÈÏÉÈqÓ1QÐTX×ThÑThÑ1hŸ˜¡IˆIÐiÜØ×&Ð&˜YÜXôˆFð .2×-@Ñ-@×-DÑ-DÀVÇYÁYÐPQÓ-RÐUVÕ-VˆD×Ñ §	¡	Ñ*Ø%Ÿy™yˆDÔØ—9‘9˜oÐ-÷# ŠZùò j÷ �ZˆZús7   –AE$Á$ E$ÂE$Â7EÃEÃE$Ã%A/E$ÅE$Å$E5	c               ó    € V ^8„  d   QhRRRR/# )r6   r—  rk   r7   rŸ  r9   )r:   s   "r;   r<   rñ  G	  s   € ÷ ?ñ ?¨3ð ?°4ñ ?r=   c                	ó  € V P                   ;_uu_ 4        V P                  P                  V^ 4      pV^8:  d   V P                  P                  VR4       MV^,
          V P                  V&   RRR4       R#   + '       g   i     R# ; i)rÊ  N)rý  rþ  rC   r|  )r�   r—  r†  s   && r;   Úrelease_leaseÚCredentialPool.release_leaseG	  s`   € Ø�Z�Z‹ZØ×'Ñ'×+Ñ+¨M¸1Ó=ˆEØ˜ŒzØ×#Ñ#×'Ñ'¨°tÕ<à5:¸QµY�×#Ñ# MÑ2÷ �Z�ZŠZús   •AA6Á6B	c               ó   € V ^8„  d   QhRR/# r<  r9   )r:   s   "r;   r<   rñ  Q	  s   € ÷ 8ñ 8Ð%?ñ 8r=   c                	óˆ   € V P                   ;_uu_ 4        V P                  4       uuR R R 4       #   + '       g   i     R # ; ir�   )rý  Ú_try_refresh_current_unlockedrŽ   s   &r;   Útry_refresh_currentÚ"CredentialPool.try_refresh_currentQ	  s#   € Ø�Z�Z‹ZØ×5Ñ5Ó7÷ �Z�Z‹ZúrF  c               ó$   € V ^8„  d   QhRRRRRR/# )r6   rH  r}   r—  r7   rå  r9   )r:   s   "r;   r<   rñ  U	  s(   € ÷ 8ñ 8à#ð8ð %ð8ð 
$ñ	8r=   c                ó²  aa€ V P                   ;_uu_ 4        S'       d   V P                  V3R l4      MRpVfQ   S'       d   V P                  V3R l4      pM2V P                  4       ;'       g    V P                  RRR7      ^ ,          pVf    RRR4       R# VP                  V n        V P                  4       uuRRR4       #   + '       g   i     R# ; i)a=  Force-refresh the entry that supplied the failed request.

Direct integrations may reload the pool after a request failed, so
``current_id`` cannot identify the issuing credential. With no hint,
select WITHOUT the normal proactive refresh: the forced refresh below
must consume a rotating refresh token exactly once.
c                ó"   <€ V P                   S8H  # r�   re  r¢  s   &€r;   rM   Ú5CredentialPool.try_refresh_matching.<locals>.<lambda>b	  r¤  r=   Nc                ó"   <€ V P                   S8H  # r�   r¦  r§  s   &€r;   rM   rÜ  e	  s   ø€ °×1BÑ1BÀlÒ1Rr=   F)rq  r†  )rý  r9  r@  r\  rw   rø  rÖ  )r�   rH  r—  rä   s   &ff r;   Útry_refresh_matchingÚ#CredentialPool.try_refresh_matchingU	  sœ   ù€ ð �Z�Z‹ZßCP�D—J‘JÔ>Ô?ÐVZˆEØŠ}ßØ ŸJ™JÔ'RÓS‘Eà ×2Ñ2Ó4×lÐl¸×8MÑ8MÐV[ÐchÐ8MÓ8iÐjkÕ8l�EØŠ}Ø÷ ‰Zð  %Ÿx™xˆDÔØ×5Ñ5Ó7÷ �Z�Z‹Zús   —+CÁ,CÁ0 CÂ CÃC	c               ó   € V ^8„  d   QhRR/# r<  r9   )r:   s   "r;   r<   rñ  m	  s   € ÷ ñ Ð/Iñ r=   c                	ó‚   € V P                  4       pVf   R # V P                  VRR7      pVe   VP                  V n        V# )NTrÉ  )r@  rÑ  rw   rø  )r�   rä   rì  s   &  r;   rÖ  Ú,CredentialPool._try_refresh_current_unlockedm	  sE   € Ø×&Ñ&Ó(ˆØŠ=ÙØ×'Ñ'¨°TÐ'Ó:ˆ	ØÒ Ø(Ÿ|™|ˆDÔØÐr=   )rþ  r­  rø  r÷  r  rý  r   rù  rú  r  rj   r�   rW  )>rš   rÊ   rË   rÌ   ré  r  r  r  r'  rí   r%  r9  r@  rD  rK  rS  r^  rg  ro  rx  r  r‹  rž  Ú%_sync_anthropic_entry_from_pool_storer¬  r¶  r¾  rº  rÑ  rÏ  rß  rÍ  rø  r  r  rÌ  r  r  r  r  rK  rÎ  rW  rT  rU  ri  ro  r  r„  r\  r”  r�  rª  r±  rÀ  rÆ  rÄ  rÒ  r×  rÞ  rÖ  rÐ   r9   r=   r;   rª  rª  Æ  s  † õ1õ:'ð	#°d÷ 	#ð#À÷ #ð ;¸$÷  ;õD'õRõFõ>õ
,÷@õ"ð_ð ,0ð_ð 37÷	_ð@	À÷ 	õ3õ Gñ&!
ð ð!
ð )-÷!
ð !
õVõ<.ð` -HÐ)õNõ`!õF)dõVõ4*AòX
õ1
õfdõaõ>õ@	
õ.õ`iõVõ*\õ6Uõ*'õRð"	¨t÷ 	ð6¸4÷ 6õ4õ,	Xõ7ð,T*Ø',ðT*Ø>CðT*Ø\`÷T*õlVð$&Ø!%ð$&Ø59ð$&ØRV÷$&õL7ð
KÀD÷ 
Kõõ>%ðNLð 37ð	Lð
 '+ðLð (,ðLð )-ðLð  $÷L÷`õ$.õ,?õ8÷8÷0ñ r=   rª  c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r6   rí   rî   rj   rk   r{   rž   rf   r7   ræ   r9   )r:   s   "r;   r<   r<   {	  s2   € ÷ 1#ñ 1#Ð1ð 1#¸Sð 1#È#ð 1#ÐXfð 1#Ðkoñ 1#r=   c                ój  € \        V 4       UUu. uF  w  rEVP                  V8X  g   K  VNK  	  pppV'       d
   V^ ,          MRp\        VR,          4      pV'       d+   \        V 4       UUu. uF  w  rEWH9  g   K  VNK  	  uppV R&   Vf£   VP                  R\        P
                  ! 4       P                  R,          4       VP                  R\        V 4      4       TP                  RVP                  R4      ;'       g    T4       V P                  \        P                  W4      4       R# W,          p	/ p
/ p\        V	4       Uu0 uF  qÌP                  kK  	  ppVP                  R	4      pVRJ;'       d    WéP                  8g  pV'       dZ   V	P                  '       gH   V	P                  P                  R
4      p\!        V\"        4      '       d   V'       d   \%        V4      V8g  pVP'                  4        F�  w  ppVR9   g   Ve   VR8X  d   V	P(                  '       d   K,  VV9   d   \+        V	V4      V8w  d   VV
V&   KK  KM  V\,        9   g   KZ  V	P                  P                  V4      V8w  g   K|  VVV&   Kƒ  	  V'       d$   V	P.                  e   V
P1                  \2        4       V
'       g	   V'       d`   V'       d   / V	P                  CVCV
R&   \5        V	3/ V
B pVW&   \7        V4      ;'       g"    V	P9                  4       VP9                  4       8g  # \7        V4      # u uppi u uppi u upi )rÊ  N:r/  NNºNNNrw   r    rz   rx   Tr|   Úsecret_fingerprintr‹   >   rw   rz   )rQ  r{   r7  r¤   r¥   r¦   r§   rù   rC   rG  rv   r¯   r   r“   r|   r‹   rp   rk   r   r£   rx   r³   r—   r`   r²  rg   r	   ræ   r·   )rí   rj   r{   rž   rR  rä   Úmatching_indicesÚexisting_idxÚduplicate_indicesrÊ  r«  rµ  rª   Ú_field_namesÚincoming_tokenÚtoken_changedÚknown_fingerprintrØ   r¶   rÕ  s   &&&&                r;   Ú_upsert_entryrï  {	  s®  € Ü.7¸Ô.@Ô[Ñ.@¡
 ÀEÇLÁLÐTZÑDZŸ˜Ñ.@ÐÑ[ß*:Ð# AÖ&À€LÜÐ,¨RÕ0Ó1ÐßÜ.7¸Ô.@ÔaÑ.@¡
 ÀCÑD`—e�eÑ.@Òaˆ�‰
àÒØ×Ñ˜4¤§¢£×!1Ñ!1°"Õ!5Ô6Ø×Ñ˜:¤~°gÓ'>Ô?Ø×Ñ˜7 G§K¡K°Ó$8×$BÐ$B¸FÔCØ�‰Ô'×1Ñ1°(ÓDÔEÙàÕ$€HØ$&€MØ$&€MÜ$*¨8Ô$4Ó5Ñ$4˜q—F”FÑ$4€LÐ5Ø—[‘[ Ó0€NØ"¨$Ð.×ZÐZ°>×EZÑEZÑ3Z€Mß˜X×2×2Ð2ð %ŸN™N×.Ñ.Ð/CÓDÐÜÐ'¬×-Ò-×2CÜ4°^ÓDÐHYÑYˆMØ—m‘m–o‰
ˆˆUØÐ$Ô$¨ª¸#À¼.ÈXÏ^Ï^È^ÙØ�,ÔÜ�x Ó%¨Ô.Ø%*�˜cÓ"ñ /à”KÖ H§N¡N×$6Ñ$6°sÓ$;¸uÖ$DØ!&ˆM˜#Óñ &÷ ˜×-Ñ-Ò9Ø×Ñœ]Ô+ßŸßØ%H¨¯©Ð%H¸-Ð%HˆM˜'Ñ"Ü˜(Ñ4 mÑ4ˆØ 'ˆÑô Ð%Ó&×QÐQ¨(×*:Ñ*:Ó*<ÀÇÁÓ@QÑ*QÐQÜÐ!Ó"Ð"ùóa \ùó bùò 6s   �L$©L$Á-
L*Á<L*ÅL0zenv:ANTHROPIC_TOKENzenv:CLAUDE_CODE_OAUTH_TOKENr¬  zenv:ANTHROPIC_API_KEYc               ó$   € V ^8„  d   QhRRRRRR/# )r6   rj   rk   rí   rî   r7   ræ   r9   )r:   s   "r;   r<   r<   ¸	  s#   € ÷ ñ ¨ð Ð7Mð ÐRVñ r=   c                óf  € V R 8w  d   R# \        R V 4       R R7      p\        R V 4       R R7      p\        V4       UUu/ uF  w  rEVP                  VbK  	  pppRp\        . VOVO4       F9  w  r…VP                  V8w  g   K  \	        WXR7      WVP                  ,          &   RpK;  	  V# u uppi )	ro   Fc              3  ó`   "  € T F$  p\        VP                  4      '       g   K   Vx € K&  	  R # 5ir�   ©rÿ   r{   rò   s   & r;   rô   Ú-_normalize_pool_priorities.<locals>.<genexpr>¼	  s   é € ÐG™G�5Ô'8¸¿¹×'F�Š›Gùó   ‚.¤
.c                ó   € V P                   # r�   rñ   rô  s   &r;   rM   Ú,_normalize_pool_priorities.<locals>.<lambda>½	  s   € ˜%Ÿ.š.r=   rö  c              3  ó`   "  € T F$  p\        VP                  4      '       d   K   Vx € K&  	  R # 5ir�   ró  rò   s   & r;   rô   rô  À	  s   é € ÐK™G�5Ô+<¸U¿\¹\×+J�Š›Gùrõ  c                óŠ   € \         P                  V P                  \        \         4      4      V P                  V P
                  3# r�   )Ú_ANTHROPIC_SOURCE_RANKrC   r{   rA  rz   rx   rô  s   &r;   rM   r÷  Á	  s/   € Ü"×&Ñ& u§|¡|´SÔ9OÓ5PÓQØ�N‰NØ�K‰Kñ
r=   rñ   T)rZ  rQ  rw   rz   r	   )	rj   rí   Úmanual_entriesÚseeded_entriesrR  rä   Ú	id_to_idxrÑ  Únew_prioritys	   &&       r;   Ú_normalize_pool_prioritiesrÿ  ¸	  s¹   € Ø�;ÔÙÜÙG™GÓGÙ(ô€Nô ÙK™GÓKñ
ô€Nô 2;¸7Ô1CÔDÑ1C¡: 3�—‘˜3’Ñ1C€IÑDØ€GÜ(Ð)K¨>Ð)K¸NÐ)KÖLÑˆØ�>‰>˜\Ö)Ü+2°5Ô+PˆG˜eŸh™hÕ'Ñ(ØŠGñ  Mð €Nùó Es   ÁB-c               ó$   € V ^8„  d   QhRRRRRR/# )r6   rí   rî   Údroprk  r7   ræ   r9   )r:   s   "r;   r<   r<   Ð	  s"   € ÷ ñ Ð$:ð À(ð Ètñ r=   c                ó”   € V  Uu. uF  q"P                   V9  g   K  VNK  	  pp\        V4      \        V 4      8X  d   R# W0R&   R# u upi )zGRemove entries whose source is in *drop*; True if anything was removed.Fræ  T)r{   rA  )rí   r  rä   Úretaineds   &&  r;   Ú_retain_sources_not_inr  Ð	  sD   € á#*ÓG¡7˜%¯l©lÀ$Ñ.F—�¡7€HÐGÜ
ˆ8ƒ}œ˜G›Ô$ÙØˆA�JÙùò	 Hs
   …AœAc                  óH   € ] tR tRtRtR R ltR R lt]R R l4       tR	t	R
# )Ú_SeederiÙ	  zIAccumulates ``_upsert_entry`` results for one ``load_pool`` seeding pass.c               ó    € V ^8„  d   QhRRRR/# rð  r9   )r:   s   "r;   r<   Ú_Seeder.__annotate__Ü	  s   € ÷ 8ñ 8 ð 8Ð/Eñ 8r=   c                	óh   € Wn         W n        R V n        \        4       V n        \        4       V n        R# )FN)rj   rí   rÑ  r7  Úactive_sourcesrQ   Úis_suppressedr  s   &&&r;   ré  Ú_Seeder.__init__Ü	  s(   € Ø ŒØŒØˆŒÜ(+«ˆÔÜ5Ó7ˆÖr=   c               ó$   € V ^8„  d   QhRRRRRR/# )r6   r{   rk   rž   rf   r7   ræ   r9   )r:   s   "r;   r<   r  ã	  s!   € ÷ ñ ˜Sð ¨>ð ¸dñ r=   c                ó  € V P                  V P                  V4      '       d   R# V P                  P                  V4       \	        V P
                  V P                  VRV/VC4      pV ;P                  V,          un        V# )zPUpsert unless suppressed (``hermes auth remove`` must stay stable across loads).Fr{   )r  rj   r
  r:  rï  rí   rÑ  )r�   r{   rž   Úingesteds   &&& r;   ÚupsertÚ_Seeder.upsertã	  sg   € à×Ñ˜dŸm™m¨V×4Ò4ÙØ×Ñ×Ñ Ô'Ü  §¡¨t¯}©}¸fÀxÐQWÐFcÐ[bÐFcÓdˆØ�Š˜Õ �Øˆr=   c               ó   € V ^8„  d   QhRR/# )r6   r7   útuple[bool, set[str]]r9   )r:   s   "r;   r<   r  í	  s   € ÷ 1ñ 1Ð-ñ 1r=   c                	ó2   € V P                   V P                  3# r�   )rÑ  r
  rŽ   s   &r;   r´   Ú_Seeder.resultì	  s   € à�|‰|˜T×0Ñ0Ð0Ð0r=   )r
  rÑ  rí   r  rj   N)
rš   rÊ   rË   rÌ   rì  ré  r  rÏ   r´   rÐ   r9   r=   r;   r  r  Ù	  s#   † ÙSõ8õð ô1ó ô1r=   r  c               ó    € V ^8„  d   QhRRRR/# ©r6   Úseedr  r7   rŸ  r9   )r:   s   "r;   r<   r<   ñ	  s   € ÷ 3ñ 3 Wð 3°ñ 3r=   c                óD  a
€  ^ RI Hp V! R4      '       g   R#  \        4       o
R V
3R llpV! R4      ;'       g	    V! R4      pV! R4      '       d:   V'       g2   V ;P                  \        V P                  R	R
04      ,          un        R# ^ RIHpH	p ^ RI
Hp R	V! 4       3.pV! 4       '       d   VP                  R
V! 4       34       M.V ;P                  \        V P                  R
04      ,          un        V F�  w  r‰V	'       g   K  V	P                  R4      '       g   K(  V P                  VR\        RV	P                  RR4      RV	P                  R4      RV	P                  R4      R\!        V	P                  RR4      V4      /4       K’  	  R#   \         d     EL„i ; i)rÊ  ©Ú!is_provider_explicitly_configuredro   Nc               ó    € V ^8„  d   QhRRRR/# ©r6   rØ   rk   r7   r9   )r:   s   "r;   r<   Ú0_seed_anthropic_singletons.<locals>.__annotate__
  s   € ÷ Jñ J�cð J˜cñ Jr=   c                ó~   <€ SP                  V 4      ;'       g    \        V R 4      ;'       g    R P                  4       # )r¢   )rC   Ú_get_secretr½   )rØ   Ú	_env_files   &€r;   Ú_env_valÚ,_seed_anthropic_singletons.<locals>._env_val
  s2   ø€ Ø—‘˜cÓ"×@Ð@¤k°#°rÓ&:×@Ð@¸b×GÑGÓIÐIr=   ÚANTHROPIC_TOKENÚCLAUDE_CODE_OAUTH_TOKENÚANTHROPIC_API_KEYr¬  rá  )r„  Úread_hermes_oauth_credentials)Úadopt_external_logins_enabledr†  rm   r|   r¢   r~   r…  r„   r‡  rx   )rO   r  rP   r   rÑ  r  rí   r¯  r„  r'  Úagent.credential_sourcesr(  rG  rC   r  rr   rÙ   )r  r  r"  Úanthropic_oauth_envr„  r'  r(  rj  Úsource_namerˆ  r!  s   &         @r;   Ú_seed_anthropic_singletonsr,  ñ	  sk  ø€ ðÝEÙ0°×=Ò=Ùð >ô “
€I÷Jð Jñ #Ð#4Ó5×\Ð\¹ÐB[Ó9\ÐÙÐ#×$Ò$×-@ð 	�ŠÔ.¨t¯|©|¸mÈ]Ð=[Ó\Õ\�Ù÷õ GàÑ<Ó>Ð?Ð@€GÙ$×&Ò&Ø�‰˜Ñ'CÓ'EÐFÕGð 	�ŠÔ.¨t¯|©|¸m¸_ÓMÕM�Û%Ñˆß‰5�U—Y‘Y˜}×-Ô-Ø�K‰K˜Øœ_Ø §	¡	¨-¸Ó <Ø §¡¨>Ó!:Ø §¡¨;Ó!7ØÔ)¨%¯)©)°MÀ2Ó*FÈÓTð&ö ó &øôG ô Úðús   ƒF ÆFÆFc               ó$   € V ^8„  d   QhRRRRRR/# ©r6   r  r  r²  rf   r7   rŸ  r9   )r:   s   "r;   r<   r<   '
  s!   € ÷ !ñ !˜wð !°Nð !Àtñ !r=   c                ó<  € \        VR 4      w  r#\        VR V4      '       d   R# ^ RIHp V! V4      '       * ;'       dŽ    \	        \        V\        4      ;'       dm    \        VP                  R4      ;'       g    R4      P                  4       ;'       g3    \        VP                  R4      ;'       g    R4      P                  4       4      pV'       d8   V'       g0   V ;P                  \        V P                  RR04      ,          un
        V'       d	   V'       g   R# \        VP                  R4      ;'       g    R4      P                  4       pT P                  RR	\        RVP                  RR4      R
VP                  R
4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      /\         Uu/ uF  qwVP                  V4      bK  	  upCR\        VP                  R4      \        4      '       d   VP                  R4      MRRT;'       g    \!        VP                  RR4      R4      /C4       R# u upi )r»   N)Úguest_without_free_tierr|   r¢   r‡   rè   r£  rx   rm   r~   rƒ   r=  r¼   r;  r<  r†   rˆ   r>  )r,   r"   Úhermes_cli.anon_authr0  ræ   rp   rÞ   rk   rC   r½   rÑ  r  rí   r  rr   r³  rÙ   )r  r²  r  r»  r0  Úhas_runtime_materialÚcustom_labelrØ   s   &&      r;   Ú_seed_nous_singletonr4  '
  s$  € Ü9¸*ÀfÓMÑ€EÜ% j°&¸+×FÒFáÝ<Ù6°uÓ=Ô=÷ dð dÄ$ÄzÐRWÔY]ÓG^÷ Hcð HcÜˆE�I‰I�nÓ%×+Ð+¨Ó,×2Ñ2Ó4×aÐa¼¸E¿I¹IÀkÓ<R×<XÐ<XÐVXÓ8Y×8_Ñ8_Ó8aóCdÐç×)Ø�ŠÔ.¨t¯|©|¸mÐMaÐ=bÓcÕc�ß×*Ùô �u—y‘y Ó)×/Ð/¨RÓ0×6Ñ6Ó8€LØ‡K�K�Ø”_Ø˜Ÿ	™	 .°"Ó5Ø˜Ÿ™ ?Ó3Ø�e—i‘i Ó-Ø�e—i‘i Ó-Ø�—‘˜7Ó#Ø�U—Y‘Y˜{Ó+Ø˜5Ÿ9™9Ð%6Ó7Ø˜eŸi™iÐ(<Ó=Ø�U—Y‘Y˜{Ó+Ø §	¡	Ð*@Ó Að õ +AÓ
AÑ*@ 3�—	‘	˜#“ÒÑ*@Ñ
Að ð  	¤:¨e¯i©i¸Ó.>Ä×#EÒ#Eˆu�y‰y˜ÔÈ4Ø�×_Ð_Ô!1°%·)±)¸NÈBÓ2OÐQ^Ó!_ñ# ö ùò Bs   ÈJrk  Ú_COPILOT_RAW_DEGRADATION_WARNEDc               ó    € V ^8„  d   QhRRRR/# )r6   rl   rk   r7   rŸ  r9   )r:   s   "r;   r<   r<   O
  s   € ÷ 
ñ 
¨cð 
°dñ 
r=   c                óž   € \        V 4      ;'       g    RpV\        9   d   R# \        P                  V4       \        P	                  R4       R# )zVWARN once per token per process when Copilot exchange degrades to raw token (#114740).r0  Nz¤Copilot token exchange degraded to RAW token (exchange unavailable); enterprise-only models may 400 with model_not_available_for_integrator until exchange recovers.)r   r5  r:  r¤  rÛ  )rl   Úfingerprints   & r;   Ú"_warn_copilot_raw_degradation_oncer9  O
  s@   € ä*¨5Ó1×>Ð>°Y€KØÔ5Ô5ÙÜ#×'Ñ'¨Ô4Ü
‡N�Nð	För=   c               ó   € V ^8„  d   QhRR/# r  r9   )r:   s   "r;   r<   r<   \
  s   € ÷ ,ñ ,¨tñ ,r=   c                 ó.   € \         P                  4        R# )z9Clear the degradation warning cache (for test isolation).N)r5  Úclearr9   r=   r;   Ú%_reset_copilot_raw_degradation_warnedr=  \
  s   € ä#×)Ñ)Ö+r=   c               ó    € V ^8„  d   QhRRRR/# r  r9   )r:   s   "r;   r<   r<   a
  s   € ÷ 0;ñ 0; 'ð 0;¨dñ 0;r=   c                ó  a €  ^ RI HpHpHp R.V Uu. uF  pRV 2NK
  	  up,           p\        ;QJ d    V 3R lV 4       F  '       d   K   RM	  RM! V 3R lV 4       4      '       d   R# V! 4       w  rgV'       g   R# VR8X  d   RMRV 2pS P                  S P                  V4      '       d   R# ^ R	IHp	 V	! S P                  4      '       g   TRrºM#V! V4      w  r«W¦8X  d   V'       g   \        V4       \        P                  ! S P                  4      pS P                  TR
\        RT
RT;'       g    V'       d   VP                  MRRV/4       R# u upi   \         d"   p\         P#                  RT4        Rp?R# Rp?ii ; i)rÊ  )ÚCOPILOT_ENV_VARSÚresolve_copilot_tokenÚget_copilot_api_tokenÚgh_cliúenv:c              3  ó\   <"  € T F!  pSP                  SP                  V4      x € K#  	  R # 5ir�   )r  rj   )ró   r¼  r  s   & €r;   rô   Ú*_seed_copilot_singleton.<locals>.<genexpr>o
  s%   øé € ÐM¹_¸ˆt×!Ñ! $§-¡-°×3Ð3»_ùs   ƒ),FTNzgh auth tokenr  rm   r|   r‚   r¢   rx   zCopilot token seed failed: %s)Úhermes_cli.copilot_authr@  rA  rB  Úallr  rj   rO   r  r9  r$   rC   r  rs   r†   rD   r¤  r¥  )r  r@  rA  rB  r®   Úcopilot_sourcesrl   r{   r+  r  Ú	api_tokenÚenterprise_base_urlÚpconfigr¦  s   f             r;   Ú_seed_copilot_singletonrM  a
  sS  ø€ ð-;÷	
ñ 	
ð $˜*Ñ<LÓ'MÑ<L°q¨$¨q¨c«
Ñ<LÑ'MÕMˆß‹3ÔM¹_ÓM�3�3Š3ÔM¹_ÓM×MÒMÙÙ-Ó/‰ˆßÙð #)¨OÔ";‘hÀ4ÈÀxÀˆà×Ñ˜dŸm™m¨[×9Ò9ÙÝEÙ0°·±×?Ò?ð
 .3°DÑ*á-BÀ5Ó-IÑ*ˆIð
 Ô!×*=Ü2°5Ô9Ü#×'Ò'¨¯©Ó6ˆØ�‰�KØÔ*Ø˜IØÐ+×^Ð^Ïg°×0JÒ0JÐ[]Ø�Vð	"
ö 	ùò9 (NøôD ô ;Ü�‰Ð4°c×:Ò:ûð;ús]   ƒE “E¡E µE ÁE Á,E Á?/E Â1E ÃE Ã+AE Ä4E Ä=E ÅE ÅFÅ$F Æ Fc               ó    € V ^8„  d   QhRRRR/# r  r9   )r:   s   "r;   r<   r<   ”
  s   € ÷ >ñ >˜wð >¨4ñ >r=   c                ó~  €  ^ RI Hp V! RR7      pVP                  RR4      pV'       dd   VP                  RR4      pV P                  VR\        R	VR
VP                  R
4      RVP                  RR4      RVP                  RV4      /4       R# R#   \
         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)rÊ  )Ú resolve_qwen_runtime_credentialsF)Úrefresh_if_expiringrW   r¢   r{   zqwen-clirm   r|   r„   r‚   rx   Ú	auth_filez Qwen OAuth token seed failed: %sN)rO   rP  rC   r  rr   rD   r¤  r¥  )r  rP  rˆ  rl   r+  r¦  s   &     r;   Ú_seed_qwen_singletonrS  ”
  s«   € ð>ÝDÙ0ÀUÔKˆØ—	‘	˜) RÓ(ˆßØŸ)™) H¨jÓ9ˆKØ�K‰K˜Øœ_Ø Ø §¡¨?Ó!;Ø˜EŸI™I j°"Ó5Ø˜Ÿ™ ;°Ó<ð&ö ñ øô ô >Ü�‰Ð7¸×=Ò=ûð>ús   ‚(B «A!B ÂB<ÂB7Â7B<c               ó    € V ^8„  d   QhRRRR/# r  r9   )r:   s   "r;   r<   r<   ¨
  s   € ÷ Añ A 'ð A¨dñ Ar=   c                óÈ  €  ^ RI Hp V! R4      pV'       d   VP                  R4      '       g   R# Rp VP                  RR4      pV'       d5   \        \        P
                  ! V4      P                  4       R,          4      pT P                  RR	\        RTR,          R
TP                  R
4      RTR\        TP                  RR4      ;'       g    R4      P                  R4      RTP                  RR4      ;'       g    \        TP                  RR4      R4      /4       R#   \         d    Rp L¯i ; i  \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)rÊ  )Úget_provider_auth_stateúminimax-oauthr|   Nrƒ   r¢   iè  rV   rm   r~   r„   r‚   r†   rÆ   rx   z#MiniMax OAuth token seed failed: %s)rO   rV  rC   ry   r
   ÚfromisoformatÚ	timestamprD   r  rr   rk   rÇ   rÙ   r¤  r¥  )r  rV  r  r„   Úrawr¦  s   &     r;   Ú_seed_minimax_singletonr[  ¨
  s1  € ðAÝ;Ù'¨Ó8ˆß˜%Ÿ)™) N×3Ò3ÙØˆð	!Ø—)‘)˜L¨"Ó-ˆCßÜ #¤H×$:Ò$:¸3Ó$?×$IÑ$IÓ$KÈdÕ$RÓ S�ð 	�‰�GØœØ˜E .Õ1Ø˜UŸY™Y Ó7Ø˜]Øœ˜EŸI™IÐ&:¸BÓ?×EÐEÀ2ÓF×MÑMÈcÓRØ�U—Y‘Y˜w¨Ó+×gÐgÔ/?ÀÇ	Á	È.ÐZ\Ó@]Ð_fÓ/gð
ö 	øô ô 	!Ø ŠMð	!ûô ô AÜ�‰Ð:¸C×@Ò@ûðAúsW   ‚D5 ˜D5 ±D5 ´D" Á4D" ÂAD5 Ã.D5 Ã>"D5 Ä"D2Ä/D5 Ä1D2Ä2D5 Ä5E!Å EÅE!c               ó$   € V ^8„  d   QhRRRRRR/# r.  r9   )r:   s   "r;   r<   r<   Ã
  s!   € ÷ ñ  ð °nð Èñ r=   c                óÔ  € \        WP                  4      w  r#\        WP                  V4      '       d   R# \        V\        4      '       d   VP                  R4      MRp\        V\        4      '       d   VP                  R4      '       g   R# V P                  R8X  dD   \        P                  p\        VP                  R4      ;'       g    R4      P                  4       pM\        P                  pRpT P                  RR\        RVP                  RR4      R	VP                  R	4      R
TRVP                  R4      RT;'       g    \        VP                  RR4      R4      /4       R# )aa  Codex / xAI: surface the auth.json ``providers.<id>.tokens`` singleton as ``device_code``.

Hermes owns its own Codex auth state and does NOT auto-import
~/.codex/auth.json: refresh tokens are single-use, so sharing them with
Codex CLI / VS Code causes refresh_token_reused races. Adoption is an
explicit one-time prompt via `hermes auth openai-codex`.
Nr¢  r|   rÄ   rx   r¢   rè   rm   r~   r‚   r…   )r,   rj   r"   rp   rÞ   rC   r¾   ÚDEFAULT_CODEX_BASE_URLrk   r½   ÚDEFAULT_XAI_OAUTH_BASE_URLr  rr   rÙ   )r  r²  r  r»  r¢  r‚   r3  s   &&     r;   Ú_seed_tokens_singletonr`  Ã
  s  € ô :¸*ÇmÁmÓTÑ€EÜ% j·-±-À×MÒMÙÜ$.¨u´d×$;Ò$;ˆU�Y‰Y�xÔ À€FÜ�vœt×$Ò$¨¯©°N×)CÒ)CÙØ‡}�}˜Ô&Ü×2Ñ2ˆÜ˜5Ÿ9™9 WÓ-×3Ð3°Ó4×:Ñ:Ó<‰ä×6Ñ6ˆØˆØ‡K�K�Ø”_Ø˜Ÿ
™
 >°2Ó6Ø˜Ÿ™ OÓ4Ø�HØ˜Ÿ	™	 .Ó1Ø�×`Ð`Ô!1°&·*±*¸^ÈRÓ2PÐR_Ó!`ð ö r=   c               ó$   € V ^8„  d   QhRRRRRR/# ©r6   rj   rk   rí   rî   r7   r  r9   )r:   s   "r;   r<   r<   á
  s#   € ÷ ñ  Cð Ð2Hð ÐMbñ r=   c                óò  € \        W4      p\        4       pV R 8X  d   \        V4       VP                  # V R8X  d   \        W#4       VP                  # V R8X  d   \	        V4       VP                  # V R8X  d   \        V4       VP                  # V R8X  d   \        V4       VP                  # V \        9   d7   V R8X  d%   VP                  V R4      '       d   VP                  # \        W#4       VP                  # )ro   r»   Úcopilotz
qwen-oauthrW  rÄ   rè   )r  r*   r,  r4  rM  rS  r[  rÞ  r  r´   r`  )rj   rí   r  r²  s   &&  r;   Ú_seed_from_singletonsre  á
  së   € Ü�8Ó%€DÜ!Ó#€JØ�;ÔÜ" 4Ô(ð �;‰;Ðð 
�VÔ	Ü˜TÔ.ð �;‰;Ðð 
�YÔ	Ü Ô%ð �;‰;Ðð 
�\Ô	!Ü˜TÔ"ð �;‰;Ðð 
�_Ô	$Ü Ô%ð �;‰;Ðð 
Ô0Ô	0ð �~Ô%¨$×*<Ñ*<¸XÀ}×*UÒ*UØ—;‘;ÐÜ˜tÔ0Ø�;‰;Ðr=   c               ó    € V ^8„  d   QhRRRR/# r  r9   )r:   s   "r;   r<   r<   ÷
  s   € ÷ ñ ˜sð  sñ r=   c                óø   € \        4       pVP                  V R4      P                  4       p\        V R4      ;'       g    RP                  4       pVP	                  R4      '       d   V'       d   V# T;'       g    T# )aú  Resolve a credential env var, preferring ~/.hermes/.env over os.environ.

The user's config file is authoritative; stale env vars from parent
processes (Codex CLI, test scripts) must not override deliberate .env
changes. load_env() memoizes on mtime, so per-call reads cost a stat().
An unresolved ``op://`` reference in .env yields to the already-resolved
value from the active secret scope (set by apply_onepassword_secrets());
otherwise every provider auth attempt would receive a URL instead of a key.
r¢   zop://)r   rC   r½   r   rq   )rØ   Úenv_filerZ  Úscoped_values   &   r;   Úget_env_prefer_dotenvrj  ÷
  sf   € ô ‹z€HØ
�,‰,�s˜BÓ
×
%Ñ
%Ó
'€CÜ  RÓ(×.Ð.¨B×5Ñ5Ó7€LØ
‡~�~�g×Ò§<ØÐØ×Ð�,Ðr=   Ú_ENV_INGESTION_WARNEDc               ó$   € V ^8„  d   QhRRRRRR/# )r6   rj   rk   rè  r7   rŸ  r9   )r:   s   "r;   r<   r<     s!   € ÷ ñ  sð °Sð ¸Tñ r=   c                óŽ   € V \         9   d   R# \         P                  V 4       \        P                  RTT V R8X  d   RMT V 4       R# )u>  WARN once per process per provider when an env credential is ingested into a paid pool.

Auto-ingesting OPENROUTER_API_KEY is what ARMS silent OpenRouter spend â€”
every downstream auto-detect keys off the pool having credentials.
Ingestion stays allowed (an exported key is arguable intent) but must
never be silent.
Nu�   Ingested %s from environment into the %s credential pool â€” this enables %s spend. Remove the key or run hermes auth remove %s <n> to suppress.Ú
openrouterÚ
OpenRouter)rk  r:  r¤  rÛ  )rj   rè  s   &&r;   Ú_warn_env_ingestion_oncerp    sF   € ð Ô(Ô(ÙÜ×Ñ˜hÔ'Ü
‡N�Nð	1ð 	ØØ  LÔ0‰°hØör=   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r6   rè  rk   rl   r‚   r7   rf   r9   )r:   s   "r;   r<   r<   $  s(   € ÷ ñ ˜Sð ¨ð ¸ð Àñ r=   c                óÄ   € R \         RVRVRV /p ^ RIHp V! V 4      pV'       d   \	        V4      P                  4       MRpV'       d   WcR&   V#   \         d    Rp L@i ; i)rm   r|   r‚   rx   )Úget_secret_sourceNÚsecret_source)rs   Úhermes_cli.env_loaderrs  rD   rk   r½   )rè  rl   r‚   rž   rs  Úsource_labelrt  s   $$$    r;   Ú_env_payloadrw  $  so   € àÔ&Ø˜Ø�HØ�ð	€GðÝ;Ù(¨Ó1ˆ÷ 2>”C˜Ó%×+Ñ+Ô-À4€MßØ#0�Ñ Ø€Nøô ô ØŠðús   �A ÁAÁAzkimi-codingÚzaic               ó$   € V ^8„  d   QhRRRRRR/# )r6   Úenv_varsrE  rí   rî   r7   r9   )r:   s   "r;   r<   r<   =  s#   € ÷ ñ  ið Ð:Pð ÐU^ñ r=   c                ó   € \        V 4      pV  F<  p^p\        V RV 24      '       g   K  VP                  V RV 24       V^,          pK9  	  V Fz  pVP                  P	                  R4      '       g   K&  VP                  P                  R^4      ^,          P                  4       pV'       g   Ka  Wb9  g   Ki  VP                  V4       K|  	  V# )a9  *env_vars*, their numbered siblings, and the ``env:VAR`` names already persisted.

``VAR_2``, ``VAR_3``, ... are tried for every declared VAR until the first
one that does not resolve, so a `.env` or secret-manager project can back a
whole rotation pool with no config: setting ``NVIDIA_API_KEY_2`` is the
whole opt-in (#76593).

Env-backed rows are written to auth.json without their secret and
re-hydrated on every load; a row whose VAR the registry does not
declare would otherwise stay empty forever and be silently dropped
from rotation by ``_available_entries``.
r"  rD  rü   )rW  rj  rG  r{   rq   Úsplitr½   )rz  rí   Únamesr  Únrä   Úenv_names   &&     r;   Ú_env_key_var_candidatesr€  =  s²   € ô �‹N€EÛˆØˆÜ# t f¨A¨a¨S M×2Ô2Ø�L‰L˜D˜6  1 #˜Ô'Ø��FŠAñ	 ó
 ˆØ�<‰<×"Ñ" 6×*Ô*Ø—|‘|×)Ñ)¨#¨qÓ1°!Õ4×:Ñ:Ó<ˆHß‰x˜HÖ1Ø—‘˜XÖ&ñ	 ð
 €Lr=   c               ó$   € V ^8„  d   QhRRRRRR/# rb  r9   )r:   s   "r;   r<   r<   X  s#   € ÷ )ñ )˜Sð )Ð+Að )ÐF[ñ )r=   c           
     ó€  € \        W4      pV R 8X  d   VP                  # V R8X  dm   \        R.V4       FO  p\        V4      pV'       g   K  VP	                  RV 2\        W4\        R7      4      '       g   KD  \        W4       KQ  	  VP                  # \        P                  ! V 4      pV'       d   VP                  \        8w  d   VP                  # RpVP                  '       d%   \        VP                  4      P                  R4      p\        VP                  4      pV R8X  d   . ROp\        Wq4      p\         P                  V 4      pV Fe  p\        V4      pV'       g   K  T;'       g    VP"                  p	Ve   V! WEP"                  V4      p	VP	                  RV 2\        W4V	R7      4       Kg  	  VP                  # )	rd  rn  ÚOPENROUTER_API_KEYrD  )rè  rl   r‚   r¢   rÆ   ro   )r$  r%  r&  )r  r´   r€  rj  r  rw  r   rp  r$   rC   rm   rs   Úbase_url_env_varrÇ   rW  Úapi_key_env_varsÚ_ENV_BASE_URL_RESOLVERSr†   )
rj   rí   r  rè  rl   rL  Úenv_urlrz  Úresolve_base_urlr‚   s
   &&        r;   Ú_seed_from_envr‰  X  s…  € Ü�8Ó%€Dð
 �9ÔØ�{‰{Ðà�<ÔÜ.Ð0DÐ/EÀwÖOˆGÜ)¨'Ó2ˆEß‰u˜Ÿ™Ø�w�iÐ Ü WÔDWÔX÷ô ô )¨Ö;ñ Pð �{‰{Ðä×#Ò# HÓ-€Gß�g×'Ñ'Ô+<Ô<Ø�{‰{Ðà€GØ××ÐÜ'¨×(@Ñ(@ÓA×HÑHÈÓMˆä�G×,Ñ,Ó-€HØ�;ÔÚVˆÜ& xÓ9€Hä.×2Ñ2°8Ó<ÐÛˆÜ% gÓ.ˆßÙØ×8Ð8˜g×8Ñ8ˆØÒ'Ù'¨×/IÑ/IÈ7ÓSˆHØ�‰�d˜7˜)Ð$¤l¸7ÐZbÔ&cÖdñ ð �;‰;Ðr=   Úprune_env_sourcesTc               ó(   € V ^8„  d   QhRRRRRRRR/# )r6   rí   rî   r
  rk  rŠ  ræ   r7   r9   )r:   s   "r;   r<   r<   „  s0   € ÷ ñ Ø#ðàðð ð	ð
 
ñr=   c               óü   a€ R  V3R llpV  Uu. uFA  p\        VP                  4      '       g"   VP                  V9   g   V! V4      '       d   K?  VNKC  	  pp\        V4      \        V 4      8X  d   R# WPR&   R# u upi )c               ó    € V ^8„  d   QhRRRR/# rC  r9   )r:   s   "r;   r<   Ú1_prune_stale_seeded_entries.<locals>.__annotate__Š  s   € ÷ lñ lÐ,ð l°ñ lr=   c                ó¸   <€ V P                   P                  R 4      '       d   S# \        V P                   V P                  4      ;'       g    V P                   R8H  # )rD  r¬  )r{   rq   r    rj   )rä   rŠ  s   &€r;   Ú_is_prunableÚ1_prune_stale_seeded_entries.<locals>._is_prunableŠ  sG   ø€ ð
 �<‰<×"Ñ" 6×*Ò*Ø$Ð$ä,¨U¯\©\¸5¿>¹>ÓJ×kÐkÈeÏlÉlÐ^kÑNkÐkr=   Fræ  T)rÿ   r{   rA  )rí   r
  rŠ  r�  rä   r  s   &&d   r;   Ú_prune_stale_seeded_entriesr’  „  sz   ø€ ÷lð lñ óáˆEÜ˜UŸ\™\×*Ò*¨e¯l©l¸nÔ.LÑT`Ðaf×Tg÷ 	ˆÙð ð ô
 ˆ8ƒ}œ˜G›Ô$ÙØˆA�JÙùòs   �<A9ÁA9c               ó$   € V ^8„  d   QhRRRRRR/# )r6   r]  rk   rí   rî   r7   r  r9   )r:   s   "r;   r<   r<   Ÿ  s#   € ÷ -ñ - ð -Ð.Dð -ÐI^ñ -r=   c                óJ  a€ \        W4      p\        V 4      pV'       d³   \        VP                  R4      ;'       g    R4      P	                  4       p\        VP                  R4      ;'       g    R4      P	                  4       pV'       dG   TP                  RV 2R\        RTR\        VP                  R4      4      RT;'       g    RV 2/4        \        4       pV'       d   VP                  R	4      MR
o\        S\        4      '       dë   \        SP                  R4      ;'       g    R4      P	                  4       P                  4       p\        SP                  R4      4      p\        V3R lR 4       R4      p	VR8X  dt   V'       dl   V	'       dd   \        V4       U
u0 uF*  p
\        V
4      P	                  4       P                  4       kK,  	  pp
W9   d   VP                  RR\        RV	RVRR/4       VP                  # u up
i   \         d     TP                  # i ; i)zJSeed a custom endpoint pool from custom_providers config and model config.rW   r¢   r“   zconfig:rm   r|   r‚   rx   r  Nrj   c              3  óÆ   <"  € T FV  pSP                  V4      p\        V\        4      '       g   K,  VP                  4       '       g   KD  VP                  4       x € KX  	  R # 5ir�   )rC   rp   rk   r½   )ró   r¬   r®   Ú	model_cfgs   &  €r;   rô   Ú$_seed_custom_pool.<locals>.<genexpr>·  sD   øé € ÐxÑ$6˜qÀÇÁÈqÓAQ¸1ÔWaÐbcÔeh×Wi”Ðno×nuÑnu×nw”�—‘—�Ó$6ùs   ƒ)A!±A!Á	A!ro  Úmodel_config)rW   Úapi)r  rb  rk   rC   r½   r  rs   r.  rE   rp   rÞ   rý   ra  rO  rD   r´   )r]  rí   r  Ú	cp_configrW   r“   r0  Úmodel_providerÚmodel_base_urlÚmodel_api_keyrØ   Úmatched_keysr–  s   &&          @r;   Ú_seed_custom_poolrŸ  Ÿ  sÚ  ø€ ä�8Ó%€Dä+¨HÓ5€IßÜ�i—m‘m IÓ.×4Ð4°"Ó5×;Ñ;Ó=ˆÜ�9—=‘= Ó(×.Ð.¨BÓ/×5Ñ5Ó7ˆßØ�K‰K˜' $ Ð(ØÔ.Ø ØœI i§m¡m°JÓ&?Ó@Ø˜×1Ð1 7¨4¨&Ð!1ð	+ô ðÜ"Ó$ˆß+1�F—J‘J˜wÔ'°tˆ	Ü�i¤×&Ò&Ü  §¡¨zÓ!:×!@Ð!@¸bÓA×GÑGÓI×OÑOÓQˆNÜ& y§}¡}°ZÓ'@ÓAˆNÜ ÜxÑ$6ÓxØóˆMð  Ô)¯nÇô 9\Ð\jÔ8kó Ù8k°”C˜“H—N‘NÓ$×*Ñ*Ö,Ñ8kð ð  ð Ô+Ø—K‘K Ø#Ô%6Ø&¨Ø" NØ ð	1ô ð �;‰;Ðùò øô ô Øà�;‰;Ððús8   ÃAH	 Ä+A!H	 ÆH	 ÆH	 Æ"0HÇ&H	 ÈH	 È	H"È!H"c               ó    € V ^8„  d   QhRRRR/# )r6   rj   rk   r7   rª  r9   )r:   s   "r;   r<   r<   Ï  s   € ÷ Jñ J˜ð J ñ Jr=   c           	     ó*  a € S ;'       g    R P                  4       P                  4       o S \        9   d   \        P                  ! S 4       \        S 4      pV Uu0 uFE  p\        V\        4      '       g   K  VP                  R4      '       g   K4  VP                  R4      kKG  	  ppRp\        ;QJ d    V 3R lV 4       F  '       g   K   RM	  RM! V 3R lV 4       4      pV Uu. uF  p\        P                  S V4      NK  	  pp\        ;QJ d    V 3R lV 4       F  '       g   K   RM	  RM! V 3R lV 4       4      pV'       dU   \        4       P                  R4      p	\        V	\        4      '       d   V	P                  S 4      MRp
V\        V
4      ,          pS P                  \        4      '       d*   \!        S V4      w  r¼W[,          pV\#        W|4      ,          pMð\%        S V4      w  rÞ\'        S V4      w  ppY];'       g    T,          pS \        9   d   V'       d   \)        S 4      pVRJ dp   V Uu. uF  q"P*                  V9   g   K  VNK  	  ppV Uu. uF  q"P*                  V9  g   K  VNK  	  ppV\#        VVV,          RR7      ,          pVV,           VR	&   MV\#        W~V,          RR7      ,          pV\-        S V4      ,          p\/        S V4      p\        P0                  ! V4      Vn        V'       d<   TP5                  \7        Y7 Uu0 uF  pVP*                  kK  	  up,
          4      R
7       S \        9   d4   V'       d,   V'       d   \)        S 4      pV'       g   \9        V4      Vn        V# u upi u upi u upi u upi u upi )r¢   rw   Nc              3  ór   <"  € T F,  p\        V\        4      ;'       d    \        VS4      V8g  x € K.  	  R # 5ir�   )rp   rÞ   r!   ©ró   rž   rj   s   & €r;   rô   Úload_pool.<locals>.<genexpr>Ù  s9   øé € ð á"ˆGô 	�7œDÓ!×hÐhÔ&JÈ7ÐT\Ó&]ÐahÑ&hÔhÛ"ùs   ƒ7Ÿ7TFc           	   3  óâ   <"  € T Fd  p\        V\        4      ;'       dH    \        SVP                  R 4      VP                  R\        4      4      VP                  R\        4      8g  x € Kf  	  R# 5i)r|   rm   N)rp   rÞ   rt   rC   rs   r£  s   & €r;   rô   r¤  Þ  sj   øé € ð 'ñ
 #ˆGô	 	�7œDÓ!÷ 	9ð 	9Ü%Ø�g—k‘k .Ó1°7·;±;¸{ÔL]Ó3^ó
à�[‰[˜Ô&7Ó8ñ9ô	9ó #ùs   ƒA/ŸAA/r´  )rŠ  ræ  rm  )r½   rý   r%   r¾   Ú#heal_forked_single_use_oauth_grantsr3   rp   rÞ   rC   rY  rv   r¯   r*   ræ   rq   r@  rŸ  r’  re  r‰  r¸  rw   rÿ  rª  rX  rù  r^  rZ  r7  r­  )rj   Úraw_entriesr0  Údisk_idsÚowns_providerrÑ  rž   rí   Úraw_needs_auth_normalizationÚactive_poolÚactive_entriesÚcustom_changedÚcustom_sourcesÚsingleton_changedÚsingleton_sourcesÚenv_changedÚenv_sourcesÚborrowedÚothersr©  rä   s   f                    r;   Ú	load_poolrµ  Ï  s  ø€ Ø—�˜B×%Ñ%Ó'×-Ñ-Ó/€HØÔ4Ô4ô 	×4Ò4°XÔ>Ü& xÓ0€KÙ%0ÓX¡[ ´J¸qÄ$×4G”ÈAÏEÉEÐRVÏK”�—‘�d–¡[€HÐXà$(€Mß‹cô á"ó�c�cŠcô á"óó €Gñ MXÓXÉKÀÔ×)Ñ)¨(°GÖ<ÉK€GÐXß#&£3ô 'ñ
 #ó'§3§3¢3ô 'ñ
 #ó'ó $Ð ÷ $ô 'Ó(×,Ñ,Ð->Ó?ˆÜ6@ÀÌd×6SÒ6S˜Ÿ™¨Ô2ÐY]ˆØ”4˜Ó'Õ'ˆà×ÑÔ-×.Ò.Ü):¸8ÀWÓ)MÑ&ˆØÕ!ˆØÔ.¨wÓGÕG‰ä/DÀXÈwÓ/WÑ,ÐÜ#1°(¸GÓ#DÑ ˆ�[Ø×3Ð3¨Õ3ˆð Ô8Ô8¿XÜ7¸ÓAˆMØ˜EÓ!ñ
 $+Ó?¡7˜a¯d©d°hÑ.>Ÿ˜¡7ˆHÐ?Ù!(ÓA¡˜A¯D©D¸Ñ,@—a�a¡ˆFÐAØÔ2ØÐ)¨KÕ7È5ôõ ˆGð " FÕ*ˆG�AŠJàÔ2Ø¨[Õ8ÈEôõ ˆGð 	Ô-¨h¸Ó@Õ@ˆä˜( GÓ,€DÜ"*×"=Ò"=¸kÓ"J€DÔßØ�‰¤&¨È7Ó4SÉ7À%°U·X´XÉ7Ñ4SÕ)SÓ"TˆÔUð Ô4Ô4¿÷ Ü7¸ÓAˆMßÜ&)¨(£mˆDÔ#Ø€KùòG Yùò YùòB @ùÚAùò 5Ts6   ÁM<Á7M<ÂM<Ã'NÈ9NÉNÉNÉ3NÌN>   r,  Úinvalid_tokenÚtoken_revokedÚtoken_invalidatedÚunauthorized_clientÚrefresh_token_reusedi€Q i,  i  >   r>  r¼   Úorg_idÚuser_idr;  Ú
anon_tokenÚ
expires_inr=  Úauth_methodÚobtained_atÚaccount_tierÚagent_key_idrt  r_   r<  Úagent_key_reusedrç  Úagent_key_expires_inÚagent_key_obtained_at)rÀ  r¾  rÂ  rÄ  rÃ  rÅ  r¿  rÁ  r½  r¼  r»  r�   rW  )ÚCodexrÆ  Úrefresh_codex_oauth_pureÚ&_is_terminal_codex_oauth_refresh_error)z	xAI OAuthr�  Úrefresh_xai_oauth_pureÚ$_is_terminal_xai_oauth_refresh_error)rÄ   rÝ  ro   )¸Ú__conditional_annotations__rì  Ú
__future__r   Úagent.credential_pool_adminr   Ú%agent.credential_pool_model_cooldownsr   r   Ú agent.credential_pool_timestampsr   Úloggingr•  r[   rû  r  r¥   ÚreÚdataclassesr   r   r	   r
   r   r   Úpathlibr   Útypingr   r   r   r   r   r   r   r   Úhermes_constantsr   rA   r   Úagent.secret_scoper   r   r   Úagent.retry_utilsr   Ú hermes_cli.auth_plugin_providersr   Úagent.credential_pool_pluginr   r   r   Úagent.credential_persistencer   r    r!   rO   Úauthr¾   Úhermes_cli.auth_oauth_grantsr"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   Ú	getLoggerrš   r¤  rE   rQ   r  r$  r#  Ú	frozensetrv  ru  rw  rr   rs   r¨   ré   rf  r�  r�  r�  rg  r  r  r  r
  r  r  r‚  r@  r—   r³  rg   rÍ   rh   rt   rv   rÙ   râ   rë   rù   rÿ   r  r  r!  r%  r*  r.  r4  r<  rC  rI  rO  rS  r[  rb  rj  rt  rx  r~  r„  rŽ  rÿ  rœ  r§  r°  rµ  r¸  r»  rÖ  rÜ  rÞ  ÚREFRESHABLE_OAUTH_PROVIDERSrË  rb  rå  rm  rD   rã  rª  rï  rú  rÿ  r  r  r,  r4  r7  r5  r9  r=  rM  rS  r[  r`  re  rj  rk  rp  rw  r†  r€  r‰  r’  rŸ  rµ  )rË  s   @r;   Ú<module>rà     s]  øðÜ Bå "å @ß hÝ Fã Û 	Û Û Û Û Û 	ß 2Ñ 2ß ,Ñ ,Ý ß L× LÓ Lå 0Ý &ß HÝ 6Ý @ß {Ñ {÷ñ õ
 #Ý G÷÷ ÷ ÷ ÷ ð* 
×	Ò	˜8Ó	$€õ	õ$ð €	ØÐ ð
 €ñ #ò $ó Ð ð $?Ð  ð !-Ð à€ØÐ à€Ø,˜o¨\Ð:Ð à"Ð Ø$Ð Ø€Ø"Ð àØØØð	Ð ð #Ð Ø#Ð Ø 'Ð ð )+Ð %ð #Ð ð %9Ð !ð -1Ð )ð Ð ñ ò ó €ðÐ ð �4Ø�dØ�tØ˜Ø˜$Ø˜4ð!€ˆ~ó ð G˜mÐF¨]¸IÑF€ˆ.Ó Fõ/ð ÷kð kó ðkõ\õ/õ"|õ"FõUð
ð "ðð %)÷	õ<õ"ð0È÷ õ$2õ
.÷Dõ"õõ÷@÷1õõgõVõõ8õ6Uð,Rð #÷	,Rõ^ðD )*Ð %õõ0cõ@õ7õ;õ"	ð)à59ð)ð 9=÷)ðX'ð ,0ð	'ð
 37ð'ð 9=÷'ðb ÐlØÐgðEÐ ÐAó ñ (¨°fÐ([Ð?ZÐ([Ó\Ð ð !KÐ ð "%Ð ð Ð:ØÐ5ðÐ ð �Ø
ˆMØ�MØ�ð	€ô�9ô ônÐ-Ð/Oô nõj-1#ðj ˜1Ø! 1Ø�1Ø�1Ø˜QðÐ õõ0÷1ñ 1õ03õl!ñJ -0«EÐ  Ó 1õ
õ,õ
0;õf>õ(Aõ6õ<õ,ñ( #&£%Ð �xÓ 'õõ,ð( Ð)Ø	Ð ðÐ õõ6)ðXð #÷	õ6-÷`Jr=   