+
    lHàjÎA  ã                   óª   € R t ^ RIt^ RIt^ RIt^ RIt^ RIHtHt ^ RIH	t	H
t
 ^ RIHt ^ RIHt ^ RIHt ]P$                  ! R4      tRt ! R	 R
4      tR# )zìSession health for MCPServerTask: dynamic tool refresh on list_changed notifications, server
log forwarding, keepalive probes, suspect-mark / lazy-verify, in-flight call fail-fast, stdio
child liveness and stdio idle/lifetime recycling.N)ÚIterableÚOptional)Ú_is_method_not_found_errorÚ_unwrap_exception_group)Úmcp_prefixed_tool_name)Ú_core)Úmcp_tool_registrationztools.mcp_toolg      >@c                   óh  a € ] tR t^t o RtR(tV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR	 lt	R
 t
R)V 3R lR lltV 3R lR ltV 3R lR ltV 3R lR ltR tR tV 3R lR ltR tV 3R lR ltV 3R lR ltV 3R lR ltR*V 3R lR  lltV 3R! lR" ltV 3R# lR$ ltV 3R% lR& ltR'tV tR# )+ÚMCPServerHealthMixinzVMethods of :class:`tools.mcp_tool.MCPServerTask` (mixed in; relies on its attributes).c                ó    <€ V ^8„  d   QhRS[ /# ©é   Úreturn©Úbool)ÚformatÚ__classdict__s   "€Ú:/home/ubuntu/.hermes/hermes-agent/tools/mcp_tool_health.pyÚ__annotate__Ú!MCPServerHealthMixin.__annotate__   s   ø€ ÷ %ñ %™$ñ %ó    c                ó    € R V P                   9   # )Úurl)Ú_config©Úselfs   &r   Ú_is_httpÚMCPServerHealthMixin._is_http   s   € Ø˜Ÿ™Ñ$Ð$r   c                ó    <€ V ^8„  d   QhRS[ /# r   r   )r   r   s   "€r   r   r      s   ø€ ÷ Iñ I¡Dñ Ir   c                óX   € V P                  4       '       * ;'       d    V P                  RJ# )z4True when a stdio server was intentionally recycled.N)r   Ú_recycled_reasonr   s   &r   Ú_is_recycled_stdioÚ'MCPServerHealthMixin._is_recycled_stdio   s$   € à—=‘=“?Ô"×HÐH t×'<Ñ'<ÀDÐ'HÐHr   c                ó   <€ V ^8„  d   QhRR/# ©r   r   N© )r   r   s   "€r   r   r       s   ø€ ÷ 3ñ 3 ñ 3r   c                ó:   € \         P                  ! 4       V n        R# )z5Record that a user-visible MCP operation is starting.N)ÚtimeÚ	monotonicÚ_last_tool_call_atr   s   &r   Úmark_tool_callÚ#MCPServerHealthMixin.mark_tool_call    s   € ä"&§.¢.Ó"2ˆÖr   c                ó   <€ V ^8„  d   QhRR/# r$   r%   )r   r   s   "€r   r   r   $   s   ø€ ÷ %ñ %¨ñ %r   c                óV   € \         P                  ! 4       ;V n        V n        R V n        R # ©N)r'   r(   Ú_lifecycle_started_atr)   r    r   s   &r   Ú_mark_lifecycle_startedÚ,MCPServerHealthMixin._mark_lifecycle_started$   s!   € Ü?C¿~º~Ó?OÐOˆÔ" TÔ%<Ø $ˆÖr   c                ó0  € V P                  4       '       g!   V P                  P                  4       '       d   . # V P                  V P                  R3V P
                  V P                  R33pV UUUu. uF  w  r#qCf   K  W#,           V3NK  	  uppp# u upppi )zj``[(deadline, reason), ...]`` for the lifetime/idle limits; empty for HTTP or while an RPC holds the lock.Úmax_lifetime_secondsÚidle_timeout_seconds)r   Ú	_rpc_lockÚlockedr/   Ú_max_lifetime_secondsr)   Ú_idle_timeout_seconds)r   ÚlimitsÚstartÚlimitÚreasons   &    r   Ú_stdio_recycle_deadlinesÚ-MCPServerHealthMixin._stdio_recycle_deadlines(   s�   € à�=‰=�?Š?˜dŸn™n×3Ñ3×5Ò5ØˆIØ×-Ñ-¨t×/IÑ/IÐKaÐbØ×*Ñ*¨D×,FÑ,FÐH^Ð_ðaˆáDJÕ`ÁFÑ,@¨E¸&Ô'�• Ó'ÁFÓ`Ð`ùÔ`s   Á1BÁ>BNc                óF   <€ V ^8„  d   QhRS[ S[,          RS[ S[,          /# )r   Únowr   )r   ÚfloatÚstr)r   r   s   "€r   r   r   0   s'   ø€ ÷ oñ o©±%­ð oÁHÉSÅMñ or   c                ó‚   a€ Sf   \         P                  ! 4       MSo\        V3R lV P                  4        4       R4      # )zTThe stdio recycle reason if idle/age limits have elapsed (lifetime wins), else None.Nc              3   ó>   <"  € T F  w  rSV8¼  g   K  Vx € K  	  R # 5ir.   r%   )Ú.0Údeadliner<   r@   s   &  €r   Ú	<genexpr>Ú=MCPServerHealthMixin._stdio_recycle_reason.<locals>.<genexpr>3   s!   øé € ÐgÑ4SÑ 0 ÐWZÐ^fÑWf—V’VÓ4Sùs   ƒ“
)r'   r(   Únextr=   )r   r@   s   &fr   Ú_stdio_recycle_reasonÚ*MCPServerHealthMixin._stdio_recycle_reason0   s2   ø€ à"%¢+Œd�nŠnÔ°3ˆÜÔg°D×4QÑ4QÔ4SÓgÐimÓnÐnr   c                ó0   <€ V ^8„  d   QhRS[ S[,          /# r   )r   rA   )r   r   s   "€r   r   r   5   s   ø€ ÷ Rñ R©h±u­oñ Rr   c                óF   € \        R  V P                  4        4       RR7      # )c              3   ó*   "  € T F	  w  rVx € K  	  R # 5ir.   r%   )rE   ÚdÚ_s   &  r   rG   ÚDMCPServerHealthMixin._next_stdio_recycle_deadline.<locals>.<genexpr>6   s   é € ÐBÑ"A™$˜!•AÓ"Aùs   ‚N)Údefault)Úminr=   r   s   &r   Ú_next_stdio_recycle_deadlineÚ1MCPServerHealthMixin._next_stdio_recycle_deadline5   s   € ÜÑB $×"?Ñ"?Ô"AÓBÈDÔQÐQr   c                ó$   <€ V ^8„  d   QhRS[ RR/# ©r   r<   r   N©rB   )r   r   s   "€r   r   r   8   s   ø€ ÷ ñ ©3ð °4ñ r   c                ó    € Wn         RV n        R# )zCMark a stdio session dormant before its transport finishes closing.N)r    Úsession©r   r<   s   &&r   Ú_mark_stdio_recycledÚ)MCPServerHealthMixin._mark_stdio_recycled8   s   € à &ÔØˆŽr   c                ó4   <€ V ^8„  d   QhRS[ P                  /# r   )ÚasyncioÚTask)r   r   s   "€r   r   r   =   s   ø€ ÷ 
ñ 
©¯©ñ 
r   c                óÊ   a € V 3R lp\         P                  ! V! 4       4      pS P                  P                  V4       VP	                  S P                  P
                  4       V# )zUSchedule a background tool refresh (failures logged) and keep it strongly referenced.c               “   óª   <"  €  S P                  4       G R j  x€L
  R #  L  \         d%    \        P                  RS P                  4        R # i ; i5i)Nz,MCP server '%s': dynamic tool refresh failed)Ú_refresh_toolsÚ	ExceptionÚloggerÚ	exceptionÚnamer   s   €r   Ú_runÚ:MCPServerHealthMixin._schedule_tools_refresh.<locals>._run?   sF   øé € ð\Ø×)Ñ)Ó+×+Ô+øÜô \Ü× Ñ Ð!OÐQU×QZÑQZ×[ð\üs1   ƒA…! ˜™! �AŸ! ¡+AÁAÁAÁA)r_   Úcreate_taskÚ_pending_refresh_tasksÚaddÚadd_done_callbackÚdiscard)r   rh   Útasks   f  r   Ú_schedule_tools_refreshÚ,MCPServerHealthMixin._schedule_tools_refresh=   sP   ø€ õ	\ô
 ×"Ò"¡4£6Ó*ˆØ×#Ñ#×'Ñ'¨Ô-Ø×Ñ˜t×:Ñ:×BÑBÔCØˆr   c                ó   a € V 3R lpV# )a®  ``logging_callback`` forwarding server ``notifications/message`` into Hermes logging (SDK default drops them).

Routes MCP ``notifications/message`` log notifications from the server into Hermes' logging
(agent.log via hermes_logging), tagged with the server name. Without this, the SDK's default
callback silently discards them, so server-side warnings/errors during a tool call were invisible.
Port of anomalyco/opencode#34529.
c           	   “   ó²  <"  €  \         P                  P                  \        \	        V R R4      4      P                  4       \        P                  4      p\	        V RR4      p\        V\        4      '       g    \        P                  ! VR\        R7      p\        V4      R8”  d   VR,          R,           p\	        V R	R4      pV'       d   SP                   R
V 2MSP                  p\        P!                  VRWB4       R#   \        \        3 d    \        T4      p L‰i ; i  \"         d'    \        P%                  RSP                  RR7        R# i ; i5i)ÚlevelÚinfoÚdataNF)Úensure_asciirR   iÐ  :NiÐ  Nz... [truncated]re   Ú/zMCP server log [%s]: %sz/Failed to handle MCP log notification from '%s'T)Úexc_info)r   Ú_MCP_LOG_LEVEL_MAPÚgetrB   ÚgetattrÚlowerÚloggingÚINFOÚ
isinstanceÚjsonÚdumpsÚ	TypeErrorÚ
ValueErrorÚlenrg   re   Úlogrd   Údebug)Úparamsrt   rv   Úlogger_nameÚoriginr   s   &    €r   Ú_on_logÚ<MCPServerHealthMixin._make_logging_callback.<locals>._on_logQ   s  øé € ðjÜ×0Ñ0×4Ñ4´S¼ÀÈÐRXÓ9YÓ5Z×5`Ñ5`Ó5bÔdk×dpÑdpÓq�Ü˜v v¨tÓ4�Ü! $¬×,Ò,ð)Ü#Ÿzšz¨$¸UÌCÔP˜ô �t“9˜tÔ#Ø �;Ð):Õ:�DÜ% f¨h¸Ó=�ß9D˜DŸI™I˜; a¨ }Ñ5È$Ï)É)�Ü—
‘
˜5Ð";¸VÖJøô &¤zÐ2ô )Ü" 4›yšð)ûô ô jÜ—‘ÐNÐPT×PYÑPYÐdh�×iðjüsN   ƒE…A3D# Á9D ÂA)D# Ã?EÄD ÄD# ÄD Ä D# Ä#-EÅEÅEÅEr%   )r   r‹   s   f r   Ú_make_logging_callbackÚ+MCPServerHealthMixin._make_logging_callbackI   s   ø€ õ	jð  ˆr   c                ó   a € V 3R lpV# )zj``message_handler``: only ``ToolListChangedNotification`` triggers a refresh; prompt/resource changes log.c              “   ó^  <"  €  \        V \        4      '       d$   \        P                  R SP                  V 4       R# \
        P                  '       d!   \        V \
        P                  4      '       g   R# \        V RV 4      p\        V\
        P                  4      '       dQ   \        P                  RSP                  4       SP                  4        \        P                  ! ^ 4      G Rj  x€L
  R# \        V\
        P                  4      '       d#   \        P                  RSP                  4       R# \        V\
        P                  4      '       d#   \        P                  RSP                  4       R# R#  LŒ  \         d%    \        P!                  RSP                  4        R# i ; i5i)z'MCP message handler (%s): exception: %sNÚrootz9MCP server '%s': received tools/list_changed notificationz/MCP server '%s': prompts/list_changed (ignored)z1MCP server '%s': resources/list_changed (ignored)z%Error in MCP message handler for '%s')r€   rd   re   r‡   rg   r   Ú_MCP_NOTIFICATION_TYPESÚServerNotificationr|   ÚToolListChangedNotificationru   rp   r_   ÚsleepÚPromptListChangedNotificationÚResourceListChangedNotificationrf   )ÚmessageÚpayloadr   s   & €r   Ú_handlerÚ<MCPServerHealthMixin._make_message_handler.<locals>._handlere   s0  øé € ðUÜ˜g¤y×1Ò1Ü—L‘LÐ!JÈDÏIÉIÐW^Ô_ÙÜ×5×5Ð5¼*ÀWÌe×NfÑNf×:gÒ:gÙô " '¨6°7Ó;�Ü˜g¤u×'HÑ'H×IÒIÜ—K‘KÐ [Ð]a×]fÑ]fÔgð ×0Ñ0Ô2Ü!Ÿ-š-¨Ó*×*Ò*Ü ¬×)LÑ)L×MÒMÜ—L‘LÐ!RÐTX×T]ÑT]Ö^Ü ¬×)NÑ)N×OÒOÜ—L‘LÐ!TÐVZ×V_ÑV_Ö`ñ Pñ +øô
 ô UÜ× Ñ Ð!HÈ$Ï)É)×TðUüsq   ƒF-…7E; ¼F-¾E; Á E; Á4F-Á6A6E; Ã,E9Ã-E; Ã1F-Ã3A E; Ä3F-Ä5A E; Å5F-Å9E; Å;+F*Æ&F-Æ)F*Æ*F-r%   )r   rš   s   f r   Ú_make_message_handlerÚ*MCPServerHealthMixin._make_message_handlerc   s   ø€ õ	Uð, ˆr   c                ó4   <€ V ^8„  d   QhRS[ S[,          RR/# )r   Ú
tool_namesr   N)r   rB   )r   r   s   "€r   r   r   }   s#   ø€ ÷ Oñ O©H±S­Mð O¸dñ Or   c                óš   € ^ RI Hp V F>  pVP                  V4      RV P                   28X  g   K(  \        P
                  ! W4       K@  	  R# )zjDeregister *tool_names* this server's toolset still owns (never a colliding name owned by another server).)Úregistryzmcp-N)Útools.registryr¡   Úget_toolset_for_toolrg   Ú_registrationÚ_deregister_mcp_tool_all_scopes)r   rŸ   r¡   Ú	tool_names   &&  r   Ú_deregister_ownedÚ&MCPServerHealthMixin._deregister_owned}   s;   € å+Û#ˆIØ×,Ñ,¨YÓ7¸TÀ$Ç)Á)ÀÐ;MÖMÜ×=Ò=¸dÖNó $r   c              ƒ  óÆ  "  € \        V RR4      e   R# V P                  4       '       g   R# V P                  ;_uu_4       GRj  x€L
  \        V P                  4      pV P
                  ;_uu_4       GRj  x€L
  V P                  pVfD   \        P                  RV P                  4        RRR4      GRj  x€L
  RRR4      GRj  x€L
  R# \        P                  ! VP                  RV P                  4      G Rj  x€L
 pRRR4      GRj  x€L
  T P                  TX Uu0 uF#  p\        V P                  VP                  4      kK%  	  up,
          4       W0n        \         P"                  ! V P                  W P$                  4      pV P                  V\        V4      ,
          4       WPn        \        V4      pRWa,
          3RW,
          33 UUu. uF.  w  rxV'       g   K  V RRP'                  \)        V4      4       2NK0  	  p	ppV	'       d2   \        P+                  R	V P                  R
P'                  V	4      4       M4\        P-                  RV P                  \/        V P                  4      4       RRR4      GRj  x€L
  R#  ELD EL EL× ELÊ EL— ELŠ  + GRj  x€L 
 '       g   i     EL¢; iu upi u uppi  L@  + GRj  x€L 
 '       g   i     R# ; i5i)uÊ   Re-fetch tools on ``tools/list_changed`` and update the registry. The lock serializes rapid-fire
notifications; after the list_tools ``await`` all mutations are synchronous â€” atomic on the event loop.Ú_editor_frozen_manifestNzEMCP server '%s': skipping dynamic tool refresh; session not connectedÚtoolsÚaddedÚremovedz: z, uU   MCP server '%s': tools changed dynamically â€” %s. Verify these changes are expected.z; z>MCP server '%s': dynamically refreshed %d tool(s) (no changes))r|   Ú_advertises_toolsÚ_refresh_lockÚsetÚ_registered_tool_namesr5   rZ   re   r‡   rg   r   Ú_paginate_full_listÚ
list_toolsr§   r   Ú_toolsr¤   Ú_register_server_toolsr   ÚjoinÚsortedÚwarningru   r…   )
r   Úold_tool_namesrZ   Únew_mcp_toolsÚtoolÚregistered_namesÚnew_tool_namesÚlabelÚnamesÚchangess
   &         r   rc   Ú#MCPServerHealthMixin._refresh_tools„   s5  é € ô �4Ð2°DÓ9ÒEÙØ×%Ñ%×'Ò'ÙØ×%×%×%Ó%Ü  ×!<Ñ!<Ó=ˆNØ—~—~—~“~ð Ÿ,™,�Ø’?Ü—L‘LÐ!hÐjn×jsÑjsÔtØ÷ &—~÷ &×%Ñ%ô ',×&?Ò&?À×@RÑ@RÐT[Ð]a×]fÑ]fÓ&g× g�÷ &—~ð ×"Ñ" >Ñn{Ó4|Ñn{ÐfjÔ5KÈDÏIÉIÐW[×W`ÑW`Ö5aÑn{Ñ4|Õ#|Ô}ð (ŒKÜ,×CÒCÀDÇIÁIÈt×UaÑUaÓbÐØ×"Ñ" >´CÐ8HÓ4IÕ#IÔJØ*:Ô'Ü Ð!1Ó2ˆNà  .Õ"AÐBÀYÐP^ÕPoÐDpÑqô|Ùqñ COÀ%Üuzô >˜%˜  4§9¡9¬V°E«]Ó#;Ð"<Ó=Ùqð ñ |çÜ—‘ð  DØEIÇYÁYÐPT×PYÑPYÐZaÓPbõdô —‘Ð\Ø ŸI™I¤s¨4×+FÑ+FÓ'GôI÷; &×%Ô%å%ò &ò !h÷ &—~—~”~üò 5}ùó|÷/ &×%×%Ó%üs  ‚'K!ªK!ÁJÁK!Á.KÁ6JÁ7KÁ:2J	Â,KÂ7JÂ8KÂ<K!ÃJÃK!Ã/J	Ã=JÃ>J	ÄKÄJÄKÄ")J7ÅBKÇJ<
Ç##J<
ÈA0KÉ6K!ÊKÊK!ÊKÊKÊK!ÊJ	ÊKÊJ4Ê J#Ê!
J4Ê,J4Ê.KËK!ËK	Ë
KË
K	ËK	Ë	K!c                ó   <€ V ^8„  d   QhRR/# r$   r%   )r   r   s   "€r   r   r   «   s   ø€ ÷ ñ ¨ñ r   c              ƒ  óÎ  a "  € V 3R lpS P                   '       g@    \        P                  ! S P                  P	                  4       \
        R7      G Rj  x€L
  R# V! 4       G Rj  x€L
  R#  L  \         dè   p\        T4      '       dD   S P                  4       '       g   h RS n         \        P                  RS P                  4        Rp?Lr\        T\        \        P                  34      '       dh   S P                  4       '       dR    T! 4       G Rj  x€L 
  M  \         d    TRhi ; iRS n         \        P                  RS P                  4        Rp?R# h Rp?ii ; i Lý5i)a  Exercise the session; raise on a genuine connection failure. ``ping`` first (cheap,
OPTIONAL); on -32601 latch ``_ping_unsupported`` (reset per transport connection) and fall
back to ``list_tools`` when the server advertises tools, else the -32601 propagates.c               “   óŒ   <"  € \         P                  ! S P                  P                  4       \        R 7      G Rj  x€L
  R#  L5i)©ÚtimeoutN)r_   Úwait_forrZ   r³   Ú_KEEPALIVE_RPC_TIMEOUTr   s   €r   r³   Ú9MCPServerHealthMixin._keepalive_probe.<locals>.list_tools¯   s*   øé € Ü×"Ò" 4§<¡<×#:Ñ#:Ó#<ÔF\Ô]×]Ô]ùs   ƒ8A»A¼ArÅ   NTz~MCP server '%s': does not implement the optional 'ping' utility (-32601); using 'list_tools' for keepalive on this connection.u�   MCP server '%s': ping timed out but list_tools succeeded â€” server silently drops ping; using 'list_tools' for keepalive on this connection.)Ú_ping_unsupportedr_   rÇ   rZ   Ú	send_pingrÈ   rd   r   r®   re   ru   rg   r€   ÚTimeoutError)r   r³   Úexcs   f  r   Ú_keepalive_probeÚ%MCPServerHealthMixin._keepalive_probe«   s*  øé € õ	^à×%×%Ð%ðÜ×&Ò& t§|¡|×'=Ñ'=Ó'?ÔI_Ô`×`Ð`Ùñ* ‹l×Òñ- aøäô Ü-¨c×2Ò2Ø×1Ñ1×3Ò3ØØ-1�DÔ*Ü—K‘Kð !WØX\×XaÑXa÷cñ cä ¤l´G×4HÑ4HÐ%I×JÒJÈt×OeÑOe×OgÒOgð,Ù(›l×*Ò*øÜ$ô ,Ø! tÐ+ð,úà-1�DÔ*Ü—K‘Kð !lØmq×mvÑmvôxåàûð'úñ( 	ùsˆ   ƒE%�7A. ÁA,ÁA. ÁE%Á%E#Á&E%Á,A. Á.E Á9&EÂ (EÃE%Ã;EÄ

DÄDÄDÄEÄD*Ä**EÅE%ÅEÅE Å E%c                ó   <€ V ^8„  d   QhRR/# r$   r%   )r   r   s   "€r   r   r   Ë   s   ø€ ÷ Añ A dñ Ar   c                óæ   € V P                   '       d   R# RV n         ^ V n        RV n        V P                  '       d(   RV n        \        P                  RV P                  4       R;V n        V n        R# )uÔ  Record that the session demonstrated real health (keepalive or tool-call success).
Only then is the reconnect budget cleared: a handshake that drops moments later must keep
consuming ``_reconnect_retries`` so a flapping transport still reaches the park.

Called from the keepalive success path (session survived a full keepalive interval â€” for
stdio without a keepalive, a full default interval idle with the child alive) and the
tool-call success path. See #62212.
NTFu^   MCP server '%s': revived â€” session healthy again after parking (state: parked â†’ connected))	Ú_session_provenÚ_reconnect_retriesÚ_park_reasonÚ_was_parkedre   r¸   rg   Ú_permanent_grace_usedÚ_teardown_racer   s   &r   Ú_mark_session_provenÚ)MCPServerHealthMixin._mark_session_provenË   sl   € ð ××ÐÙØ#ˆÔØ"#ˆÔØ ˆÔØ××ÐØ$ˆDÔÜ�N‰Nð CØDHÇIÁIôOð <AÐ@ˆÔ" TÖ%8r   c                ó$   <€ V ^8„  d   QhRS[ RR/# rW   rX   )r   r   s   "€r   r   r   à   s   ø€ ÷ 	.ñ 	.¡3ð 	.¨4ñ 	.r   c                ó–   € V P                   f*   V'       d"   \        P                  RV P                  V4       T;'       g    RV n         R# )a+  Latch a suspicion (no I/O); the NEXT call verifies via :meth:`ensure_healthy` and recycles on failure.

The NEXT call verifies via :meth:`ensure_healthy` and recycles the transport if the probe fails,
instead of the connection silently staying poisoned until process restart (#81051/#77765/#84132).
NzOMCP server '%s': connection marked suspect (%s); next call will health-check it)Ú_suspect_reasonre   r¸   rg   r[   s   &&r   Úmark_suspectÚ!MCPServerHealthMixin.mark_suspectà   s8   € ð ×ÑÒ'¯FÜ�N‰NÐlØŸ9™9 fô.à%Ÿ~˜~¨ˆÖr   c                ó&   <€ V ^8„  d   QhRS[ RS[/# )r   rÆ   r   )rA   r   )r   r   s   "€r   r   r   ë   s   ø€ ÷ ñ ©Eð ¹Dñ r   c           	   ƒ  óÎ  "  € V P                   pV'       g   R# V P                  f$   RV n         V P                  P                  4        R#  \        P
                  ! V P                  4       VR7      G Rj  x€L
  \        P#                  RT P                  T4       RT n         T P%                  4        R#  L>  \         d£   p\        T4      p\        P                  RT P                  T\        T4      P                  T4       RT n         T P                  RT 24       RT n        T P                  P!                  4        T P                  P                  4         Rp?R# Rp?ii ; i5i)zçVerify a suspect connection before reuse; recycle if dead. True when healthy (suspicion
cleared). On failure requests a reconnect, drops the stale session so the caller's
no-session path takes over, and returns False. Never raises.TNFrÅ   u|   MCP server '%s': suspect connection (%s) failed health check (%s: %s) â€” requesting reconnect (state: suspect â†’ degraded)zhealth check failed after uS   MCP server '%s': suspect connection passed health check (%s) â€” clearing suspicion)rÜ   rZ   Ú_reconnect_eventr°   r_   rÇ   rÎ   rd   r   re   r¸   rg   ÚtypeÚ__name__rÝ   Ú_readyÚclearru   rØ   )r   rÆ   r<   rÍ   r‘   s   &&   r   Úensure_healthyÚ#MCPServerHealthMixin.ensure_healthyë   s)  é € ð ×%Ñ%ˆßÙØ�<‰<ÒØ#'ˆDÔ Ø×!Ñ!×%Ñ%Ô'Ùð	Ü×"Ò" 4×#8Ñ#8Ó#:ÀGÔL×LÐLô 	�‰ÐiØ—I‘I˜vô	'à#ˆÔØ×!Ñ!Ô#Ùñ! MøÜô 
	Ü*¨3Ó/ˆDÜ�N‰Nð PàŸ9™9 f¬d°4«j×.AÑ.AÀ4ôIð $(ˆDÔ Ø×ÑÐ :¸6¸(ÐCÔDØˆDŒLØ�K‰K×ÑÔØ×!Ñ!×%Ñ%Ô'Ýûð
	üsC   ‚AE%Á)B5 Á4B3Á5B5 Á9:E%Â3B5 Â5E"Ã BEÅE%ÅE"Å"E%c                ó$   <€ V ^8„  d   QhRS[ RR/# rW   rX   )r   r   s   "€r   r   r   	  s   ø€ ÷ ñ ©3ð °4ñ r   c                ó  € V P                    Uu. uF  q"P                  4       '       d   K  VNK  	  ppV'       g   R# R;V n        V n        V P	                  V R\        V4       R24       V F  pVP                  4        K  	  R# u upi )a<  Cancel every in-flight RPC BEFORE the transport unwinds: the SDK does not always fail
pending requests when streams close, so a call would otherwise wait out the full tool
timeout. Cancelling anything flags ``_teardown_race`` so run() treats the next reconnect
as recovery rather than charging the rapid-drop budget.NTz tore down z in-flight call(s))Ú_inflight_tasksÚdoneÚ_reconnectingr×   rÝ   r…   Úcancel)r   r<   ÚtÚvictimsro   s   &&   r   Ú_fail_inflight_callsÚ)MCPServerHealthMixin._fail_inflight_calls	  sw   € ð
 #×2Ò2ÓCÑ2˜¿&¹&¿(—1�1Ñ2ˆÐCßÙØ37Ð7ˆÔ˜TÔ0Ø×Ñ˜V˜H K´°G³¨~Ð=OÐPÔQÛˆDØ�K‰KŽMó ùò Ds
   �B«Bc                ó    <€ V ^8„  d   QhRS[ /# r   r   )r   r   s   "€r   r   r     s   ø€ ÷ 
ñ 
¡dñ 
r   c                ó  a€ \        V RR4      pV'       d   V P                  4       '       d   R#  ^ RIo\        ;QJ d)    V3R lV 4       F  '       g   K   R'       * # 	  R'       * # ! V3R lV 4       4      '       * #   \         d     R# i ; i)u¢   True when every stdio child we spawned has exited. Best-effort: False (unknown â†’ don't
fail fast) for HTTP, no captured PIDs, missing psutil, or a failed probe.Ú_stdio_child_pidsNFc              3   óF   <"  € T F  pSP                  V4      x € K  	  R # 5ir.   )Ú
pid_exists)rE   ÚpidÚpsutils   & €r   rG   Ú<MCPServerHealthMixin._stdio_children_dead.<locals>.<genexpr>  s   øé € ÐB¹T°c˜6×,Ñ,¨S×1Ð1»Tùs   ƒ!T)r|   r   rø   Úanyrd   )r   Úpidsrø   s   & @r   Ú_stdio_children_deadÚ)MCPServerHealthMixin._stdio_children_dead  sp   ø€ ô �tÐ0°$Ó7ˆß�t—}‘}—’Ùð	Ûß“sÔB¹TÓB—s”sÔBÐB’sÔBÐB�sÔB¹TÓBÓBÔBÐBøÜô 	Úð	ús(   °A= ¿A= ÁA= ÁA= Á'A= Á=BÂBc                ó   <€ V ^8„  d   QhRR/# r$   r%   )r   r   s   "€r   r   r   "  s   ø€ ÷ &ñ &¨Tñ &r   c              ƒ  ó~   "  € V P                  4       '       g!   \        P                  ! R4      G Rj  x€L
  K6  R#  L5i)zwPoll child liveness during a stdio RPC; resolves when a tracked child dies so the caller cancels the RPC.

See #81995.
g      Ð?N)rü   r_   r•   r   s   &r   Ú_watch_stdio_childrenÚ*MCPServerHealthMixin._watch_stdio_children"  s0   é € ð
 ×+Ñ+×-Ò-ä—-’- Ó%×%Ò%ñ .á%ùs   ‚=™=²;³	=)r)   r/   rÔ   rÖ   rÊ   rÓ   rì   r    r±   rÒ   rÜ   r×   r´   rÕ   rZ   r%   r.   )g      @)rã   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú	__slots__r   r!   r*   r0   r=   rJ   rT   r\   rp   r�   rœ   r§   rc   rÎ   rØ   rÝ   ræ   rð   rü   r   Ú__static_attributes__Ú__classdictcell__)r   s   @r   r
   r
      sÏ   ø‡ € Ù`à€I÷%ð %÷Ið I÷3ð 3÷%ð %òa÷oò o÷
Rð R÷ð ÷

ð 
òò4÷4Oð Oò%I÷Nð ÷@Að A÷*	.ð 	.÷ò ÷<ð ÷
ð 
÷&ö &r   r
   )r  r_   r�   r~   r'   Útypingr   r   Útools.mcp_tool_errorsr   r   Útools.mcp_tool_schemar   Útools.mcp_tool_commonr   r«   r   r¤   Ú	getLoggerre   rÈ   r
   r%   r   r   Ú<module>r     sJ   ðñ5ó Û Û Û ß %ß UÝ 8Ý 'Ý 8à	×	Ò	Ð+Ó	,€àÐ ÷U&ó U&r   