Ë
    áß²jj  ã                   óD  — U d Z ddlZddlZddlZddlZddlmZ  ej                  e«      Z	 G d„ de
«      Z ej                  «       Zdaee   ed<    e«       Zee   ed<   ded	efd
„Zded	efd„Zded	ee   fd„Zded	efd„Zded	efd„Zded	efd„Zdd„Zd	ee   fd„Zy)u5  Why an auxiliary client could not be built â€” and the Nous credential failure behind it.

``_resolve_nous_runtime_api`` must swallow the resolver's ``AuthError`` and return None so the
ladder can still fall back (stored token, fallback_chain). Swallowing it at DEBUG left the goal
loop reporting ``judge error: RuntimeError`` while the real cause was an ``invalid_grant`` refresh
(#42177). This module remembers the latest failure so the ladder's raise and the goal judge can
name it, and warns ONCE per distinct message so operators see it without debug logging.
é    N)ÚOptionalc                   ó   — e Zd ZdZy)ÚAuxiliaryClientUnavailablezQNo auxiliary client could be built for the task (missing credentials / provider).N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    ú@/home/ubuntu/.hermes/hermes-agent/agent/auxiliary_unavailable.pyr   r      s   „ Ú[r   r   Ú_last_nous_detailÚ_warned_nous_detailsÚexcÚreturnc                 óÒ  — ddl m}m} ddlm} t        j                  t        «      5   | |d«      xs i «      }|rA|j                  d«      r0 |t        |d   «      d|j                  d«      d¬«      cd	d	d	«       S d	d	d	«       t        | |«      rI |t        | «      | j                  | j                  | j                  | j                  | j                  ¬
«      S | S # 1 sw Y   Œ`xY w)uí  Prefer the persisted terminal quarantine marker over *exc*; sentence-terminate either message.

    The pool rung swallows the real ``invalid_grant`` and wipes the dead tokens, so by the time the
    auth-store resolver runs it can only say "No access token found"; the marker it wrote still
    carries the message and code the user needs (#42177). ``format_auth_error`` appends the
    remediation sentence with a space, so an unterminated message reads "Invalid refresh token Run â€¦".
    r   )Ú	AuthErrorÚget_provider_auth_state)Ú_terminal_quarantine_markerÚnousÚmessageÚcodeT)Úproviderr   Úrelogin_requiredN)r   r   r   Úretry_afterÚ	retryable)Úhermes_cli.authr   r   Úhermes_cli.auth_nousr   Ú
contextlibÚsuppressÚ	ExceptionÚgetÚ	_sentenceÚ
isinstancer   r   r   r   r   )r   r   r   r   Úmarkers        r   Ú_quarantined_nous_errorr%      sÌ   € ÷ CÝ@ä	×	Ñ	œYÓ	'ñ 4Ù,Ñ-DÀVÓ-LÒ-RÐPRÓSˆÙ�f—j‘j Ô+ÙœY v¨iÑ'8Ó9ÀFÐQW×Q[ÑQ[Ð\bÓQcØ.2ô4÷4÷ 4ñ 4ô
 �#�yÔ!Ùœ 3›°#·,±,ÀSÇXÁXØ*-×*>Ñ*>ÈCÏOÉOØ#&§=¡=ô2ð 	2ð €J÷4ð 4ús   ¨ACÃC&Útextc                 óX   — t        | «      j                  «       j                  d«      dz   S )Nú.)ÚstrÚstripÚrstrip)r&   s    r   r"   r"   3   s#   € Üˆt‹9�?‰?Ó×#Ñ# CÓ(¨3Ñ.Ð.r   Úprovider_idc           
      óÄ  — ddl m}m}m} ddlm} g }t        j                  t        «      5   || «      D �cg c]$  }t        |t        «      r|j                  | |«      ‘Œ& }}ddd«       |D �cg c]  }|j                  |k7  sŒ|‘Œ }}|syt        j                  «       }|D ��	cg c]!  } ||t        |«      dk(  ¬«      }	|	�|	|kD  r|	‘Œ# }
}}	t        |
«      t        |«      k7  ryt        j                  dt        j                   t#        |
«      «      «      }t        |«      dk(  rdnd	t        |«      › d
�}d| › d|› d|› d| › d�	S c c}w # 1 sw Y   ŒêxY wc c}w c c}	}w )u‡  The "all N credentials â€¦ are cooling down" error when the provider's pool is fully benched.

    ``resolve_provider_client()`` returns ``None`` both when no credential exists and when every
    pool entry sits in a 429/quota cooldown, so the raise sites could only say "no credentials
    were found. Run hermes auth add â€¦" â€” wrong on both counts for a valid OAuth grant that is
    merely rate-limited (#56810). Read the persisted pool state (no seeding, no writes) and name
    the cooldown and its reset time instead; ``None`` when the pool is empty or a credential is
    usable (the caller keeps the missing-credential diagnostic).
    r   )ÚSTATUS_DEADÚPooledCredentialÚ_exhausted_until)Úread_credential_poolNé   )Úsole_credentialz%Y-%m-%d %H:%M %Zzits only credential iszall z credentials areú
Provider 'ú' is set in config.yaml but zM cooling down after a rate limit / quota error (429); the next one resets at zC. Wait for the reset, add another credential with `hermes auth add z9`, or switch to a different provider with `hermes model`.)Úagent.credential_poolr.   r/   r0   r   r1   r   r   r    r#   ÚdictÚ	from_dictÚlast_statusÚtimeÚlenÚstrftimeÚ	localtimeÚmin)r,   r.   r/   r0   r1   ÚentriesÚeÚliveÚnowÚuntilÚresetsÚwhenÚwhichs                r   Úpool_cooldown_messagerG   7   s~  € ÷ VÑUÝ4à€GÜ	×	Ñ	œYÓ	'ñ Vá0°Ó=öVØÄÈAÌtÔATð $×-Ñ-¨k¸1Õ=ð Vˆð V÷Vð Ö?�! !§-¡-°;Ó">ŠAÐ?€DÐ?ÙØÜ
�)‰)‹+€CØ!÷ 4˜Ù,¨QÄÀDÃ	ÈQÁÔO�%ØÐ" u¨s¢{ò ð 4€Fñ 4ô ˆ6ƒ{”c˜$“iÒØÜ�=‰=Ð,¬d¯n©n¼SÀ»[Ó.IÓJ€DÜ),¨T«°aªÑ%Øœ˜T›˜Ð#3Ð4ð 
à˜˜Ð%AÀ%Àð IFØFJÀVð L<Ø<G¸=ð I6ð6ð 7ùòV÷Vð Vüò @ùó4s.   ¬E·)EÁ EÁ.EÂEÂ%&EÅEÅEc                 óþ  — t        | «      }|r|S d}t        j                  t        «      5  ddlm} |j                  | «      }ddd«       t        t        |dd«      xs d«      }d\  }}|r
d|d   › d�}nV|€%d| j                  «       j                  d	d
«      › d�}n/t        |j                  «      j                  d«      r	dd| › d�}}nd}d}d| › d|› d�|r	|› d|› �z   S |j                  «       z   S # 1 sw Y   Œ±xY w)uF  The "Provider 'X' is set in config.yaml but â€¦" error for an explicit provider with no credentials.

    The remedy comes from the registry, never from the provider id: ``f"{id.upper()}_API_KEY"``
    invents names nothing reads (alibaba â†’ ALIBABA_API_KEY instead of DASHSCOPE_API_KEY, and the
    unsettable MINIMAX-OAUTH_API_KEY for OAuth ids, #114405 / #78996). OAuth providers have no key
    env var at all, so they are pointed at the sign-in command instead. A pool whose every
    credential is cooling down is not "missing" â€” that case names the cooldown (#56810).
    Nr   )ÚPROVIDER_REGISTRYÚapi_key_env_varsr
   )zno API key was foundÚ zSet the z environment variableú-Ú_z_API_KEY environment variableÚoauthzno credentials were foundzRun `hermes auth add z` to sign inz3switch to a different provider with `hermes model`.r4   r5   z. z, or )rG   r   r   r    r   rI   r!   ÚtupleÚgetattrÚupperÚreplacer)   Ú	auth_typeÚ
startswithÚ
capitalize)r,   ÚcooldownÚpconfigrI   Úenv_varsÚproblemÚremedyÚswitchs           r   Ú$missing_provider_credentials_messager\   Z   s4  € ô % [Ó1€HÙØˆØ€GÜ	×	Ñ	œYÓ	'ñ 5Ý5Ø#×'Ñ'¨Ó4ˆ÷5ô ”W˜WÐ&8¸$Ó?ÒEÀ2ÓF€HØ0�O€GˆVÙØ˜H Q™K˜=Ð(=Ð>‰Ø	ˆØ˜K×-Ñ-Ó/×7Ñ7¸¸SÓAÐBÐB_Ð`‰Ü	ˆW×ÑÓ	×	*Ñ	*¨7Ô	3Ø5Ð9NÈ{ÈmÐ[gÐ7h�‰à-ˆØB€FØ˜˜Ð%AÀ'ÀÈ"ÐMÙ+1�&�˜˜v˜hÐ'ñLð MØ7=×7HÑ7HÓ7JñLð M÷5ð 5ús   «C3Ã3C<c                 óª   — t        | dd«      ryddlm} t        j                  t
        «      5  t         |d«      «      cddd«       S # 1 sw Y   yxY w)u”  True when a Nous credential exists that failed â€” a coded error (``invalid_grant``, a quarantine
    marker, ``refresh_failed``) or persisted Nous auth state. The uncoded "not logged into Nous Portal"
    with no stored state is the normal condition for users who never chose Nous; the auto-route walk
    hits it on every discovery pass and must not warn (the ladder already logs its own summary).
    r   NTr   )r   r   F)rP   r   r   r   r   r    Úbool)r   r   s     r   Ú_nous_credential_presentr_   y   sJ   € ô ˆs�F˜DÔ!ØÝ7ä	×	Ñ	œYÓ	'ñ 5ÜÑ+¨FÓ3Ó4÷5÷ 5ñ 5àús   ®A	Á	Ac                 ó
  — ddl m} t        | «      } t        | t        «      r || «      n
t        | «      }|j                  «       xs t        | «      j                  }t        | dd«      }|rt        |«      |vr|› d|› d�}d|› �}t        5  |a|t        v}t        j                  |«       ddd«       rBt        | «      rt        j                   nt        j"                  }t$        j'                  |d|«       |S # 1 sw Y   ŒOxY w)	zÁRemember *exc* as the latest Nous credential failure.

    Logged once per distinct message: WARNING when a real credential failed, DEBUG when Hermes was
    simply never logged into Nous.
    r   )Úformat_auth_errorr   Nz (code: ú)z-Nous Portal runtime credentials unavailable: z%Auxiliary Nous client unavailable: %s)r   ra   r%   r#   r    r)   r*   Útyper   rP   Ú_lockr   r   Úaddr_   ÚloggingÚWARNINGÚDEBUGÚloggerÚlog)r   ra   r   r   ÚdetailÚ
first_timeÚlevels          r   Úrecord_nous_credential_failurern   ˆ   sç   € õ 2ä
! #Ó
&€CÜ(2°3¼	Ô(BÑ Ô$ÌÈCË€GØ�m‰m‹oÒ3¤ c£×!3Ñ!3€GÜ�3˜ Ó%€DÙ”�D“	 Ñ(Ø�I˜X d V¨1Ð-ˆØ<¸W¸IÐF€Fä	ñ )Ø"ÐØÔ#7Ð7ˆ
Ü× Ñ  Ô(÷)ñ Ü#;¸CÔ#@”—’ÄgÇmÁmˆÜ�
‰
�5ÐAÀ6ÔJØ€M÷)ð )ús   Â C9Ã9Dc                  ó>   — t         5  d ad d d «       y # 1 sw Y   y xY w)N©rd   r   r
   r   r   Úclear_nous_credential_failurerq   ¢   s    € ä	ñ !Ø Ð÷!÷ !ñ !ús   ‡“c                  óF   — t         5  t        cddd«       S # 1 sw Y   yxY w)zXThe latest recorded Nous credential failure, or None when the last resolution succeeded.Nrp   r
   r   r   Únous_credential_failure_detailrs   ¨   s   € ä	ñ !Ü ÷!÷ !ò !ús   ‡— )r   N)r	   r   rf   Ú	threadingr:   Útypingr   Ú	getLoggerr   ri   ÚRuntimeErrorr   ÚLockrd   r   r)   Ú__annotations__Úsetr   ÚBaseExceptionr%   Úobjectr"   rG   r\   r^   r_   rn   rq   rs   r
   r   r   ú<module>r}      sú   ðòó Û Û Û Ý à	ˆ×	Ñ	˜8Ó	$€ô\ ô \ð 	ˆ	�‰Ó€Ø#'Ð �8˜C‘=Ó 'Ù!$£Ð �c˜#‘hÓ &ð ð °=ó ð./�Fð /˜só /ð 7 sð  7¨x¸©}ó  7ðFM°cð M¸có Mð> -ð °Dó ð¨ð ¸#ó ó4!ð!¨°©ô !r   