+
    i9                       R 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 ^ RI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HtHtH t H!t!H"t"H#t#H$t$H%t%H&t&H't'H(t( ]PR                  ! ]*4      t+R R	 lt,R
t-Rt.Rt/Rt0Rt1Rt2Rt3Rt4Rt5]2]3]4]50t6RBt7RCt8Rt9]:! 0 RDm4      t;] ! R R4      4       t<R R lt=R R lt>R R lt?R R lt@R R ltAR  R! ltBR" R# ltCR$ R% ltDR& R' ltERER( R) lltFR* R+ ltGR, R- ltHR. R/ ltIR0 R1 ltJ ! R2 R34      tKR4 R5 ltLR6 R7 ltMR8 R9 ltNR: R; ltOR< R= ltPR> R? ltQR@ RA ltRR# )Fz<Persistent multi-credential pool for same-provider failover.)annotationsN)	dataclassfieldsreplace)datetimetimezone)AnyDictListOptionalSetTuple)OPENROUTER_BASE_URL)!ACCESS_TOKEN_REFRESH_SKEW_SECONDS'CODEX_ACCESS_TOKEN_REFRESH_SKEW_SECONDS!DEFAULT_AGENT_KEY_MIN_TTL_SECONDSPROVIDER_REGISTRY_agent_key_is_usable_codex_access_token_is_expiring_decode_jwt_claims_import_codex_cli_tokens_is_expiring_load_auth_store_load_provider_stateread_credential_poolwrite_credential_poolc                   V ^8  d   QhRR/# )   returnOptional[dict] )formats   "2/home/ubuntu/hermes-agent/agent/credential_pool.py__annotate__r#   %   s      >     c                 B     ^ RI Hp  V ! 4       #   \         d     R# i ; i)z.Load config.yaml, returning None on any error.load_configN)hermes_cli.configr'   	Exceptionr&   s    r"   _load_config_safer*   %   s$    1} s    ok	exhaustedoauthapi_keymanual
fill_firstround_robinrandom
least_usedzcustom:c                     ] tR t^Xt$ 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&   ^ 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
# )+PooledCredentialstrprovideridlabel	auth_typeintprioritysourceaccess_tokenNOptional[str]refresh_tokenlast_statusOptional[float]last_status_atOptional[int]last_error_codelast_error_reasonlast_error_messagelast_error_reset_atbase_url
expires_atexpires_at_mslast_refreshinference_base_url	agent_keyagent_key_expires_atrequest_countDict[str, Any]extrac                	4    V P                   f
   / V n         R # R # NrR   selfs   &r"   __post_init__PooledCredential.__post_init__r   s    ::DJ r$   c                   V ^8  d   QhRR/# )r   namer6   r    )r!   s   "r"   r#   PooledCredential.__annotate__v   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_KEYSrR   getAttributeErrortype__name__)rW   r[   s   &&r"   __getattr__PooledCredential.__getattr__v   sB    ;::>>$''qd!4!4 55OPTxXYYr$   c               $    V ^8  d   QhRRRRRR/# )r   r7   r6   payloadrQ   r   z'PooledCredential'r    )r!   s   "r"   r#   r\   |   s"     . . .~ .BT .r$   c                	   \        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\         Uu/ uF   qUV9   g   K  W%,          f   K  WRV,          bK"  	  ppWvR&   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i )r7   rR   r8   N   Nr9   r=   r:   r<   r>    r    )
r   r[   r`   r_   
setdefaultuuiduuid4hexAUTH_TYPE_API_KEYSOURCE_MANUAL)clsr7   rg   ffield_nameskdatarR   s   &&&     r"   	from_dictPooledCredential.from_dict{   s   '-c{K{!ff
6Jvqvv{K+6G;aw,!;;q>!;G(3_1G|
AJ_Wdjjl..r23Xx!@A%67
A&-0+-H--- LG_s'   EEE
E
'E4E Ec                   V ^8  d   QhRR/# )r   r   rQ   r    )r!   s   "r"   r#   r\      s       r$   c                	*   0 Rmp/ p\        V 4       FP  pVP                  R9   d   K  \        WP                  4      pVf   VP                  V9   g   KB  WBVP                  &   KR  	  V P                  P	                  4        F  w  rVVf   K  WbV&   K  	  V# )rA   >   rA   rC   rE   rF   rG   rH   )r7   rR   )r   r[   getattrrR   items)rW   _ALWAYS_EMITresult	field_defvalueru   vs   &      r"   to_dictPooledCredential.to_dict   s    
 "$I~~!66D..1E INNl$B).y~~& & JJ$$&DA}q	 ' r$   c                   V ^8  d   QhRR/# )r   r   r6   r    )r!   s   "r"   r#   r\      s     , , ,r$   c                	    V P                   R 8X  d4   \        V P                  ;'       g    V P                  ;'       g    R4      # \        V P                  ;'       g    R4      # )nousrk   )r7   r6   rN   r>   rV   s   &r"   runtime_api_key PooledCredential.runtime_api_key   sL    ==F"t~~@@):):@@bAA4$$**++r$   c                   V ^8  d   QhRR/# )r   r   r?   r    )r!   s   "r"   r#   r\      s      - r$   c                	|    V P                   R 8X  d!   V P                  ;'       g    V P                  # V P                  # )r   )r7   rM   rI   rV   s   &r"   runtime_base_url!PooledCredential.runtime_base_url   s0    ==F"**;;dmm;}}r$   rU   )rc   
__module____qualname____firstlineno____annotations__r@   rA   rC   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rR   rX   rd   classmethodrw   r   propertyr   r   __static_attributes__r    r$   r"   r5   r5   X   s   MGJNMK#'M='!%K%&*NO*%)O])'+}+(,,+//"Hm" $J$#'M='"&L-&(,,#I}#*.-.M3 E> Z
 . .* , ,
  r$   r5   c               $    V ^8  d   QhRRRRRR/# )r   tokenr6   fallbackr   r    )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   r`   
isinstancer6   strip)r   r   claimskeyr   s   &&   r"   label_from_tokenr      sM    &F5

3eS!!ekkmm;;=  6 Or$   c                    V ^8  d   QhRRRR/# )r   entriesList[PooledCredential]r   r;   r    )r!   s   "r"   r#   r#      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rT   r<   .0entrys   & r"   	<genexpr>!_next_priority.<locals>.<genexpr>   s     4G5Gs   )default)max)r   s   &r"   _next_priorityr      s    4G4bAAEEr$   c                    V ^8  d   QhRRRR/# )r   r=   r6   r   boolr    )r!   s   "r"   r#   r#      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      # )rk   :)r   lowerrq   
startswith)r=   
normalizeds   & r"   _is_manual_sourcer      sE    ,,B%%'--/J&TT**?*?=/QR@S*TTr$   c                    V ^8  d   QhRRRR/# )r   
error_coderD   r   r;   r    )r!   s   "r"   r#   r#      s     ) )} ) )r$   c                (    V R8X  d   \         # \        # )zHReturn cooldown seconds based on the HTTP status that caused exhaustion.i  )EXHAUSTED_TTL_429_SECONDSEXHAUSTED_TTL_DEFAULT_SECONDS)r   s   &r"   _exhausted_ttlr      s    S((((r$   c                    V ^8  d   QhRRRR/# )r   r   r   r   rB   r    )r!   s   "r"   r#   r#      s      S _ r$   c                   V e   V R8X  d   R# \        V \        \        34      '       d'   \        V 4      pV^ 8:  d   R# VR8  d
   VR,          # T# \        V \        4      '       dr   V P	                  4       pV'       g   R#  \        V4      pVe   VR8  d
   VR,          # T#  \        P                  ! VP                  RR4      4      P                  4       # R#   \
         d    Rp L\i ; i  \
         d     R# i ; i)zBest-effort parse for provider reset timestamps.

Accepts epoch seconds, epoch milliseconds, and ISO-8601 strings.
Returns seconds since epoch.
Nrk   l    J)     @@Zz+00:00)
r   r;   floatr6   r   
ValueErrorr   fromisoformatr   	timestamp)r   numericraws   &  r"   _parse_absolute_timestampr      s     }%#u&&,a<#*->#>wKGK%kkm	CjG '.1B'B7V#OO	))#++c8*DEOOQQ   	G	  		s$   C #3C, C)(C),C;:C;c                    V ^8  d   QhRRRR/# )r   messager6   r   rB   r    )r!   s   "r"   r#   r#      s     
 
# 
/ 
r$   c                   V '       g   R # \         P                  ! RV \         P                  4      pV'       dJ   \        VP	                  ^4      4      pVP	                  ^4      P                  4       R8X  d
   VR,          # T# \         P                  ! RV \         P                  4      pV'       d   \        VP	                  ^4      4      # R # )Nz,quotaResetDelay[:\s\"]+(\d+(?:\.\d+)?)(ms|s)msr   z?retry\s+(?:after\s+)?(\d+(?:\.\d+)?)\s*(?:sec|secs|seconds|s\b))research
IGNORECASEr   groupr   )r   delay_matchr   	sec_matchs   &   r"   _extract_retry_delay_secondsr      s    ))KWVXVcVcdKk''*+!,!2!21!5!;!;!=!Euv~P5P		\^egigtgtuIY__Q'((r$   c                    V ^8  d   QhRRRR/# )r   error_contextOptional[Dict[str, Any]]r   rQ   r    )r!   s   "r"   r#   r#      s      ,D  r$   c                   \        V \        4      '       g   / # / pV P                  R 4      p\        V\        4      '       d*   VP	                  4       '       d   VP	                  4       VR &   V P                  R4      p\        V\        4      '       d*   VP	                  4       '       d   VP	                  4       VR&   V P                  R4      ;'       g+    V P                  R4      ;'       g    V P                  R4      p\        V4      pVfB   \        V\        4      '       d,   \        V4      pVe   \        P                  ! 4       V,           pVe   WQR&   V# )reasonr   reset_at	resets_atretry_until)r   dictr`   r6   r   r   r   time)r   r   r   r   r   parsed_reset_atretry_delay_secondss   &      r"   _normalize_error_contextr      s   mT**	!#Jx(F&#6<<>>%||~
8	*G'3GMMOO '
9*% 	, 	,[)	, 	,]+ 
 09O:gs#;#;:7C*"iik,??O"!0:r$   c                    V ^8  d   QhRRRR/# )r   r   r5   r   rB   r    )r!   s   "r"   r#   r#     s      ,  r$   c                    V P                   \        8w  d   R # \        \        V RR 4      4      pVe   V# V P                  '       d'   V P                  \        V P                  4      ,           # R # )NrH   )rA   STATUS_EXHAUSTEDr   r{   rC   r   rE   )r   r   s   & r"   _exhausted_untilr     s^    ,,(8Mt)TUH##nU5J5J&KKKr$   c                    V ^8  d   QhRRRR/# )r   r[   r6   r   r    )r!   s   "r"   r#   r#     s     2 2c 2c 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   configr   r    )r!   s   "r"   r#   r#     s     7 7> 7r$   c              #  :  "   V f   \        4       p V f   R# V P                  R4      p\        V\        4      '       g   R# V FS  p\        V\        4      '       g   K  VP                  R4      p\        V\
        4      '       g   KD  \        V4      V3x  KU  	  R# 5i)zJYield (normalized_name, entry_dict) for each valid custom_providers entry.Ncustom_providersr[   )r*   r`   r   listr   r6   r   )r   r   r   r[   s   &   r"   _iter_custom_providersr     s     ~"$~zz"45&--!%&&yy $$$)$/66 "s   BBc                    V ^8  d   QhRRRR/# )r   rI   r6   r   r?   r    )r!   s   "r"   r#   r#   *  s      3 = r$   c                8   V '       g   R# V P                  4       P                  R4      p\        4        Fb  w  r#\        VP	                  R4      ;'       g    R4      P                  4       P                  R4      pV'       g   KP  WA8X  g   KX  \
         V 2u # 	  R# )zLook up the custom_providers list in config.yaml and return 'custom:<name>' for a matching base_url.

Returns None if no match is found.
N/rI   rk   )r   rstripr   r6   r`   CUSTOM_POOL_PREFIX)rI   normalized_url	norm_namer   	entry_urls   &    r"   get_custom_provider_pool_keyr   *  s    
 ^^%,,S1N24			*-334::<CCCH	94())55 5 r$   c                   V ^8  d   QhRR/# )r   r   z	List[str]r    )r!   s   "r"   r#   r#   9  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rT   )r   r   r   r`   r   )r   r   	pool_datas   & r"   r   -list_custom_pool_providers.<locals>.<genexpr><  sN       >>,- 	y}}S)40 	 cNN 	ys   A'"A'A'
A')r   sorted)r   s   @r"   list_custom_pool_providersr   9  s'    $T*I    r$   c                    V ^8  d   QhRRRR/# )r   pool_keyr6   r   r   r    )r!   s   "r"   r#   r#   D  s      # 2J r$   c                    V P                  \        4      '       g   R# V \        \        4      R p\        4        F  w  r#W!8X  g   K  Vu # 	  R# )zWReturn the custom_providers config entry matching a pool key like 'custom:together.ai'.N)r   r   lenr   )r   suffixr   r   s   &   r"   _get_custom_provider_configr  D  sJ    122c,-./F24	L 5 r$   c                    V ^8  d   QhRRRR/# )r   r7   r6   r   r    )r!   s   "r"   r#   r#   O  s        r$   c                ,   \        4       pVf   \        # VP                  R4      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_strategiesrk   )	r*   STRATEGY_FILL_FIRSTr`   r   r   r6   r   r   SUPPORTED_POOL_STRATEGIES)r7   r   
strategiesstrategys   &   r"   get_pool_strategyr  O  sz     F~""89Jj$''"":>>(B/5526<<>DDFH,,r$   c                  R   ] tR tR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
R8R R lltR R ltR R ltR R ltR R ltR8R R lltR R ltRR R!R /R" R# ll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/ R0 ltR1 R2 ltR3 R4 ltR5 R6 ltR7tR# )9CredentialPooli_  c                    V ^8  d   QhRRRR/# )r   r7   r6   r   r   r    )r!   s   "r"   r#   CredentialPool.__annotate__`  s     & & &/E &r$   c                	    Wn         \        VR  R7      V n        RV n        \	        V4      V n        \        P                  ! 4       V n        R# )c                    V P                   # rT   r   r   s   &r"   <lambda>)CredentialPool.__init__.<locals>.<lambda>b  s    %..r$   r   N)	r7   r   _entries_current_idr  	_strategy	threadingLock_lock)rW   r7   r   s   &&&r"   __init__CredentialPool.__init__`  s8     w,HI*.*84^^%
r$   c                   V ^8  d   QhRR/# r   r   r   r    )r!   s   "r"   r#   r  g  s     # # #r$   c                	,    \        V P                  4      # rT   )r   r  rV   s   &r"   has_credentialsCredentialPool.has_credentialsg      DMM""r$   c                   V ^8  d   QhRR/# r   r    )r!   s   "r"   r#   r  j  s     / /t /r$   c                4    \        V P                  4       4      # )zCTrue if at least one entry is not currently in exhaustion cooldown.)r   _available_entriesrV   s   &r"   has_availableCredentialPool.has_availablej  s    D++-..r$   c                   V ^8  d   QhRR/# )r   r   r   r    )r!   s   "r"   r#   r  n  s     # #/ #r$   c                	,    \        V P                  4      # rT   )r   r  rV   s   &r"   r   CredentialPool.entriesn  r$  r$   c                   V ^8  d   QhRR/# r   r   Optional[PooledCredential]r    )r!   s   "r"   r#   r  q  s     ^ ^3 ^r$   c                	l   a  S P                   '       g   R # \        V 3R lS P                   4       R 4      # )Nc              3  `   <"   T F#  qP                   SP                  8X  g   K  Vx  K%  	  R # 5irT   )r8   r  )r   r   rW   s   & r"   r   )CredentialPool.current.<locals>.<genexpr>t  s"     VuTEUEU9UUUs   .
.)r  nextr  rV   s   fr"   currentCredentialPool.currentq  s*    VVX\]]r$   c               $    V ^8  d   QhRRRRRR/# )r   oldr5   newr   Noner    )r!   s   "r"   r#   r  v  s#      "2 9I d r$   c                    \        V P                  4       F1  w  r4VP                  VP                  8X  g   K"  W P                  V&    R# 	  R# )z4Swap an entry in-place by id, preserving sort order.N)	enumerater  r8   )rW   r7  r8  idxr   s   &&&  r"   _replace_entryCredentialPool._replace_entryv  s6    #DMM2JCxx366!%(c" 3r$   c                   V ^8  d   QhRR/# )r   r   r9  r    )r!   s   "r"   r#   r  }  s     
 
$ 
r$   c                	    \        V P                  V P                   Uu. uF  qP                  4       NK  	  up4       R # u upi rT   )r   r7   r  r   rW   r   s   & r"   _persistCredentialPool._persist}  s.    MM*.--8-]]_-8	
8s   A 
Nc               (    V ^8  d   QhRRRRRRRR/# )r   r   r5   status_coderD   r   r   r   r    )r!   s   "r"   r#   r    s2       # 0	
 
r$   c                	
   \        V4      p\        V\        \        P                  ! 4       VVP	                  R 4      VP	                  R4      VP	                  R4      R7      pV P                  W4       V P                  4        V# )r   r   r   rA   rC   rE   rF   rG   rH   )r   r   r   r   r`   r=  rB  )rW   r   rE  r   normalized_errorupdateds   &&&&  r"   _mark_exhaustedCredentialPool._mark_exhausted  ss     4MB(99;'.228</33I> 0 4 4Z @
 	E+r$   c                    V ^8  d   QhRRRR/# r   r   r5   r   r    )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P	                  R^ 4      pV'       df   WAP
                  8w  dV   \        P                  RVP                  4       \        VVVVR	R	R	R
7      pV P                  W4       V P                  4        V# V#   \         d"   p\        P                  RT4        R	p?T# R	p?ii ; i)a_  Sync a claude_code pool entry from ~/.claude/.credentials.json if tokens differ.

OAuth refresh tokens are single-use. When something external (e.g.
Claude Code CLI, or another profile's pool) refreshes the token, it
writes the new pair to ~/.claude/.credentials.json. The pool entry's
refresh token becomes stale. This method detects that and syncs.
	anthropicclaude_code)read_claude_code_credentialsrefreshTokenrk   accessToken	expiresAtzKPool entry %s: syncing tokens from credentials file (refresh token changed)Nr>   r@   rK   rA   rC   rE   z(Failed to sync from credentials file: %s)r7   r=   agent.anthropic_adapterrQ  r`   r@   loggerdebugr8   r   r=  rB  r)   )	rW   r   rQ  credsfile_refreshfile_accessfile_expiresrI  excs	   &&       r"   +_sync_anthropic_entry_from_credentials_file:CredentialPool._sync_anthropic_entry_from_credentials_file  s     ==K'5<<=+HL	JL02E 99^R8L))M26K 99[!4L0C0C Cjlqltltu!!,".". $#'$( ##E3   	JLLCSII	Js(   C" C" =C" ;A$C" "D-D		Dc                    V ^8  d   QhRRRR/# rM  r    )r!   s   "r"   r#   r    s      0@ EU r$   c           	        V P                   R8w  d   V#  \        4       pV'       g   V# VP                  RR4      pVP                  RR4      pV'       de   W1P                  8w  dU   \        P                  RVP                  4       \        VVVRRRR7      pV P                  W4       V P                  4        V# V#   \         d"   p\        P                  RT4        Rp?T# Rp?ii ; i)	ac  Sync an openai-codex pool entry from ~/.codex/auth.json if tokens differ.

OpenAI OAuth refresh tokens are single-use and rotate on every refresh.
When the Codex CLI (or another Hermes profile) refreshes its token,
the pool entry's refresh_token becomes stale.  This method detects that
by comparing against ~/.codex/auth.json and syncing the fresh pair.
openai-codexr@   rk   r>   zMPool entry %s: syncing tokens from ~/.codex/auth.json (refresh token changed)N)r>   r@   rA   rC   rE   z*Failed to sync from ~/.codex/auth.json: %s)r7   r   r`   r@   rW  rX  r8   r   r=  rB  r)   )rW   r   
cli_tokenscli_refresh
cli_accessrI  r]  s   &&     r"   _sync_codex_entry_from_cli)CredentialPool._sync_codex_entry_from_cli  s     ==N*L	L13J$.."=K#;J{.A.AAlnsnvnvw!!+"- $#'$( ##E3   	LLLEsKK	Ls#   B; +B; A#B; ;C'C""C'c               $    V ^8  d   QhRRRRRR/# )r   r   r5   forcer   r   r/  r    )r!   s   "r"   r#   r    s(     E E$4 E EIc Er$   c               		   VP                   \        8w  g   VP                  '       g   V'       d   V P                  VR 4       R #  V P                  R8X  d   ^ RIHp V! VP                  VP                  P                  R4      R7      p\        VVR,          VR,          VR,          R7      pVP                  R	8X  d)    ^ R
IH
p V! VR,          VR,          VR,          4       EMEMV P                  R8X  dZ   \        P                  ! VP                   VP                  4      p\        VVR,          VR,          VP#                  R4      R7      pEMCV P                  R8X  Ed0   RVP                   RVP                  RVP$                  RVP&                  RVP(                  RVP*                  RVP,                  RVP.                  RVP0                  RVP2                  RVP4                  RVP6                  /p\        P8                  ! V\:        VVR7      p/ p	\=        VP>                  4      p
\A        V4       Uu0 uF  qPB                  kK  	  ppVPE                  4        F"  w  rW9   d   WV&   K  V\F        9   g   K  WV&   K$  	  \        V3RV
/V	B pMV# \        V\L        R R R R R R"7      pV PO                  W4       V PQ                  4        V#   \         d!   p\        P                  RT4        R p?L_R p?ii ; iu upi   \         Ed   p\        P                  RT P                  TPH                  T4       T P                  R8X  Ed   TP                  R	8X  Ed   T PK                  T4      pTP                  TP                  8w  Ed!   \        P                  R4        ^ RIHp T! TP                  TP                  P                  R4      R7      p\        TTR,          TR,          TR,          \L        R R R7      pT PO                  TT4       T PQ                  4         ^ R
IH
p T! TR,          TR,          TR,          4       M.  \         d!   p\        P                  RT4        R p?MR p?ii ; iTu R p?#   \         d!   p\        P                  R T4        R p?M;R p?ii ; iT PS                  T4      '       g   \        P                  R!4       Tu R p?# T P                  TR 4        R p?R # R p?ii ; i)#NrO  )refresh_anthropic_oauth_purehermes_pkce)use_jsonr>   r@   rK   )r>   r@   rK   rP  )_write_claude_code_credentialsz7Failed to write refreshed token to credentials file: %srb  rL   )r>   r@   rL   r   	client_idportal_base_urlrM   
token_typescopeobtained_atrJ   rN   rO   tls)min_key_ttl_secondsforce_refresh
force_mintrR   z'Credential refresh failed for %s/%s: %sz8Retrying refresh with synced token from credentials filerU  zDFailed to write refreshed token to credentials file (retry path): %szRetry refresh also failed: %sz7Credentials file has valid token, using without refreshrG  )*r:   AUTH_TYPE_OAUTHr@   rJ  r7   rV  rk  r=   endswithr   rn  r)   rW  rX  auth_modrefresh_codex_oauth_purer>   r`   ro  rp  rM   rq  rr  rs  rJ   rN   rO   rt  refresh_nous_oauth_from_stater   r   rR   r   r[   r|   r_   r8   r^  	STATUS_OKr=  rB  _entry_needs_refresh)rW   r   ri  rk  	refreshedrI  rn  wexc
nous_statefield_updatesextra_updatesrs   _field_namesru   r   r]  synced	retry_excs   &&$               r"   _refresh_entryCredentialPool._refresh_entry  sb   ??o-U5H5H5H$$UD1r	}}+P8''"\\22=A	 "!*>!:"+O"<"+O"<	 <<=0fZ6%n5%o6%o6 1 .0$==&&''	 "!*>!:"+O"<!*~!>	 &("E$6$6#U%8%8%u'<'<(%*B*B %"2"2U[[!5#4#4 %"2"2*E,F,F599
 %BB(I"'$		 !# $U[[ 106u>1>%OO-DA(+,a(k)+,a(	 .
 "%N}NN\ ! "# $
 	E+M % f%^`deefJ  ?  +	LLBDMMSXS[S[]`a }}+0MII%P''5+>+>>LL![\QX$@"00%+]]%;%;M%J%	 #*")2>)B*3O*D*3O*D(1+/,0# ++FG<w^: ). 9 )/ : )/ :
  ) w"LL)oquvvw&$ Q%DiPPQ226::LL!Z[!M  -W+	s   A9L ?%K (A(L C&L 8K<+L <L L K9K4/L 4K99L S:BS5 B Q<!%QQ<Q2Q-(Q<-Q22Q<6S:<R'R"S5"R''S5S5S:S55S:c                    V ^8  d   QhRRRR/# )r   r   r5   r   r   r    )r!   s   "r"   r#   r  d  s      *: t r$   c                	v   VP                   \        8w  d   R # V P                  R8X  dS   VP                  f   R # \	        VP                  4      \	        \
        P
                  ! 4       R,          4      R,           8*  # V P                  R8X  d   \        VP                  \        4      # V P                  R8X  d   R # R # )FrO  i  i rb  r   )	r:   rx  r7   rK   r;   r   r   r>   r   rA  s   &&r"   r~  #CredentialPool._entry_needs_refreshd  s    ??o-==K'""*u**+s499;3E/F/PPP==N*2""7  ==F" r$   c                    V ^8  d   QhRRRR/# )r   entry_idr?   r   r9  r    )r!   s   "r"   r#   r  w  s     	 	- 	4 	r$   c                p   T;'       g    V P                   pV'       g   R# V P                  ;_uu_ 4        \        V P                  4       FK  w  r4VP                  V8X  g   K  \        WDP                  ^,           R7      V P                  V&    RRR4       R# 	  RRR4       R#   + '       g   i     R# ; i)zBIncrement request_count for tracking. Used by least_used strategy.NrP   )r  r  r;  r  r8   r   rP   )rW   r  	target_idr<  r   s   &&   r"   	mark_usedCredentialPool.mark_usedw  sx    00 0 0	ZZZ'6
88y()0FYFY\]F])^DMM#&	 Z6 ZZZs   )B$#+B$B$$B5	c                   V ^8  d   QhRR/# r.  r    )r!   s   "r"   r#   r    s     + +2 +r$   c                	    V P                   ;_uu_ 4        V P                  4       uuR R R 4       #   + '       g   i     R # ; irT   )r  _select_unlockedrV   s   &r"   selectCredentialPool.select  s#    ZZZ((* ZZZ	   0A	clear_expiredFrefreshc               $    V ^8  d   QhRRRRRR/# )r   r  r   r  r   r   r    )r!   s   "r"   r#   r    s"     7 74 7$ 7[q 7r$   c               .   \         P                   ! 4       pRp. pV P                   EFR  pV P                  R8X  dA   VP                  R8X  d0   VP                  \
        8X  d   V P                  V4      pWvJd   TpRpV P                  R8X  dB   VP                  \
        8X  d-   VP                  '       d   V P                  V4      pWvJd   TpRpVP                  \
        8X  dK   \        V4      pVe	   W88  d   K  V'       d,   \        V\        RRRRRR7      p	V P                  Wi4       T	pRpV'       d4   V P                  V4      '       d   V P                  VRR7      p
V
f   EK?  T
pVP                  V4       EKU  	  V'       d   V P!                  4        V# )	zReturn entries not currently in exhaustion cooldown.

When *clear_expired* is True, entries whose cooldown has elapsed are
reset to STATUS_OK and persisted.  When *refresh* is True, entries
that need a token refresh are refreshed (skipped on failure).
FrO  rP  Trb  NrG  ri  )r   r  r7   r=   rA   r   r^  r@   rf  r   r   r}  r=  r~  r  appendrB  )rW   r  r  nowcleared_any	availabler   r  exhausted_untilclearedr  s   &$$        r"   r'  !CredentialPool._available_entries  su    iik,.	]]E ,1N))-==II%P&"E"&K /))-==+++88?&"E"&K  $44"25"9".33H %$-'+(,*.+/,0G ''7#E"&K444U;; //U/C	$!U#U #V MMOr$   c                   V ^8  d   QhRR/# r.  r    )r!   s   "r"   r#   r    s      "< r$   c           	     	   V P                  R R R7      pV'       g   RV n        \        P                  R4       R# V P                  \
        8X  d*   \        P                  ! V4      pVP                  V n        V# V P                  \        8X  d2   \        V4      ^8  d"   \        VR R7      pVP                  V n        V# V P                  \        8X  d   \        V4      ^8  d   V^ ,          pV P                   Uu. uF!  q3P                  VP                  8w  g   K  VNK#  	  ppVP                  \        V\        V P                  4      ^,
          R7      4       \!        V4       UUu. uF  w  rS\        W5R7      NK  	  uppV n        V P#                  4        VP                  V n        V P%                  4       ;'       g    T# V^ ,          pVP                  V n        V# u upi u uppi )T)r  r  Nz>credential pool: no available entries (all exhausted or empty)c                    V P                   # rT   r  )es   &r"   r  1CredentialPool._select_unlocked.<locals>.<lambda>  s    r$   r  r   )r'  r  rW  infor  STRATEGY_RANDOMr2   choicer8   STRATEGY_LEAST_USEDr  minSTRATEGY_ROUND_ROBINr  r  r   r;  rB  r4  )rW   r  r   	candidaterotatedr<  s   &     r"   r  CredentialPool._select_unlocked  sp   ++$+M	#DKKXY>>_,MM),E$xxDL>>00S^a5G	'@AE$xxDL>>11c)nq6HaLE26--\-Y<<SXS[S[C[yy-G\NN753t}}3E3IJKT]^eTfgTf.#WY=TfgDMMMO$xxD<<>**U*! 88 ]gs   :GG'G#c                   V ^8  d   QhRR/# r.  r    )r!   s   "r"   r#   r    s     3 30 3r$   c                	t    V P                  4       pVe   V# V P                  4       pV'       d
   V^ ,          # R # rT   )r4  r'  )rW   r4  r  s   &  r"   peekCredentialPool.peek  s7    ,,.N++-	(y|2d2r$   r   c               $    V ^8  d   QhRRRRRR/# )r   rE  rD   r   r   r   r/  r    )r!   s   "r"   r#   r    s*       # 0	
 
$r$   c               	0   V P                   ;_uu_ 4        V P                  4       ;'       g    V P                  4       pVf    R R R 4       R # VP                  ;'       g    VP                  R,          p\
        P                  RWA4       V P                  W1V4       R V n        V P                  4       pV'       d>   VP                  ;'       g    VP                  R,          p\
        P                  RV4       VuuR R R 4       #   + '       g   i     R # ; i)N:N   Nz;credential pool: marking %s exhausted (status=%s), rotatingzcredential pool: rotated to %s)	r  r4  r  r9   r8   rW  r  rJ  r  )rW   rE  r   r   _label
next_entry_next_labels   &$$    r"   mark_exhausted_and_rotate(CredentialPool.mark_exhausted_and_rotate  s     ZZZLLN==d&;&;&=E} Z [[00EHHRLFKKM   ]C#D..0J(..CC*--2C<kJ ZZZs   .DD A-D+DD	c                   V ^8  d   QhRR/# r.  r    )r!   s   "r"   r#   r    s     8 8%? 8r$   c                	    V P                   ;_uu_ 4        V P                  4       uuR R R 4       #   + '       g   i     R # ; irT   )r  _try_refresh_current_unlockedrV   s   &r"   try_refresh_current"CredentialPool.try_refresh_current  s#    ZZZ557 ZZZr  c                   V ^8  d   QhRR/# r.  r    )r!   s   "r"   r#   r    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  )r4  r  r8   r  )rW   r   r  s   &  r"   r  ,CredentialPool._try_refresh_current_unlocked  sB    =''T':	 (||Dr$   c                   V ^8  d   QhRR/# )r   r   r;   r    )r!   s   "r"   r#   r    s       r$   c                	V   ^ p. pV P                    Fv  pVP                  '       g%   VP                  '       g   VP                  '       d-   VP	                  \        VRRRRRRR7      4       V^,          pKe  VP	                  V4       Kx  	  V'       d   W n         V P                  4        V# )    NrG  )r  rA   rC   rE   r  r   rB  )rW   countnew_entriesr   s   &   r"   reset_statusesCredentialPool.reset_statuses  s    ]]E   E$8$8$8E<Q<Q<Q""$('+(,*.+/,0
 
""5) #  'MMMOr$   c                    V ^8  d   QhRRRR/# )r   indexr;   r   r/  r    )r!   s   "r"   r#   r     s      # *D r$   c           	     	p   V^8  g   V\        V P                  4      8  d   R# V P                  P                  V^,
          4      p\        V P                  4       UUu. uF  w  r4\	        WCR7      NK  	  uppV n        V P                  4        V P                  VP                  8X  d   RV n        V# u uppi )   Nr   )r  r  popr;  r   rB  r  r8   )rW   r  removednew_priorityr   s   &&   r"   remove_indexCredentialPool.remove_index   s    19DMM 22--##EAI. (1'?
'?# E1'?
 	wzz)#D
s   B2c                    V ^8  d   QhRRRR/# )r   targetr   r   z?Tuple[Optional[int], Optional[PooledCredential], Optional[str]]r    )r!   s   "r"   r#   r  -  s     > >S >-l >r$   c                	"   \        T;'       g    R 4      P                  4       pV'       g   R	# \        V P                  ^R7       F  w  r4VP                  V8X  g   K  W4R3u # 	  \        V P                  ^R7       UUu. uFE  w  r4VP
                  P                  4       P                  4       VP                  4       8X  g   KB  W43NKG  	  ppp\        V4      ^8X  d"   V^ ,          ^ ,          V^ ,          ^,          R3# \        V4      ^8  d
   RRRV R23# VP                  4       '       dV   \        V4      p^Tu;8:  d   \        V P                  4      8:  d    M MW`P                  V^,
          ,          R3# RRRV R23# RRRV R23# u uppi )
rk   N)startzAmbiguous credential label "z-". Use the numeric index or entry id instead.zNo credential #.zNo credential matching "z".)NNzNo credential target provided.)
r6   r   r;  r  r8   r9   r   r  isdigitr;   )rW   r  r   r<  r   label_matchesr  s   &&     r"   resolve_targetCredentialPool.resolve_target-  sq   &,,B%%'??#DMM;JCxx34'' < (Q?
?
{{  "((*ciik9 SL? 	 

 }" #A&a(8(;TAA}!!=cUBoppp;;==HEE/S//mmEAI6<<q999T5cU"===
s   ??FFc                    V ^8  d   QhRRRR/# rM  r    )r!   s   "r"   r#   r  F  s      / 4D r$   c                	    \        V\        V P                  4      R 7      pV P                  P                  V4       V P	                  4        V# )r   )r   r   r  r  rB  rA  s   &&r"   	add_entryCredentialPool.add_entryF  s7    t}}(EFU#r$   )r  r  r  r  r7   rT   )rc   r   r   r   r  r"  r(  r   r4  r=  rB  rJ  r^  rf  r  r~  r  r  r'  r  r  r  r  r  r  r  r  r  r   r    r$   r"   r  r  _  s    &#/#^

(#JBEN&	+7% 7QV 7r<3 37	.80>2 r$   r  c          
     ,    V ^8  d   QhRRRRRRRRRR	/# )
r   r   r   r7   r6   r=   rg   rQ   r   r   r    )r!   s   "r"   r#   r#   M  s2     " "1 "S "# "Xf "ko "r$   c                   R p\        V 4       F  w  rVVP                  V8X  g   K  Tp M	  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  qP                  kK  	  pp
VP                  4        F~  w  rVR9   g   Vf   K  VR8X  d   VP                  '       d   K-  W9   d   \        W|4      V8w  d   WV&   KI  KK  V\         9   g   KX  VP"                  P                  V4      V8w  g   Kz  WV&   K  	  V'       g	   V	'       d,   V	'       d   / VP"                  CV	CVR&   \%        V3/ VB W&   R# R# u up
i )	Nr8   ri   r<   r9   TrR   F>   r8   r<   )r;  r=   rl   rm   rn   ro   r   r`   r  r5   rw   r   r[   r|   r9   r{   r_   rR   r   )r   r7   r=   rg   existing_idxr<  r   existingr  r  rs   r  r   r   s   &&&&          r"   _upsert_entryr  M  s   L(
<<6!L )
 4!1!1"!56:~g'>?7GKK$8$B$BFC'11(DE$HMM$*8$45$4qFF$4L5mmo
$$'>hnnnx%.%*c" /K~~!!#&%/%*c" & %H%H-%HM'" ' BM B# 6s   +Gc               $    V ^8  d   QhRRRRRR/# )r   r7   r6   r   r   r   r   r    )r!   s   "r"   r#   r#   r  s#       7M RV r$   c           
       a
 V R 8w  d   R# R^ R^R^R^R^/o
\        R V 4       R R	7      p\        R
 V 4       V
3R lR	7      p. VOVOp\        V4       UUu/ uF  w  rVVP                  VbK  	  pppRp\        V4       F9  w  rVP                  V	8w  g   K  \	        WiR7      WVP                  ,          &   RpK;  	  V# u uppi )rO  Fzenv:ANTHROPIC_TOKENzenv:CLAUDE_CODE_OAUTH_TOKENrl  rP  zenv:ANTHROPIC_API_KEYc              3  `   "   T F$  p\        VP                  4      '       g   K   Vx  K&  	  R # 5irT   r   r=   r   s   & r"   r   -_normalize_pool_priorities.<locals>.<genexpr>~  s     GG5'8'FG   .
.c                    V P                   # rT   r   r  s   &r"   r  ,_normalize_pool_priorities.<locals>.<lambda>  s    %..r$   r  c              3  `   "   T F$  p\        VP                  4      '       d   K   Vx  K&  	  R # 5irT   r  r   s   & r"   r   r    s     KG5+<U\\+JGr  c                |   < SP                  V P                  \        S4      4      V P                  V P                  3# rT   )r`   r=   r  r<   r9   )r   source_ranks   &r"   r  r    s-    OOELL#k*:;NNKK
r$   r   T)r   r;  r8   r<   r   )r7   r   manual_entriesseeded_entriesorderedr<  r   	id_to_idxchangedr  r  s   &&        @r"   _normalize_pool_prioritiesr  r  s    ; 	q%qqqK GGG(N KGK
N 100G1:71CD1C:331CIDG(1>>\)+25+PGehh'(G  2 N Es   B?c               $    V ^8  d   QhRRRRRR/# r   r7   r6   r   r   r   Tuple[bool, Set[str]]r    )r!   s   "r"   r#   r#     s(     J# J#C J#2H J#Mb J#r$   c           '     <   R p\        4       p\        4       pV R8X  d   ^ RIHpHp RV! 4       3RV! 4       33 F  w  rxV'       g   K  VP                  R4      '       g   K(  VP                  V4       V\        VV VR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      ,          pK  	  W#3# V R8X  EdF   \        VR4      p	V	'       Ed.   VP                  R4       T\        TT RR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      R\        V	P                  R4      \        4      '       d   V	P                  R4      MRR\        V	P                  RR	4      R4      /4      ,          pW#3# V R8X  d   \        VR4      p	\        V	\        4      '       d   V	P                  R4      MRp
\        V
\        4      '       d   V
P                  R4      '       d   VP                  R4       V\        VV RRRR\        RV
P                  RR	4      R
V
P                  R
4      RRRV	P                  R4      R\        V
P                  RR	4      R4      /4      ,          pW#3# ) FrO  )rQ  read_hermes_oauth_credentialsrl  rP  rS  r=   r:   r>   rk   r@   rR  rK   rT  r9   r   device_coderJ   rq  rr  ro  rp  rM   rN   rO   rt  Nrb  tokensrI   z%https://chatgpt.com/backend-api/codexrL   )setr   rV  rQ  r  r`   addr  rx  r   r   r   r   )r7   r   r  active_sources
auth_storerQ  r  source_namerY  stater   s   &&         r"   _seed_from_singletonsr    s   G"uN!#J;g 9;<8:;#
K u=11"";/= +#_&		-(D'>)B';)?!1%))M22NP[!\	 #
D ""] 
V	$Z85}-}m"EIInb$A#UYY%? %))L"9 %))L"9UYYw/;!7%uyy1B'C(%))4H*I;!7*EII6L,Mz%))E:JD/Q/Q599U+W[-eii.K][	 GT "") 
^	#$Z@(25$(?(?8$Tfd##

>(B(B}-}m"FJJ~r$B#VZZ%@ G"EIIn$=-fjj.Lm\	 G ""r$   c               $    V ^8  d   QhRRRRRR/# r  r    )r!   s   "r"   r#   r#     s#     :# :#S :#+A :#F[ :#r$   c                   R p\        4       pV R8X  dk   \        P                  ! RR4      P                  4       pV'       d;   RpVP	                  V4       V\        VV VRVR\        RVR\        R	R/4      ,          pW#3# \        P                  ! V 4      pV'       d   VP                  \        8w  d   W#3# RpVP                  '       d?   \        P                  ! VP                  R4      P                  4       P                  R
4      p\        VP                  4      pV R8X  d   . ROpV F  p	\        P                  ! V	R4      P                  4       pV'       g   K2  RV	 2pVP	                  V4       V R8X  d   VP                  R4      '       g   \         M\        p
T;'       g    VP"                  pV\        VV VRVRV
RVRVR	V	/4      ,          pK  	  W#3# )F
openrouterOPENROUTER_API_KEYrk   zenv:OPENROUTER_API_KEYr=   r:   r>   rI   r9   r   rO  env:z
sk-ant-api)ANTHROPIC_TOKENCLAUDE_CODE_OAUTH_TOKENANTHROPIC_API_KEY)r  osgetenvr   r  r  rp   r   r   r`   r:   base_url_env_varr   r   api_key_env_varsr   rx  rM   )r7   r   r  r  r   r=   pconfigenv_urlenv_varsenv_varr:   rI   s   &&          r"   _seed_from_envr    s   G"uN<		.399;-Fv&}f!2"E 31	 G &&##H-Gg''+<<&&G))G44b9??AHHMG,,-H;
 		'2&,,.y!6"'/;'>uGWGWXdGeGeOk|	88g88=&YH	
 	
 ( ""r$   c               $    V ^8  d   QhRRRRRR/# )r   r   r   r  zSet[str]r   r   r    )r!   s   "r"   r#   r#     s$      )? QY ^b r$   c                4   V  Uu. uFg  p\        VP                  4      '       gH   VP                  V9   g7   VP                  P                  R 4      '       d   KR  VP                  R9   d   Ke  VNKi  	  pp\        V4      \        V 4      8X  d   R# W0R&   R# u upi )r  F:NNNT>   rP  rl  )r   r=   r   r  )r   r  r   retaineds   &&  r"   _prune_stale_seeded_entriesr    s     	EU\\**<<>)LL##F+ 	 ||== 	  	 8}G$AJ	s   ABB,Bc               $    V ^8  d   QhRRRRRR/# )r   r   r6   r   r   r   r  r    )r!   s   "r"   r#   r#   /  s#     =# =# =#.D =#I^ =#r$   c                >   Rp\        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                  R4      p\        VP                  R4      ;'       g    R4      P	                  4       pV'       dD   RV 2pVP                  V4       T\        TT TRTR	\        R
TRTRT;'       g    T/4      ,          p \        4       p	V	'       d   V	P                  R4      MRp
\        V
\        4      '       Ed=   \        V
P                  R4      ;'       g    R4      P	                  4       P                  4       p\        V
P                  R4      ;'       g    R4      P	                  4       P                  R4      pRpR FT  pV
P                  V4      p\        V\        4      '       g   K,  VP	                  4       '       g   KD  VP	                  4       p M	  VR8X  dY   V'       dQ   V'       dI   \        V4      pVV 8X  d7   RpVP                  V4       V\        VV VRVR	\        R
VRVRR/4      ,          pW#3#   \         d     Y#3# i ; i)zJSeed a custom endpoint pool from custom_providers config and model config.Fr.   rk   rI   r   r[   zconfig:r=   r:   r>   r9   modelNr7   custommodel_config)r.   api)r  r  r6   r`   r   r   r  r  rp   r*   r   r   r   r   r)   )r   r   r  r  	cp_configr.   rI   r[   r=   r   	model_cfgmodel_providermodel_base_urlmodel_api_keyru   r   matched_keys   &&               r"   _seed_custom_poolr)  /  sO   G"uN ,H5IimmI.44"5;;=y}}Z066B7==?FFsK9==(..B/557tf%Fv&}f!2"GT^^V	 G"$+1FJJw't	i&& z!:!@!@bAGGIOOQN z!:!@!@bAGGIPPQTUNM'MM!$a%%!''))$%GGIM	 (
 )n:>J(*+F"&&v.} $f'):*M&#^	  G ""  ""s9   AJ *?J *AJ >J "J 9J AJ JJc                    V ^8  d   QhRRRR/# )r   r7   r6   r   r  r    )r!   s   "r"   r#   r#   o  s     - - - -r$   c                p   T ;'       g    R P                  4       P                  4       p \        V 4      pV Uu. uF  p\        P	                  W4      NK  	  ppV P                  \        4      '       d#   \        W4      w  rETpV\        W54      ,          pMQ\        W4      w  rx\        W4      w  rT;'       g    T	pV\        W8V
,          4      ,          pV\        W4      ,          pV'       d6   \        T \        VR R7       Uu. uF  qP                  4       NK  	  up4       \        W4      # u upi u upi )rk   c                    V P                   # rT   r   )items   &r"   r  load_pool.<locals>.<lambda>  s    4==r$   r  )r   r   r   r5   rw   r   r   r)  r  r  r  r  r   r   r   r  )r7   raw_entriesrg   r   custom_changedcustom_sourcesr  singleton_changedsingleton_sourcesenv_changedenv_sourcesr   s   &           r"   	load_poolr6  o  s   B%%'--/H&x0KLWXK))(<KGX-..):8)M& .wGG/DX/W,#1(#D #22{.wK8WXX-h@@*0>X*YZ*Y]]_*YZ	
 (,,' Y" [s   D.D3
i  iQ >   rt  rr  ro  
expires_inrq  rs  agent_key_idrp  agent_key_reusedagent_key_expires_inagent_key_obtained_atrT   )S__doc__
__future__r   loggingr2   r  r   rm   r  r   dataclassesr   r   r   r   r   typingr   r	   r
   r   r   r   hermes_constantsr   hermes_cli.authauthrz  r   r   r   r   r   r   r   r   r   r   r   r   r   	getLoggerrc   rW  r*   r}  r   rx  rp   rq   r  r  r  r  r	  r   r   r   	frozensetr_   r5   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  r)  r6  r    r$   r"   <module>rF     sj   B "      	 	 2 2 ' 8 8 0 "     
		8	$ 	  " $ " 	  $  , 
      O O OdFU
)<
22
7$ k k\"JDJ#Z:#z"=#@-r$   