+
    jHàjla  ã                  ó  a € 0 t $ R t^ RIHt ^ RIHt ^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIHt ^ RIHt ^ RIHtHt ^ RIHt ^ RIHt ^ R	IHtHt RsR
]R&    ! R R]4      tRR]P:                  3RR]P<                  3RR]P>                  3/t R=R R llt!R R lt"R R lt#R R lt$RR>RR?R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,R- R. lt-R/ R0 lt.R1 R2 lt/R3t0R4 R5 lt1R6t2R7 R8 lt3R9 R: lt4R; R< lt5R# )Au  API connectivity probes for ``hermes doctor`` (split out of ``doctor.py``).

Every probe is a pure function: one HTTP/SDK call returning a ``ProbeResult`` with the row(s) to
print and issue strings to append. No printing inside workers â€” the caller prints in submission order.
)Úannotations)Úinstall_hintN)Ú
NamedTuple)Úurlsplit)ÚColorsÚcolor)Ú_HERMES_USER_AGENT)ÚOPENROUTER_MODELS_URL)Úbase_url_host_matchesÚnormalize_proxy_env_varsúlist | NoneÚ_APIKEY_PROVIDERS_CACHEc                  ó6   € ] tR t^t$ R]R&   R]R&   R]R&   RtR# )ÚProbeResultÚstrÚlabelÚlistÚlinesÚissues© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__annotations__Ú__static_attributes__r   ó    ÚC/home/ubuntu/.hermes/hermes-agent/hermes_cli/doctor_connectivity.pyr   r      s   ‡ ØƒJØƒKØ‡Lr   r   Úoku   âœ“Úwarnu   âš Úfailu   âœ—c               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# )é   Únamer   ÚstatusÚdetailr   r   r   z
str | NoneÚreturnr   r   )Úformats   "r   Ú__annotate__r(   #   s8   € ÷ +ñ +ˆsð +˜Cð +¨ð +¸;ð +ÐV`ð +Ðlwñ +r   c           	     óÊ   € \         V,          w  rV\        T \        WV4      Vf   T MTV'       d   \        V\        P                  4      MR3.\        T;'       g    . 4      4      # )NÚ )Ú_GLYPHr   r   r   ÚDIMr   )r#   r$   r%   r   r   ÚglyphÚcols   &&&&&  r   Ú_rowr/   #   s]   € Ü˜•�J€EÜ�tœu UÓ0¸%º-±$ÈU×qwÔTYÐZ`Ôbh×blÑblÔTmÐ}ð  Að  BÜ˜FŸL˜L bÓ)ó+ð +r   c               ó    € V ^8„  d   QhRRRR/# )r"   r#   r   r&   r   r   )r'   s   "r   r(   r(   )   s   € ÷ %ñ %�ð %˜ñ %r   c                ó   € \        V . . 4      # ©N)r   )r#   s   &r   Ú_skipr3   )   s   € Ü�t˜R Ó$Ð$r   c               ó    € V ^8„  d   QhRRRR/# )r"   Úprovider_labelr   r&   Úboolr   )r'   s   "r   r(   r(   -   s   € ÷ 
ñ 
ÀCð 
ÈDñ 
r   c                ó"  € RRRR/P                  T ;'       g    RP                  4       P                  4       4      pV'       g   R#  ^ RIHp \        \        W!4      ! 4       ;'       g    / P                  R4      4      #   \         d     R# i ; i)	zÃTrue when a failed direct API-key probe is non-blocking because the same provider family's OAuth
runtime path is already healthy: the failed row is still shown, but not promoted into the summary.ÚminimaxÚget_minimax_oauth_auth_statusÚxaiÚget_xai_oauth_auth_statusr*   F)ÚauthÚ	logged_in)ÚgetÚstripÚlowerÚ
hermes_clir<   r6   ÚgetattrÚ	Exception)r5   Úgetterr<   s   &  r   Ú/_has_healthy_oauth_fallback_for_apikey_providerrE   -   s”   € ð Ð8¸%ÐA\Ð]×aÑaÐcq×cwÐcwÐuw×b~Ñb~ó  cA÷  cGñ  cGó  cIó  J€FßÙðÝ#Ü”W˜TÔ*Ó,×2Ð2°×7Ñ7¸ÓDÓEÐEøÜô Úðús   Á7A? Á?BÂBc               ó   € V ^8„  d   QhRR/# ©r"   r&   r   r   )r'   s   "r   r(   r(   :   s   € ÷ ?ñ ? dñ ?r   c                 ó2  a€ . ROp V  Uu0 uF  q^ ,          kK  	  pp0 Rmp0 RmV,          p ^ RI Hp ^ RIHp  ^ RIHp V! 4        EF—  p\        W†4      '       d$   VP                  R8w  g   VP                  '       g   K:  VP                  ;'       g    VP                  p	W’9   g   VP                  V9   d   Ks  VP                  .VP                  ;'       g    RO U
u0 uF
  q§! V
4      kK  	  up
V,          '       d   Kº  R	 o\        ;QJ d!    . V3R
 lVP                   4       F  NK  	  5M! V3R
 lVP                   4       4      pV'       g   EK  \        V3R lVP                   4       R4      pVP                  '       d7   VP                   ;'       g#    VP                  P#                  R4      R,           MRpV P%                  W›WÜ\'        VRR4      34       EKš  	  V # u upi   \         d    R R lp EL¾i ; iu up
i   \         d     T # i ; i)u9  Build the API-key provider health-check list once and cache it.

Tuple format: (name, env_vars, default_url, base_env, supports_models_endpoint). Base list augmented
with any ProviderProfile with auth_type="api_key" not already present â€” adding
plugins/model-providers/<name>/ is sufficient to get into doctor.
TN)Úlist_providers)ÚProviderProfile)Únormalize_providerc               ó    € V ^8„  d   QhRRRR/# )r"   Ú_namer   r&   r   )r'   s   "r   r(   Ú2_build_apikey_providers_list.<locals>.__annotate__e   s   € ÷ 5ñ 5¨3ð 5°3ñ 5r   c                óR   € T ;'       g    R P                  4       P                  4       # )r*   )r?   r@   )rM   s   &r   Ú_normalize_providerÚ9_build_apikey_providers_list.<locals>._normalize_providere   s    € ØŸ˜ ×*Ñ*Ó,×2Ñ2Ó4Ð4r   Úapi_keyc                óV   € V P                  R 4      ;'       g    V P                  R4      # )Ú	_BASE_URLÚ_URL)Úendswith)Úvs   &r   Ú<lambda>Ú._build_apikey_providers_list.<locals>.<lambda>p   s!   €  §
¡
¨;Ó 7× MÐ M¸1¿:¹:ÀfÓ;MÐ Mr   c              3  óH   <"  € T F  pS! V4      '       d   K  Vx € K  	  R # 5ir2   r   ©Ú.0rW   Ú_is_urls   & €r   Ú	<genexpr>Ú/_build_apikey_providers_list.<locals>.<genexpr>q   s   øé € ÐH© A¹WÀQ¿ZŸaša«ùó   ƒ"˜
"c              3  óH   <"  € T F  pS! V4      '       g   K  Vx € K  	  R # 5ir2   r   r[   s   & €r   r^   r_   t   s   øé € ÐD© A¹À¿Ÿaša«ùr`   Ú/ú/modelsÚsupports_health_check))z
Z.AI / GLM)ÚGLM_API_KEYÚZAI_API_KEYÚZ_AI_API_KEYz#https://api.z.ai/api/paas/v4/modelsÚGLM_BASE_URLT)zKimi / Moonshot)ÚKIMI_API_KEYz!https://api.moonshot.ai/v1/modelsÚKIMI_BASE_URLT)zStepFun Step Plan)ÚSTEPFUN_API_KEYz*https://api.stepfun.ai/step_plan/v1/modelsÚSTEPFUN_BASE_URLT)zKimi / Moonshot (China))ÚKIMI_CN_API_KEYz!https://api.moonshot.cn/v1/modelsNT)zArcee AI)ÚARCEEAI_API_KEYz"https://api.arcee.ai/api/v1/modelsÚARCEE_BASE_URLT)z	GMI Cloud)ÚGMI_API_KEYz%https://api.gmi-serving.com/v1/modelsÚGMI_BASE_URLT)ÚDeepSeek)ÚDEEPSEEK_API_KEYz"https://api.deepseek.com/v1/modelsÚDEEPSEEK_BASE_URLT)zHugging Face)ÚHF_TOKENz'https://router.huggingface.co/v1/modelsÚHF_BASE_URLT)z
NVIDIA NIM)ÚNVIDIA_API_KEYz*https://integrate.api.nvidia.com/v1/modelsÚNVIDIA_BASE_URLT)úAlibaba/DashScope)ÚDASHSCOPE_API_KEYz=https://dashscope-intl.aliyuncs.com/compatible-mode/v1/modelsÚDASHSCOPE_BASE_URLT)ÚMiniMax)ÚMINIMAX_API_KEYz https://api.minimax.io/v1/modelsÚMINIMAX_BASE_URLT)zMiniMax (China))ÚMINIMAX_CN_API_KEYz"https://api.minimaxi.com/v1/modelsÚMINIMAX_CN_BASE_URLF)zVercel AI Gateway)ÚAI_GATEWAY_API_KEYz&https://ai-gateway.vercel.sh/v1/modelsÚAI_GATEWAY_BASE_URLT)z	Kilo Code)ÚKILOCODE_API_KEYz&https://api.kilo.ai/api/gateway/modelsÚKILOCODE_BASE_URLT)zOpenCode Zen)ÚOPENCODE_ZEN_API_KEYz!https://opencode.ai/zen/v1/modelsÚOPENCODE_ZEN_BASE_URLT)zOpenCode Go)ÚOPENCODE_GO_API_KEYNÚOPENCODE_GO_BASE_URLF>   ÚbedrockÚ	anthropicÚ
openrouter>   ÚgmiÚzaiÚarceeÚnvidiaÚalibabar8   ÚstepfunÚdeepseekÚkilocodeÚhuggingfaceú
ai-gatewayú
minimax-cnúkimi-codingúopencode-goúopencode-zenúkimi-coding-cnr   )Ú	providersrI   Úproviders.baserJ   Úhermes_cli.providersrK   rC   Ú
isinstanceÚ	auth_typeÚenv_varsÚdisplay_namer#   ÚaliasesÚtupleÚnextÚbase_urlÚ
models_urlÚrstripÚappendrB   )Ú_staticÚtÚ_known_namesÚ_dedicated_canonicalÚ_known_canonicalrI   Ú_PPrP   Ú_ppÚ_labelÚaÚ	_key_varsÚ	_base_varÚ_models_urlr]   s                 @r   Ú_build_apikey_providers_listrµ   :   sË  ø€ ò€Gñ* #*Ó*¡'˜Q�a—D�D¡'€LÐ*ò BÐòð 	õÐðÝ,Ý9ð	5ÝVñ "×#ˆCÜ˜c×'Ò'¨3¯=©=¸IÔ+EÈSÏ\Ï\È\ÙØ×%Ñ%×1Ð1¨¯©ˆFØÔ%¨¯©Ð5EÔ)EÙØ14·±Ð0P¸S¿[¹[×=NÐ=NÈBÑ0PÓQÑ0P¨1Ð# AÖ&Ñ0PÑQÐTh×hÔhÙáMˆGßœÔH¨¯ªÓHŸ™ÔH¨¯ªÓHÓHˆIßÚÜÔD¨¯ªÓDÀdÓKˆIØX[×Xd×XdÐXd˜3Ÿ>™>×SÐS¨c¯l©l×.AÑ.AÀ#Ó.FÈÕ.RøÐjnˆKØ�N‰N˜F¨{ÄwÈsÐTkÐmqÓGrÐs×tñ $ð$ €NùòG +øô ô 	5÷5ð 5ð	5üò Røô ô ØØ€Nðúss   ŠG%­H ºG* Á >H Á?H ÂAH ÃH ÃHÃ/H Ã?H ÄAH ÅAH ÆA	H Ç*G?Ç;H Ç>G?Ç?H ÈHÈHé‘  i’  i­  c               ó   € V ^8„  d   QhRR/# ©r"   r&   r   r   )r'   s   "r   r(   r(   ˆ   s   € ÷ Bñ B˜;ñ Br   c                 óÌ  € R p \         P                  ! R4      pV'       g   \        V RR4      #  ^ RIpVP	                  \
        RRV 2/^
R7      pTP                  ^È8X  d   \        T R4      # \        P	                  TP                  RTP                   R
2R34      w  rV\        T RYV'       d   T.4      # R4      #   \         d   p\        T RR	T R
2R.4      u Rp?# Rp?ii ; i)úOpenRouter APIÚOPENROUTER_API_KEYr   z(not configured)NÚAuthorizationúBearer ©ÚheadersÚtimeoutr    Ú(Ú)úCheck network connectivityr   ú(HTTP )	ÚosÚgetenvr/   Úhttpxr>   r	   rC   Ústatus_codeÚ_OPENROUTER_STATUS)r#   ÚkeyrÇ   ÚrÚer%   Úissues          r   Ú_probe_openrouterrÎ   ˆ   sê   € Ø€DÜ
�)Š)Ð(Ó
)€CßÜ�D˜&Ð"4Ó5Ð5ðLÛØ�I‰IÔ+°oÈÐQTÐPUÀÐ5WÐacˆIÓdˆð 	‡}�}˜ÔÜ�D˜$ÓÐÜ&×*Ñ*¨1¯=©=¸VÀAÇMÁMÀ?ÐRSÐ;TÐVZÐ:[Ó\�M€FÜ��f˜f¶ u gÓAÐA¸DÓAÐAøô ô LÜ�D˜& A a S¨ (Ð-IÐ,JÓKÕKûðLús   ¯!B; Â;C#ÃCÃC#ÃC#c               ó   € V ^8„  d   QhRR/# r¸   r   )r'   s   "r   r(   r(   ˜   s   € ÷ }ñ }˜+ñ }r   c                 ó  € R p ^ RI Hp V! 4       pV'       g   \        V 4      #  ^ RIp^ RIHpHpHp ^ RIH	p V! V4      pRR/V'       d   RRV 2R	R
P                  WE,           4      /MRV/Cp	Rp
VP                  W©^
R7      pV'       dŸ   VP                  R8X  dŽ   RVP                  P                  4       9   do   RVP                  P                  4       9   dP   R
P                  V Uu. uF  qÌV8w  g   K  VNK  	  up\        V4      ,           4      V	R	&   VP                  W©^
R7      p\#        T .^ÈRRR/P                  TP                  R4      O5!  # u upi   \          d   p\#        T RRT R24      u Rp?# Rp?ii ; i)úAnthropic API)Úget_anthropic_keyN)Ú_COMMON_BETASÚ_OAUTH_ONLY_BETASÚ_CONTEXT_1M_BETA)Ú_is_oauth_tokenúanthropic-versionú
2023-06-01r¼   r½   zanthropic-betaÚ,ú	x-api-keyz#https://api.anthropic.com/v1/modelsr¾   é�  zlong context betaznot yet availabler   rÁ   rÂ   r¶   )r   )r    ú(invalid API key))r   z(couldn't verify))Úhermes_cli.authrÒ   r3   rÇ   Úagent.anthropic_adapterrÓ   rÔ   rÕ   Úagent.anthropic_credentialsrÖ   Újoinr>   rÈ   Útextr@   r   rC   r/   )r#   rÒ   rÊ   rÇ   rÓ   rÔ   rÕ   rÖ   Úis_oauthr¿   ÚurlrË   ÚbrÌ   s                 r   Ú_probe_anthropicrå   ˜   s�  € Ø€DÝ1Ù
Ó
€CßÜ�T‹{Ðð,Ûß^Ñ^Ý?Ù" 3Ó'ˆØ&¨ð _ß<Dð ;JÈWÐUXÐTYÈ?Ð\lÐnq×nvÑnvð  xEõ  xYó  oZñ  :[ØKVÐX[ÐJ\ð_ˆà3ˆØ�I‰I�c°BˆIÓ7ˆ÷ ˜Ÿ™¨Ô,Ð1DÈÏÉÏÉËÔ1VÐ[nÐrs×rxÑrx×r~Ñr~ó  sAô  \AØ(+¯©¹]Ó1d¹]¸ÐScÑNc·!°!¹]Ñ1dÔgkÐl}Óg~Õ1~Ó(ˆGÐ$Ñ%Ø—	‘	˜#¸�	Ó;ˆAô �Ð|˜˜W cÐ+HÐI×MÑMÈaÏmÉmÐ]zÓ{Ó|Ð|ùò	 2eøäô ,Ü�D˜& A a S¨ (Ó+Õ+ûð,ús<   ¤&E ÁBE Ã)EÃ6EÃ<-E ÅE ÅE?Å$E:Å4E?Å:E?c               ó   € V ^8„  d   QhRR/# r¸   r   )r'   s   "r   r(   r(   ±   s   € ÷ Cñ CÐ]hñ Cr   c                ó†  € \        R  R V 4        4       R4      pV'       g   \        V 4      # V P                  ^4      pV'       g   \        V RRVR7      #  ^ RIp\        WSV4      w  r‰p
VP                  R4      P                  R4      '       dY   \        W…4      pVP                  R	8X  d   \        V RVR7      # VP                  R
8X  d   \        V RRRV^ ,           R2.VR7      # MVP                  Wš^
R7      pV R8X  d.   V'       g&   VP                  R8X  d   VP                  RV
^
R7      pTP                  R8X  d   \        T RRRT^ ,           R2.TR7      # TP                  ^È8X  d   \        T RTR7      # \        T RRTP                   R2TR7      #   \         d   p\        T RRT R2TR7      u Rp?# Rp?ii ; i)c              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir2   r   )r\   Úks   & r   r^   Ú)_probe_apikey_provider.<locals>.<genexpr>²   s   é € ÐGÑA�aÃQ—’ÓAùs   ‚	�
c              3  óP   "  € T F  p\         P                  ! VR 4      x € K  	  R# 5i)r*   N)rÅ   rÆ   )r\   Úevs   & r   r^   rê   ²   s   é € ÐA¹°"œBŸIšI b¨"×-Ð-»ùs   ‚$&r*   r   z(key configured)©r   Nrb   ú
/anthropicrÛ   i“  r    z(access denied)zCheck z in .envr¾   ry   r¶   z8https://dashscope.aliyuncs.com/compatible-mode/v1/modelsr   rÁ   rÂ   rÜ   rÄ   )r¤   r3   Úljustr/   rÇ   Ú_apikey_requestr§   rV   Ú_anthropic_messages_proberÈ   r>   rC   )Úpnamer    Údefault_urlÚbase_envrd   rÊ   r   rÇ   Úbaserã   r¿   rË   rÌ   s   &&&&&        r   Ú_probe_apikey_providerrö   ±   sÅ  € Ü
ÑGÑA¹ÔAÓGÈÓ
L€CßÜ�U‹|ÐØ�K‰K˜‹O€Eß Ü�E˜4Ð!3¸5ÔAÐAð:ÛÜ,¨S¸KÓHÑˆ�7Ø�;‰;�sÓ×$Ñ$ \×2Ò2ä)¨$Ó4ˆAØ�}‰} Ô#Ü˜E 4¨uÔ5Ð5Ø�}‰} Ô#Ü˜E 6Ð+<ÀÈÐQRÍÀ}ÐT\Ð?]Ð>^ÐfkÔlÐlð $ð —	‘	˜#¸�	Ó;ˆAØÐ'Ô'·¸¿¹È#Ô9MØ—	‘	ÐTÐ^eÐoq�	ÓrˆAð 	‡}�}˜ÔÜ�E˜6Ð#6¸6À(È1Å+ÀÈhÐ9WÐ8XÐ`eÔfÐfØ-.¯]©]¸cÔ-AŒ4��t 5Ô)ð  CÄtÈEÐSYÐ]cÐde×dqÑdqÐcrÐrsÐ[tð  }Bô  HCð  Cøô	 ô :Ü�E˜6 Q q c¨ 8°5Ô9Õ9ûð:ús1   ÁA"F Â:,F Ã'"F Ä
%F ÆG Æ#F;Æ5G Æ;G c               ó    € V ^8„  d   QhRRRR/# )r"   rõ   r   rÊ   r   )r'   s   "r   r(   r(   Í   s   € ÷ ñ  Cð ¨cñ r   c           	     óz  € ^ RI p^ RIHp ^ RIHp V! V R4      w  rVV! V4      '       d   RRV 2/MRV/pRRR	\
        /VCp\        \        4       P                  R
4      ;'       g    R4      P                  4       ;'       g    Rp	RV	R^RRRRR/./p
VP                  VR,           W†P                  R4      V
^
R7      # )a  POST ``<base>/v1/messages`` with ``max_tokens=1`` exactly as the Anthropic adapter would: same
auth family (Bearer for Azure Foundry, else x-api-key) and the same ``api-version`` query. Azure
Foundry's ``/anthropic`` route 404s on ``GET /models`` even when chat works (#66756).N)Ú_base_client_kwargs)Ú_requires_bearer_authr¼   r½   rÚ   r×   rØ   ú
User-AgentÚdefaultr*   zclaude-sonnet-4-5ÚmodelÚ
max_tokensÚmessagesÚroleÚuserÚcontentÚpingz/v1/messagesÚdefault_query)r¿   ÚparamsÚjsonrÀ   )rÇ   rÞ   rù   Úagent.anthropic_endpointsrú   r   r   Ú
_model_cfgr>   r?   Úpost)rõ   rÊ   rÇ   rù   rú   Ú
normalizedÚkwargsr<   r¿   rý   Úbodys   &&         r   rñ   rñ   Í   sÌ   € ó Ý;Ý?Ù,¨T°4Ó8Ñ€JÙ1FÀz×1RÒ1RˆO˜w s e˜_Ñ-ÐYdÐfiÐXj€DØ" L°,Ô@RÐ[ÐVZÐ[€GÜ”
“× Ñ  Ó+×1Ð1¨rÓ2×8Ñ8Ó:×QÐQÐ>Q€EØ�U˜L¨!¨Z¸6À6È9ÐV\Ð:]Ð9^Ð_€DØ�:‰:�j >Õ1¸7Ï:É:ÐVeÓKfÐmqÐ{}ˆ:Ó~Ð~r   c               ó   € V ^8„  d   QhRR/# ©r"   r&   Údictr   )r'   s   "r   r(   r(   Ü   s   € ÷ <ñ <�Dñ <r   c                 óª   €  ^ RI Hp  V ! 4       ;'       g    / P                  R4      p\	        T\
        4      '       d   T# / #   \         d    / u # i ; i)é    ©Úload_config_readonlyrý   ©Úhermes_cli.configr  r>   rC   rž   r  )r  Ú	model_cfgs     r   r  r  Ü   sT   € ðÝ:Ù)Ó+×1Ð1¨r×6Ñ6°wÓ?ˆ	ô # 9¬d×3Ò3ˆ9Ð;¸Ð;øô ô ØŠ	ðúó   ‚A –A ÁAÁAc               ó    € V ^8„  d   QhRRRR/# )r"   rÊ   r   r&   r£   r   )r'   s   "r   r(   r(   å   s   € ÷ !ñ !˜ð !¸ñ !r   c                ó‚  € V'       d   \         P                  ! VR4      MRpV'       g�   VR8X  dˆ   \        \        4       P	                  R4      ;'       g    R4      P                  4       P                  4       R8X  d;   \        \        4       P	                  R4      ;'       g    R4      P                  4       pV'       g   V P                  R4      '       d   RpV'       d5   VP                  R4      P                  R	4      '       d   ^ R
I
Hp V! V4      p\        VR4      '       d?   VP                  R4      P                  R4      '       d   VP                  R4      R,           pV'       d   VP                  R4      R,           MTpRRV  2R\        /p\        VR4      '       d   RVR&   V'       d‹   \        VR4      '       g   \        VR4      '       dg   ^ RIHpHp VP#                  R^4      ^ ,          p	\        VR4      '       g   V! V	4      '       d&   V! V	4      R,           pVP%                  RR4       WR&   W5V3# )zd(effective base, models URL, headers) for a generic Bearer-auth probe, with the per-vendor rewrites.r*   ÚAZURE_FOUNDRY_BASE_URLÚproviderúazure-foundryr¥   zsk-kimi-zhttps://api.kimi.com/coding/v1rb   rî   )Ú_to_openai_base_urlzapi.kimi.comz/codingz/v1rc   r¼   r½   rû   zclaude-code/0.1.0z!generativelanguage.googleapis.comzaiplatform.googleapis.com)Úis_vertex_express_base_urlÚnormalize_gemini_base_urlNzx-goog-api-key)rÅ   rÆ   r   r  r>   r?   r@   Ú
startswithr§   rV   Úagent.auxiliary_clientr  r
   r   Úagent.gemini_native_adapterr  r  ÚrsplitÚpop)
rÊ   rô   ró   rõ   r  rã   r¿   r  r  Úroots
   &&&       r   rð   rð   å   sÈ  € ç&.Œ2�9Š9�X˜rÔ"°B€Dç�HÐ 8Ô8¼SÄÃ×AQÑAQÐR\ÓA]×AcÐAcÐacÓ=d×=jÑ=jÓ=l×=rÑ=rÓ=tð  yHô  >HÜ”:“<×#Ñ# JÓ/×5Ð5°2Ó6×<Ñ<Ó>ˆç�C—N‘N :×.Ò.Ø/ˆç�—‘˜CÓ ×)Ñ)¨,×7Ò7Ý>Ù" 4Ó(ˆÜ˜T >×2Ò2°t·{±{À3Ó7G×7PÑ7PÐQZ×7[Ò7[Ø�{‰{˜3Ó %Õ'ˆß,0ˆ4�;‰;�sÓ˜iÖ'°k€CØ '¨#¨ °Ô?QÐR€GÜ˜T >×2Ò2Ø 3ˆ�Ñ÷ Ô% cÐ+N×OÒOÜ(¨Ð.I×JÒJßeØ�z‰z˜) QÓ'¨Õ*ˆÜ  Ð&I×JÒJÑNhÐim×NnÒNnñ
 ,¨DÓ1°IÕ=ˆCØ�K‰K˜¨Ô.Ø(+Ð$Ñ%Ø�gÐÐr   c               ó   € V ^8„  d   QhRR/# r¸   r   )r'   s   "r   r(   r(   	  s   € ÷ ^ñ ^˜ñ ^r   c                 ó€  € R p  ^ RI HpHpHp T! 4       '       g   \        T 4      # T! 4       T! 4       T P                  ^4      rep ^ RIp^ RIH	p TP                  RYX! ^^
R^/R7      R7      p	\        T	P                  4       P                  R. 4      4      p
\        T R	R
T RT RT
 R2TR7      #   \         d    \        T 4      u # i ; i  \         d$    R\        R4       R2p\        T RRT.TR7      u # \          d<   p\#        T4      P$                  p\        T RR
T RT R2RT R2.TR7      u Rp?# Rp?ii ; i)úAWS Bedrock)Úhas_aws_credentialsÚresolve_aws_auth_env_varÚresolve_bedrock_regionN)ÚConfigr‰   Úmax_attempts)Úconnect_timeoutÚread_timeoutÚretries)Úregion_nameÚconfigÚmodelSummariesr   rÁ   ú, z models)rí   ú"From the Hermes environment, run: ú. Then restart Hermes.r   z(boto3 not installed)z: rÂ   zAWS Bedrock: u;    â€” check IAM permissions for bedrock:ListFoundationModels)Úagent.bedrock_adapterr)  r*  r+  ÚImportErrorr3   rï   Úboto3Úbotocore.configr,  ÚclientÚlenÚlist_foundation_modelsr>   r/   r   rC   Útyper   )r#   r)  r*  r+  Úauth_varÚregionr   r9  Ú_BotoConfigr;  ÚnÚhintrÌ   Úerr_names                 r   Ú_probe_bedrockrE  	  sŽ  € Ø€DðßoÑoñ × Ò Ü�T‹{ÐÙ6Ó8Ñ:PÓ:RÐTX×T^ÑT^Ð_aÓTb�e€Hð^ÛÝ9à—‘˜i°VÀKÐ`aÐprð  ~Lð  NOð  }Pô  EQ�ó  RˆÜ�×-Ñ-Ó/×3Ñ3Ð4DÀbÓIÓJˆÜ�D˜$ ! H :¨R°¨x°r¸!¸¸HÐ EÈUÔSÐSøô ô Ü�T‹{Òðûô ô PØ4Ü 	Ó*Ð+ð ,'ð'ˆô �D˜&Ð"9¸D¸6ÈÔOÒOÜô ^Ü˜“7×#Ñ#ˆÜ�D˜& A h Z¨r°!°°AÐ"6¸=ÈÈ
ð  SNð  :Oð  9Pð  X]ô  ^õ  	^ûð^ús<   „
B/ ÁA)C Â/CÃCÃ+D=Ã8D=ÄD=Ä0D8Ä2D=Ä8D=c               ó   € V ^8„  d   QhRR/# r¸   r   )r'   s   "r   r(   r(   #  s   € ÷ $`ñ $`˜Kñ $`r   c            	     ó  € Rp V P                  ^4      p ^ RIHp V! 4       p\        V\        4      '       d   VP                  R4      M/ p\        V\        4      '       g   \        V 4      # R# Uu. uFC  p\        VP                  V4      ;'       g    R4      P                  4       P                  4       NKE  	  upRR.8w  d   \        V 4      #   ^ RIHpHpHpHp	 T	! 4       '       g   \!        T RRR\#        R4       R2.TR7      # TP                  R4      ;'       g    / p\        T\        4      '       d3   \        TP                  R4      ;'       g    R4      P                  4       MR;'       g    TpT! T! TR7      RR7      pTP                  R4      '       dK   RP%                  TP                  R4      ;'       g    . 4      ;'       g    Rp\!        T RRT RT R
2TR7      # TP                  R4      ;'       g    RpTP                  R4      ;'       g    R p\!        T RRT R
2R!T R"T 2.TR7      # u upi   \         d    \        T 4      u # i ; i  \         d#   p
\!        T RR	T
 R
2RT
 2.TR7      u Rp
?
# Rp
?
ii ; i)$u  Probe Azure Foundry Entra ID auth, parallel to ``_probe_bedrock``.

Skipped unless the active config has ``model.provider: azure-foundry`` AND ``model.auth_mode: entra_id``
â€” we don't probe the token-service / CLI chain for plain API-key Azure. Bounded by a 10s timeout.
úAzure Foundry (Entra ID))Úload_configrý   r*   r  Úentra_id)ÚEntraIdentityConfigÚSCOPE_AI_AZURE_DEFAULTÚdescribe_active_credentialÚhas_azure_identity_installedr   z(adapter import failed: rÂ   z%Azure Foundry adapter import failed: rí   Nz(azure-identity not installed)r5  zazure-identityr6  ÚentraÚscope)rP  g      $@)r2  Útimeout_secondsr   r4  Úenv_sourceszdefault credential chainrÁ   z, scope=Úerrorzcredential chain exhaustedrC  zqRun `az login`, set AZURE_TENANT_ID/AZURE_CLIENT_ID/AZURE_CLIENT_SECRET, or attach a managed identity to this VM.zAzure Foundry Entra: z. )r  Ú	auth_mode)rï   r  rI  rž   r  r>   r3   r   r?   r@   rC   Úagent.azure_identity_adapterrK  rL  rM  rN  r/   r   rà   )r#   r   rI  Úcfgr  ré   rK  rL  rM  rN  ÚexcÚ	entra_cfgrP  ÚinfoÚtagÚerrrC  s                    r   Ú_probe_azure_entrar\  #  sŠ  € ð &€DØ�J‰J�r‹N€Eð	Ý1Ù‹mˆÜ(2°3¼×(=Ò(=�C—G‘G˜GÔ$À2ˆ	Ü˜)¤T×*Ò*Ü˜“;ÐÙAZÓ[ÑAZ¸AŒC�	—‘˜aÓ ×&Ð& BÓ'×-Ñ-Ó/×5Ñ5Ö7ÑAZÑ[Ð`oÐq{Ð_|Ô|Ü˜“;Ðð }ðC÷	
ó 	
ñ
 (×)Ò)Ü�D˜&Ð"BÐEiÜ$Ð%5Ó6Ð7ð 8,ðF,ð E-à49ô;ð 	;ð —‘˜gÓ&×,Ð,¨"€IÜ:DÀYÔPT×:UÒ:UŒS�—‘˜wÓ'×-Ð-¨2Ó.×4Ñ4Ô6Ð[]×xÐxÐbx€EÙ%Ñ-@ÀuÔ-MÐ_cÔd€DØ‡x�x�‡~‚~Ø�i‰i˜Ÿ™ Ó/×5Ð5°2Ó6×TÐTÐ:TˆÜ�D˜$ ! C 5¨°°°qÐ 9ÀÔGÐGØ
�(‰(�7Ó
×
;Ð
;Ð;€CØ�8‰8�FÓ÷  Sð  Sð   S€DÜ��f  #  a˜jÐ-BÀ3À%ÀrÈ$ÈÐ+PÐ*QÐY^Ô_Ð_ùò- \øäô Ü�T‹{Òðûô ô CÜ�D˜&Ð$<¸S¸EÀÐ"CÐHmÐnqÐmrÐFsÐEtð  }Bô  Cõ  	CûðCúsN   •AH> Á,H> Á0!H9Â'H9Â9H> ÃI È9H> È>IÉIÉJÉ%JÉ<JÊJc               ó   € V ^8„  d   QhRR/# r  r   )r'   s   "r   r(   r(   J  s   € ÷ 0ñ 0˜dñ 0r   c                 óª   €  ^ RI Hp  V ! 4       ;'       g    / P                  R4      p\	        T\
        4      '       d   T# / #   \         d    / u # i ; i)r  r  Únetworkr  )r  Únets     r   Ú_load_network_configra  J  sT   € ðÝ:Ù#Ó%×+Ð+¨×0Ñ0°Ó;ˆô ˜S¤$×'Ò'ˆ3Ð/¨RÐ/øô ô ØŠ	ðúr  c               ó    € V ^8„  d   QhRRRR/# )r"   rÀ   Úfloatr&   ÚNoner   )r'   s   "r   r(   r(   S  s   € ÷ ñ  Eð ¨dñ r   c                óú   € \         P                   ! \         P                  \         P                  4      ;_uu_ 4       pVP                  V4       VP	                  V 4       RRR4       R#   + '       g   i     R# ; i)zTOpen + close one IPv6 TCP connection; raises OSError (TimeoutError on a dead route).N)ÚsocketÚAF_INET6ÚSOCK_STREAMÚ
settimeoutÚconnect)ÚsockaddrrÀ   Úsocks   && r   Ú_tcp_connectrm  S  sF   € ä	�Š”v—‘¬×(:Ñ(:×	;Ô	;¸tØ�‰˜Ô Ø�‰�XÔ÷ 
<×	;×	;Ò	;ús   ¼#A)Á)A:	g       @c               ó   € V ^8„  d   QhRR/# r¸   r   )r'   s   "r   r(   r(   ]  s   € ÷ @ñ @˜+ñ @r   c                 óÒ  € Rp \        4       P                  R4      '       d   \        V 4      # \        \        4      P
                  p \        P                  ! VR\        P                  \        P                  4      pV'       g   \        V 4      #  \        V^ ,          ^,          \        4       \        T RRT R24      #   \         d    . p LRi ; i  \         d'    Rp\        T RRT R\        R R	T R
2RT 2.4      u # \         d[   pTP                  \        P                   \        P"                  \        P$                  39   d   \        T RR4      u Rp?#  Rp?L³Rp?ii ; i)zºDead-IPv6-route detector (#114265): an advertised AAAA path that only times out makes every
serial connect burn its full timeout before IPv4 answers. Name the remedy instead of stalling.ú
IPv6 routeÚ
force_ipv4i»  zEset `network.force_ipv4: true` in config.yaml (or fix the IPv6 route)r   z(IPv6 route to z. advertised but dead: connect timed out after Úgu   s â€” rÂ   zKDead IPv6 route: every IPv6-first connect stalls before IPv4 answers. Fix: r   u   (no IPv6 route â€” IPv4 only)Nz(IPv6 path to z reachable))ra  r>   r3   r   r	   Úhostnamerf  Úgetaddrinforg  rh  ÚOSErrorrm  Ú_IPV6_PROBE_TIMEOUTÚTimeoutErrorr/   ÚerrnoÚENETUNREACHÚEHOSTUNREACHÚEADDRNOTAVAIL)r#   ÚhostÚinfosÚremedyrÌ   s        r   Ú_probe_ipv6_pathr  ]  sS  € ð €DÜÓ×!Ñ! ,×/Ò/Ü�T‹{ÐÜÔ)Ó*×3Ñ3€DðÜ×"Ò" 4¨¬f¯o©o¼v×?QÑ?QÓRˆ÷ Ü�T‹{Ðð	EÜ�U˜1•X˜a•[Ô"5Ô6ô ��d˜n¨T¨F°+Ð>Ó?Ð?øô ô ØŠðûô ô nØXˆÜ�D˜& O°D°6Ð9gÜ*¨1Ð-¨V°F°8¸1ð#>àbÐciÐbjÐkÐlónò 	nô ô EØ�7‰7”u×(Ñ(¬%×*<Ñ*<¼e×>QÑ>QÐRÔRÜ˜˜dÐ$CÓDÕDô SûðEús=   Á5B? ÂC Â?CÃCÃ.E&ÄE&ÄE&ÄA
E!ÅE&Å!E&z!https://api.github.com/rate_limitc               ó   € V ^8„  d   QhRR/# r¸   r   )r'   s   "r   r(   r(   }  s   € ÷ Mñ M˜[ñ Mr   c            
     ó"  a€ Rp ^ RI HoHp \        V3R lR 4       R4      pVf   \	        V 4      # ^ RIHp W!! 4       9   d   V R2MRp ^ RIpVP                  \        ^
RR	S! V4       2R
\        RR/R7      pTP                  ^È8X  d   \        T RRT RT R24      # TP                  R8X  d   \        T RRT RT R2T RT R2.4      # \        T RRTP                   R24      #   \         d   p\        T RRT R2R.4      u Rp?# Rp?ii ; i)aE  Validate a configured ``GITHUB_TOKEN``/``GH_TOKEN`` against api.github.com (#115257).

A dead PAT in ``.env`` used to fail every git-auth clone with a message that never named the
token; the resolver now falls through to the gh CLI, and this row tells the user WHICH file
still carries the stale token so they can remove it.
úGitHub token)Úget_env_valueÚload_envc              3  óH   <"  € T F  pS! V4      '       g   K  Vx € K  	  R # 5ir2   r   )r\   rW   rƒ  s   & €r   r^   Ú&_probe_github_token.<locals>.<genexpr>†  s   øé € ÐLÑ7�a¹=È×;K—’Ó7ùr`   N)Ú_DHHz/.envzthe environmentr¼   r½   rû   ÚAcceptzapplication/vnd.github+json)rÀ   r¿   r    rÁ   rÂ   rÃ   r   z from z accepted by api.github.com)r¶   z in u3    rejected by api.github.com â€” expired or revoked)zW is expired or revoked: remove it (gh CLI login is used instead) or paste a fresh tokenrÄ   z from api.github.com))ÚGITHUB_TOKENÚGH_TOKEN)r  rƒ  r„  r¤   r3   Úhermes_cli.doctorr‡  rÇ   r>   ÚGITHUB_API_PROBE_URLr   rC   r/   rÈ   )	r#   r„  Úvarr‡  ÚwhererÇ   rË   rÌ   rƒ  s	           @r   Ú_probe_github_tokenr�  }  sM  ø€ ð €Dß9Ü
ÔLÑ7ÓLÈdÓ
S€CØ
‚{Ü�T‹{ÐÝ&Ø! X£ZÔ/ˆtˆf�E‰NÐ5F€EðLÛØ�I‰IÔ*°BØ˜w¡}°SÓ'9Ð&:Ð;¸\ÔK]ØÐ3ðA5ˆIó 6ˆð
 	‡}�}˜ÔÜ�D˜$ ! C 5¨¨u¨gÐ5QÐ RÓSÐSØ‡}�}˜ÔÜ�D˜& A c U¨$¨u¨gÐ5hÐ"iØ�u˜D  Ð'~Ðð  AóBð 	Bä��f  q§}¡} oÐ5JÐKÓLÐLøô ô LÜ�D˜& A a S¨ (Ð-IÐ,JÓKÕKûðLús   Á
/C& Ã&DÃ1D	ÄDÄ	Dc               ó   € V ^8„  d   QhRR/# rG   r   )r'   s   "r   r(   r(   š  s   € ÷ ñ �dñ r   c                 óž   € \         f   \        4       s R\        3R\        3R\        3.R \          4       OR\
        3NR\        3NR\        3N# )z)(label, callable) pairs in display order.rp  rº   rÑ   c              3  ój   "  € T F)  q^ ,          \         P                  ! \        .VO5!  3x € K+  	  R# 5i)r  N)Ú	functoolsÚpartialrö   )r\   Úrows   & r   r^   Úbuild_probes.<locals>.<genexpr>£  s*   é € Ð	gÑOfÈˆq�6”9×$Ò$Ô%;ÐB¸cÓBÕ
CÓOfùs   ‚13r(  rH  r‚  )r   rµ   r  rÎ   rå   rE  r\  r�  r   r   r   Úbuild_probesr—  š  sx   € ô Ò&Ü">Ó"@Ðà	Ô'Ð(Ø	Ô,Ð-°ÔAQÐ/Rðñ 
hÕOfÓ	gð	ð
 
œÐ'ðð
 +EÔFXÐ)Yðð 
Ô,Ð-ðð r   c               ó    € V ^8„  d   QhRRRR/# )r"   Úprobesr   r&   r   )r'   s   "r   r(   r(   ©  s   € ÷ Añ A�tð A ñ Ar   c           	     ó  € \        4        \        P                  P                  R4      pR\        P                  R&    \        P
                  P                  ^RR7      ;_uu_ 4       pV  UUu. uF  w  r4VP                  V4      NK  	  upp Uu. uF  qUP                  4       NK  	  upuuRRR4       Vf"   \        P                  P                  RR4       # V\        P                  R&   # u uppi u upi   + '       g   i     M; i Tf#   \        P                  P                  RR4       R# T\        P                  R&   R#   Tf"   \        P                  P                  RR4       i T\        P                  R&   i ; i)zøRun every probe in a thread pool; results in submission order.

Probes are independent HTTP calls (series cost ~5s wall, 2s of it boto3's IMDS lookup);
parallel collapses the section to roughly the slowest single probe without changing the output.
ÚAWS_EC2_METADATA_DISABLEDÚtruezdoctor-probe)Úmax_workersÚthread_name_prefixN)
r   rÅ   Úenvironr>   Ú
concurrentÚfuturesÚThreadPoolExecutorÚsubmitÚresultr$  )r™  Ú
_imds_prevÚexÚ_ÚfnÚfs   &     r   Ú
run_probesrª  ©  s$  € ô Ôô —‘—‘Ð ;Ó<€JØ.4„B‡J�JÐ*Ñ+ðAä×Ñ×2Ñ2¸qÐUcÐ2×dÔdÐhjÙDJÔ(KÁF¹5¸1¨¯©°2®ÁFÓ(KÓLÑ(K 1—H‘H–JÑ(KÑL÷ eÑdð ÒÜ�J‰J�N‰NÐ6¸Õ=à6@ŒB�J‰JÐ2Ò3ùó )LùÒL÷ e×dúÐdð ÒÜ�J‰J�N‰NÐ6¸Ö=à6@ŒB�J‰JÐ2Ó3øð ÒÜ�J‰J�N‰NÐ6¸Õ=à6@ŒB�J‰JÐ2Ò3úsA   ¾)E Á'C7Á-C,
Â	C7ÂC2Â'C7Â)
E Ã,C7Ã7D	ÄE Å:F )r*   NN)rÜ   z Check OPENROUTER_API_KEY in .env)u%   (out of credits â€” payment required)zÂOpenRouter account has insufficient credits. Fix: run 'hermes config set model.provider <provider>' to switch providers, or fund your OpenRouter account at https://openrouter.ai/settings/credits)z(rate limited)uS   OpenRouter rate limit hit â€” consider switching to a different provider or waiting)6Ú__conditional_annotations__Ú__doc__Ú
__future__r   Úpmr   Úconcurrent.futuresr   rx  r“  rÅ   rf  Útypingr   Úurllib.parser   Úhermes_cli.colorsr   r   Úhermes_cli.modelsr   Úhermes_constantsr	   Úutilsr
   r   r   r   r   ÚGREENÚYELLOWÚREDr+   r/   r3   rE   rµ   rÉ   rÎ   rå   rö   rñ   r  rð   rE  r\  ra  rm  rv  r  rŒ  r�  r—  rª  )r«  s   @r   Ú<module>r¹     s  øðôõ #å Û Û Û Û 	Û Ý Ý !ç +Ý 0Ý 2ß Aà'+Ð ˜Ó +ô�*ô ð �˜Ÿ™Ð% v°°v·}±}Ð/EÀvÐPUÐW]×WaÑWaÐObÐ	c€÷+õ%õ
õ?ðH Ð	BØð 
7ð
 Ð	rðÐ õBõ }õ2Cõ8õ<õ!õH^õ4$`õN0õð Ð õ@ð: ;Ð õMõ:÷Ar   