+
    lHàj2´  ã                   óŒ  € R t ^ RI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 ^ RIHtHtHtHtHtHt ^ RIHt ^ RIHtHt ^ RIHt ^ R	IHtHtHtHt ^ R
I H!t" ^ RI#H$t$H%t%H&t&H't'H(t(H)t)H*t*H+t+ ^ RI,H-t-H.t.H/t/H0t0 ]Pb                  ! R4      t2]3! 4       t4]]n5        Rt6Rt7Rt8Rt9Rt:R R lt;RgR R llt<RR/R R llt=R R lt>R R lt?R R  lt@R! R" ltAR# R$ ltBR% R& ltCRhR( R) lltDR* R+ ltER, R- ltFR.R'/R/ R0 lltG ! R1 R2]H4      tIR3 R4 ltJRhR5 R6 lltK]R7R/R8 R9 ll4       tLRgR: R; lltMR< R= ltNR> R? ltOR@ tPRA RB ltQRgRC RD lltRRER'/RF RG lltSRgRH RI lltTRJ RK ltURL RM ltVRN RO ltWRP RQ ltXRR RS ltY]T! RTRURV ]V4      tZ]T! RWRXRY ]WRZR[7      t[]T! R\R]R^ ]X4      t\]T! R_R`Ra ]YRbR[7      t]Rc Rd lt^Re Rf lt_R# )izàRegistry-facing sync handlers for MCP tools and utility tools (resources/prompts), plus the per-call recovery
ladder: trust gating, circuit breaker, auth (401) refresh, session-expired reconnect and dead-stdio respawn retry.N)Úasynccontextmanager)Úpartial)ÚSimpleNamespace)ÚAnyÚCallableÚDictÚListÚOptionalÚTuple©Údeclaration)Úinvalidate_check_fn_cacheÚ
tool_error)Ústrip_unicode_tags)Ú_exc_strÚ_sanitize_errorÚ	mcp_fieldÚ_core)Úmcp_tool_loop)Ú_MCP_HARD_RESULT_CAP_CHARSÚ_cache_mcp_audio_blockÚ_cache_mcp_image_blockÚ_mcp_result_with_native_imagesÚ _render_mcp_dropped_block_noticeÚ_render_mcp_resource_blockÚ_strip_reserved_meta_keysÚ_truncate_mcp_text_result)Ú_auth_error_detailÚ_is_auth_errorÚ_is_session_expired_errorÚ_mcp_call_failed_messageztools.mcp_tooluÐ   MCP server '{s}' requires re-authentication.{detail} Run `hermes mcp login {s}` (or delete the tokens file under ~/.hermes/mcp-tokens/ and restart). Do NOT retry this tool â€” ask the user to re-authenticate.u  MCP server '{s}' stdio subprocess had exited (this is not a timeout â€” the call never reached the server). A respawn was requested but no fresh session came back within {t:.0f}s. Wait a few seconds before retrying; if it keeps failing the server is not starting and needs the user.uÎ   MCP server '{s}' respawned its stdio subprocess and it exited again immediately. The server is not starting cleanly â€” do NOT retry this tool; ask the user to check the server's command and its stderr log.zÂMCP server '{s}' lost its stdio subprocess after the tool call began. The operation may have completed, so Hermes did not replay it. Do NOT retry automatically; inspect the external state first.um  The MCP transport session to '{s}' expired while this write-capable call was in flight, so the outcome is UNKNOWN â€” the operation may or may not have taken effect server-side. It was NOT automatically retried to avoid a duplicate side effect. The connection has {state}. Verify whether the operation took effect (e.g. with a read-only tool) before re-invoking it.c                ó<   € V ^8„  d   QhR\         R\         R\        /# )é   Úserver_nameÚ	tool_nameÚreturn©ÚstrÚbool)Úformats   "Ú</home/ubuntu/.hermes/hermes-agent/tools/mcp_tool_handlers.pyÚ__annotate__r+   4   s&   € ÷ hñ h¤Cð h´Cð h¼Dñ hó    c                ó|   € ^ RI Hp \        P                  P	                  V! V 4      / 4      P	                  V4      RJ # )zïTrue only when discovery captured ``readOnlyHint=True`` for the tool. Missing or malformed
metadata fails safe to False (treated as write-capable). readOnlyHint is a property of the
connection's tools, so it lives under the connection key.©Ú_resolve_server_keyT)Útools.mcp_tool_scoper/   r   Ú_tool_read_only_hintsÚget)r#   r$   r/   s   && r*   Ú_tool_is_read_onlyr3   4   s8   € õ 9Ü×&Ñ&×*Ñ*Ñ+>¸{Ó+KÈRÓP×TÑTÐU^Ó_ÐcgÐgÐgr,   c          	      ót   € V ^8„  d   QhR\         R\         R\        \        ,          R\        \         ,          /# )r"   r#   r$   Úbookedr%   ©r'   r	   Úlist)r)   s   "r*   r+   r+   <   s9   € ÷ Rñ R¤3ð R´3ð RÄÌÅð RÔZbÔcfÕZgñ Rr,   c           
     ó|  € ^ RI Hp ^ RIHp V! V 4      p\        P
                  P                  V\        P                  4      pV\        P                  8H  ;'       d    \        W4      '       * pRpV\        P                  9   d   ^ RIHp	 VP                  WPW! 4       4      pVf   V'       d   \        WRV4      # R# V'       g5   VP                  4       ^ ,          '       d   Ve   VP!                  V4       R# VP#                  4       ;_uu_ 4        \        WW‚VR7      uuRRR4       #   + '       g   i     R# ; i)aZ  Approval gate for write-capable tools on ``trust: untrusted`` servers, plus the declared spend
limit on any server. None to proceed, else a ``tool_error``. Fail-closed: approval-system errors
block. An admitted costed call is charged to the chat's tally and appended to *booked* so the
caller can refund it when the call never reaches the server.)Ú_server_key)Úmcp_tool_costsN)Úget_current_session_key)Úgated)r0   r9   Útoolsr:   r   Ú_server_trust_levelsr2   Ú_TRUST_FULLÚ_TRUST_UNTRUSTEDr3   Ú_server_cost_policiesÚtools.approval_contextr;   Úpending_chargeÚ_ask_for_callÚreserve_within_limitÚappendÚasking)
r#   r$   r5   r9   Ú_costsÚkeyÚtrustr<   Úcharger;   s
   &&&       r*   Ú_trust_gate_checkrL   <   së   € õ
 1Ý.á
�kÓ
"€CÜ×&Ñ&×*Ñ*¨3´×0AÑ0AÓB€EØ”U×+Ñ+Ñ+×^Ð^Ô4FÀ{Ó4^Ô0^€EØ€FØ
Œe×)Ñ)Ô)ÝBØ×&Ñ& s¸ÐD[ÓD]Ó^ˆØ‚~ßFKŒ}˜[°T¸6ÓBÐUÐQUÐUß�V×0Ñ0Ó2°1×5Ô5ØÒØ�M‰M˜&Ô!ÙØ	�‰��Ü˜[°VÈ5ÔQ÷ 
��‹ús   ÄD*Ä*D;	r<   Tc                ó€   € V ^8„  d   QhR\         R\         R\        \        ,          R\        R\        \         ,          /# )r"   r#   r$   r5   r<   r%   )r'   r	   r7   r(   )r)   s   "r*   r+   r+   U   s@   € ÷ 2rñ 2rœsð 2r¬sð 2rÄHÌTÅNð 2rÜð2rÜ)1´#­ñ2rr,   c          	     ó  € RRreVe^   V'       d#   VP                  4       pVP                  V4      pM3VP                  4       w  ruV'       d   Ve   VP                  V4       R# RpVe   VP	                  V4      M. pV'       d?   RV RV  R2p	Rp
R	P                  V	.V'       d   R
.M. OVOV
N4      pRV  RV R2pRV  R2pM*R	P                  RV RV  R2.VO4      pRV  RV R2pRV  R2p ^ RIHp V! W¼RV  2VR7      pTR8X  d,   Te&   TP                  4        Te   TP                  T4       R# \        P                  RTR8X  d   RMR Y'       d   R!MR"T 4       T'       d   Te   \        TP                  T4      4      # \        R#T RT  R$24      #   \         da   p\        P                  RYTRR7       T'       d$   Te    \        TP                  T4      4      u Rp?# \        RT RT  R24      u Rp?# Rp?ii ; i)%zYAsk the user about one gated and/or costed call; book the charge only on an explicit yes.ç        FNTz
MCP tool 'z' on UNTRUSTED server 'z' wants to run.z[This tool is write-capable (no readOnlyHint=true annotation) and may modify external state.Ú z+This call goes past the chat's spend limit.zServer 'z4' is configured 'trust: untrusted'. Approve to run 'z' once, or deny to block it.úMCP server 'z' is askingz' on server 'z,' would take this chat past its spend limit.z3' declares a spend limit per chat. Approve to run 'zN' once (every further paid call in this chat asks again), or deny to block it.z' spend limit)Úrequest_elicitation_consentz
mcp-trust/)ÚsurfaceÚtitlez3MCP trust gate: approval check failed for %s.%s: %s)Úexc_infoz' on untrusted server 'zA' was blocked: the approval system was unavailable (fail-closed).Úacceptz.MCP trust gate: user %s '%s' on %s server '%s'ÚcancelÚ	cancelledÚdeniedÚ	untrustedzspend-limitedz9The user did not approve running write-capable MCP tool 'zI'. The command was NOT run. Do not retry without explicit user direction.)ÚspentÚ
over_limitrE   rF   ÚlinesÚjoinÚtools.approval_promptrR   Ú	ExceptionÚloggerÚerrorr   ÚrefusalÚbookÚinfo)r#   r$   rK   r5   r<   r[   ÚoverÚreservedÚextraÚheadÚtailÚmessageÚdescriptionrT   rR   ÚanswerÚexcs   &&&&$            r*   rD   rD   U   ss  € ð �uˆ4ØÒßØ—L‘L“NˆEØ×$Ñ$ UÓ+‰Dà$×9Ñ9Ó;‰OˆHßØÒ%Ø—M‘M &Ô)ÙØˆDØ#)Ò#5ˆF�L‰L˜Ô¸2€EßØ˜I˜;Ð&=¸k¸]È/ÐZˆØlˆà—(‘(˜DÐs×W[Ð%RÑ$SÐacÐsÐglÐsÐnrÐsÓtˆØ! + ð /*Ø*3¨Ð4PðRˆà˜{˜m¨;Ð7‰à—(‘(˜j¨¨°=ÀÀð N+ð ,ð 5Ø.3ð5ó 6ˆà! + Ð.aÐbkÐalð mfð gˆà˜{˜m¨=Ð9ˆðDÝEÙ,¨WÈZÐXcÐWdÐKeÐmrÔsˆð �ÔØÒØ�K‰KŒMØÒ!Ø—‘˜fÔ%ÙÜ
‡K�KÐ@ÐQWÐ[cÔQcÁ+ÐiqØ®%™;°_ÀkôSç�Ò"Ü˜&Ÿ.™.¨Ó/Ó0Ð0ÜÐQÐR[ÐQ\ð ]Ø%˜Ð&oðqó rð røô! ô DÜ�‰ÐJÈKÐdgÐrvˆÔwß�FÒ&Ü˜fŸn™n¨UÓ3Ó4Õ4Ü˜J y kÐ1HÈÈð VBð Có Dõ 	Dûð	Dús*   Ã-F ÆHÆ!>G<ÇHÇ%G<Ç6HÇ<Hc                óF   € V ^8„  d   QhR\         R\        \         ,          /# ©r"   r#   r%   ©r'   r	   )r)   s   "r*   r+   r+   Š   s"   € ÷ pñ p¬ð p´¼µñ pr,   c           	     ó  € ^ RI Hp V! V 4      p\        P                  P	                  V^ 4      p\
        P                  ! 4       \        P                  P	                  VR4      ,
          pV\        P                  8  g   V\        P                  8¼  d   R# \        ^\        \        P                  V,
          4      4      p\        P                  P	                  V4      '       d   \        RV  RV RV R24      # \        RV  RV R	V R
24      # )z±Open-breaker error, or None when calls may proceed. After the cooldown the breaker is
half-open: the next call probes; success resets, failure re-bumps and re-arms the cooldown.r.   rO   NrQ   z' rejected the last zO calls (it is reachable; see the error text those calls returned). Paused for ~u\   s. Do NOT repeat the same call â€” fix the arguments/URL/target or use a different approach.z' is unreachable after z0 consecutive failures. Auto-retry available in ~ue   s. Do NOT retry this tool yet â€” use alternative approaches or ask the user to check the MCP server.)r0   r/   r   Ú_server_error_countsr2   ÚtimeÚ	monotonicÚ_server_breaker_opened_atÚ_CIRCUIT_BREAKER_THRESHOLDÚ_CIRCUIT_BREAKER_COOLDOWN_SECÚmaxÚintÚ_server_errors_all_applicationr   )r#   r/   rI   ÚfailuresÚageÚretry_ins   &     r*   Ú_check_circuit_breakerr   Š   s
  € õ 9Ù
˜kÓ
*€CÜ×)Ñ)×-Ñ-¨c°1Ó5€HÜ
�.Š.Ó
œU×<Ñ<×@Ñ@ÀÀcÓJÕ
J€CØ”%×2Ñ2Ô2°c¼U×=`Ñ=`Ô6`ÙÜ�1”cœ%×=Ñ=ÀÕCÓDÓE€HÜ×+Ñ+×/Ñ/°×4Ò4ô ˜L¨¨Ð5IÈ(Èð TKØKSÈ*ð UVðWó Xð 	Xô ˜ [ MÐ1HÈÈ
ð S2Ø2:°ð <nðoó pð pr,   c                ó0   € V ^8„  d   QhR\         R\        /# ©r"   r#   Útool_timeout©r'   Úfloat)r)   s   "r*   r+   r+   Ÿ   s   € ÷ ñ ¤cð ¼ñ r,   c                óœ  € ^ RI Hp \        RV  R24      p^ RIHp V! V 4      pVem   Vw  rgp\        VV VP
                  RVP                  RVP                  P                  RVP                  P                  /VP                  VP                  R	7      pVP                  V 4      p	\        R
\        T;'       g    R
4      4      p
V	'       d4   V	P                  '       g   \         P"                  ! WšR7      '       d   V	R3# \$        P&                  ! V 4       V	'       d.   \         P(                  ! V	4      '       d   R\        RV  R24      3# RV3# )a  ``(server, None)`` when a call may be dispatched, else ``(None, error)``. No session: a
reconnect may be completing, so wait briefly before a breaker strike; still down -> ask the
server task to rebuild (probing a dead transport would re-arm the breaker forever).©Úmcp_tool_discoveryrQ   ú' is not connected)Úunavailable_detailsNÚnameÚversionÚpath)ÚserverÚstateÚappÚuser_actionÚretryg      @©Útimeoutut   ' transport is down; reconnect requested. Do NOT retry this tool immediately â€” give it a few seconds to come back.)r=   r‡   r   Útools.mcp_livenessr‰   rŽ   rŠ   Úavailabilityr‹   rŒ   r�   r‘   Ú_get_connected_server_for_callÚminr„   ÚsessionÚ_loopÚ_wait_for_server_session_readyr   Ú_bump_server_errorÚ_signal_reconnect)r#   r‚   Ú
_discoveryÚnot_connectedr‰   ÚdetailsÚdeclÚcurrentÚsentencer�   Úwaits   &&         r*   Ú_acquire_call_serverr¤   Ÿ   s6  € õ 7Ü ¨k¨]Ð:LÐMÓN€MÝ6Ù! +Ó.€GØÒØ")Ñˆ�xÜ"ØØØ—-‘-à˜Ÿ	™	Ø˜7×/Ñ/×7Ñ7Ø˜×,Ñ,×1Ñ1ðð
  ×+Ñ+Ø—-‘-ô
ˆð ×6Ñ6°{ÓC€FÜˆs”E˜,×-Ð-¨#Ó.Ó/€Dß�6—>—>�>¤U×%IÒ%IÈ&×%_Ó%_Ø�tˆ|ÐÜ	×Ò˜[Ô)ß”%×)Ò)¨&×1Ò1Ø”Z ,¨{¨mð <[ð !\ó ]ð ]ð 	]à�ÐÐr,   c                ó$   € V ^8„  d   QhR\         /# ©r"   r%   ©r(   )r)   s   "r*   r+   r+   À   s   € ÷ ñ ¤ñ r,   c                óz   €  R\         P                  ! V 4      9   #   \         P                  \        3 d     R# i ; i)zLTrue only for a JSON payload carrying an ``error`` key (non-JSON = success).rb   F)ÚjsonÚloadsÚJSONDecodeErrorÚ	TypeError)Úresults   &r*   Ú_result_is_errorr®   À   s8   € ðØœ$Ÿ*š* VÓ,Ñ,Ð,øÜ× Ñ ¤)Ð,ô Úðús   ‚ ›:¹:c                ó0   € V ^8„  d   QhR\         R\        /# rp   )r'   r   )r)   s   "r*   r+   r+   È   s   € ÷ ñ ¤cð ´cñ r,   c                óˆ   € \        V4      '       d   \        P                  ! V RR7       V# \        P                  ! V 4       V# )z©Breaker bookkeeping: an error payload from the tool itself still counts as a strike (#10447),
flagged as an application error so the open-breaker message stays truthful.T)Úapplication)r®   r   r›   Ú_reset_server_error)r#   r­   s   &&r*   Ú_record_call_outcomer³   È   s;   € ô ˜×ÒÜ× Ò  ¸$Õ?ð €Mô 	×!Ò! +Ô.Ø€Mr,   c                ó<   € V ^8„  d   QhR\         R\         R\         /# )r"   r#   rk   r%   ©r'   )r)   s   "r*   r+   r+   Ò   s!   € ÷ (ñ (œð (¤sð (¼ñ (r,   c                óF   € \         P                  ! V 4       \        V3/ VB # )z:Breaker strike + the ``tool_error`` payload for *message*.)r   r›   r   )r#   rk   rh   s   &&,r*   Ú_striker·   Ò   s    € ä	×Ò˜[Ô)Ü�gÑ' Ñ'Ð'r,   c                ó$   € V ^8„  d   QhR\         /# r¦   r§   )r)   s   "r*   r+   r+   Ø   s   € ÷ Hñ Hœ4ñ Hr,   c                  ór   € \         P                  R J;'       d    \         P                  P                  4       # ©N)r   Ú	_mcp_loopÚ
is_running© r,   r*   Ú_mcp_loop_runningr¾   Ø   s&   € Ü�?‰? $Ð&×GÐG¬5¯?©?×+EÑ+EÓ+GÐGr,   Fc                ó0   € V ^8„  d   QhR\         R\        /# )r"   r#   Úrequire_loopr&   )r)   s   "r*   r+   r+   Ü   s   € ÷ ñ ¬cð Äñ r,   c                óJ  € ^ RI Hp \        P                  ;_uu_ 4        \        P                  P                  V! V 4      4      pRRR4       XRJ;'       d.    \        VR4      ;'       d    \        4       ;'       g    V'       * pV'       d   V# R#   + '       g   i     LU; i)z¢The registered server object when it can be signalled to reconnect, else None.
With *require_loop*, also None unless the MCP loop is running (nothing to wait on).r.   NÚ_reconnect_event)r0   r/   r   Ú_lockÚ_serversr2   Úhasattrr¾   )r#   rÀ   r/   ÚsrvÚoks   &&   r*   Ú_lookup_reconnectable_serverrÈ   Ü   su   € õ 9Ü	��‹Ü�n‰n× Ñ Ñ!4°[Ó!AÓBˆ÷ 
à	�Dˆ×	kÐ	kœW SÐ*<Ó=×	kÐ	kÔCTÓCV×CjÐCjÐ^jÔZj€Bßˆ3Ð˜$Ð÷ 
�ús   Ÿ&BÂB"	c                ó<   € V ^8„  d   QhR\         R\         R\         /# )r"   r#   Úop_descriptionÚwhatrµ   )r)   s   "r*   r+   r+   æ   s!   € ÷ 	5ñ 	5œSð 	5¼cð 	5Ìñ 	5r,   c                óˆ   €  V! 4       p\        Y4      #   \          d#   p\        P                  RYY54        Rp?R# Rp?ii ; i)zèRe-run ``retry_call`` after a recovery step. Returns the result when the RPC completed
(an application error is still the tool's real answer, and still a breaker strike per #10447);
None when the retry raised (caller falls through).z#MCP %s/%s retry after %s failed: %sN)r`   ra   Úwarningr³   )r#   Ú
retry_callrÊ   rË   r­   Ú	retry_excs   &&&&  r*   Ú_retry_oncerÐ   æ   sB   € ðÙ“ˆô   Ó4Ð4øô ô Ü�‰Ð<¸kÐ[_ÔkÝûðús   ‚ ”AŸ<¼Ac                ó<   € V ^8„  d   QhR\         R\        R\         /# ©r"   r#   rn   rÊ   )r'   ÚBaseException)r)   s   "r*   r+   r+   ò   s"   € ÷ :ñ :¬cð :¼ð :Ôcfñ :r,   c           	     óô  a a€ \        V4      '       g   R# ^ RIHo  \        P                  ! VV 3R l^
R7      pV'       d[   \        S 4      pVe9   \        P                  ! S Wc R2^R7      '       d   \        P                  ! S 4       \        S W#R	4      pVe   V# \        S \        P                  S \!        V4      R
7      RS R7      #   \
         d$   p\        P                  RS T4       Rp Rp?L¸Rp?ii ; i)a  OAuth recovery + one retry; None when *exc* is not an auth error. ``handle_401`` decides
viability; if viable, signal a reconnect (fresh credentials), wait ready, retry once. Any
failure returns the structured ``needs_reauth`` error so the model stops refreshing.N)Úget_managerc                  ó2   <€ S ! 4       P                  SR 4      # rº   )Ú
handle_401)rÕ   r#   s   €€r*   Ú<lambda>Ú._handle_auth_error_and_retry.<locals>.<lambda>ú   s   ø€ ±;³=×3KÑ3KÈKÐY]Ô3^r,   r’   z+MCP OAuth '%s': recovery attempt failed: %sFz after OAuth recovery©rÊ   r“   zauth recovery)ÚsÚdetailT)Úneeds_reauthr�   )r   Útools.mcp_oauth_managerrÕ   r™   Ú_run_on_mcp_loopr`   ra   rÍ   rÈ   Ú_signal_reconnect_and_waitr   r²   rÐ   r·   Ú_NEEDS_REAUTH_MSGr)   r   )	r#   rn   rÎ   rÊ   Ú	recoveredÚrec_excrÆ   r­   rÕ   s	   f&&&    @r*   Ú_handle_auth_error_and_retryrä   ò   sè   ù€ ô ˜#×ÒÙÝ3ðÜ×*Ò*Õ+^ÐhjÔkˆ	÷ Ü*¨;Ó7ˆð Š?œu×?Ò?Ø˜SÐ3CÐCXÐ1YÐce÷ gó  gä×%Ò% kÔ2Ü˜[¨*ÀoÓVˆØÒØˆMÜ�;Ô 1× 8Ñ 8¸;ÔOaÐbeÓOfÐ 8Ó gØ $¨[ô:ð :øô ô Ü�‰ÐDÀkÐSZÔ[Ø�	ûðús   �C	 Ã	C7ÃC2Ã2C7Úcall_may_have_side_effectsc                óH   € V ^8„  d   QhR\         R\        R\         R\        /# )r"   r#   rn   rÊ   rå   )r'   rÓ   r(   )r)   s   "r*   r+   r+     s0   € ÷ +Uñ +U´3ð +U¼]ð +UÔhkð +UÜEIñ+Ur,   c               óh  € \        V4      '       g   R# \        V RR7      pV'       d«   VRJ;'       d    \        P                  ! WV R2^R7      pV'       d   \        P
                  ! V 4       M\        P                  ! V 4       \        P                  RYV'       d   RMR4       \        \        P                  Y'       d   R	MR
R7      RV R7      # Vf   R# \        P                  RWV4       \        P                  ! WV^R7      '       g   \        P                  RV 4       R# \        WVR4      # )u"  Transport reconnect + one retry on session expiry; None to fall through. Skips
``handle_401``: the token is valid, only the server-side session is stale.

Unlike :func:`_handle_auth_error_and_retry`, this does **not** call the OAuth manager's ``handle_401`` â€”
the access token is still valid, only the server-side session state is stale. Setting
``_reconnect_event`` causes the server task's lifecycle loop to tear down the current
``streamablehttp_client`` + ``ClientSession`` and rebuild them, reusing the existing OAuth provider
instance. See #13383.

At-most-once for writes: a session-expired shape can be synthesized by a proxy AFTER the upstream
executed the request, and the transport errors this classifier also matches (``ClosedResourceError``,
broken pipe) routinely fire mid-response. With ``call_may_have_side_effects`` the transport is still
healed but the call is never re-run; the model gets an ``outcome_uncertain`` error instead (same
contract as the mid-call stdio death path). Callers pass True unless the tool is positively read-only.
NT)rÀ   z (write, no auto-retry)rÚ   z¤MCP server '%s': %s failed with a session-expired/transport error after the request may have been dispatched; NOT auto-retrying a write-capable tool (reconnect %s).Ú	succeededÚfailedzbeen re-establishedznot recovered yet)rÛ   rŽ   )Úoutcome_uncertainr�   zmMCP server '%s': %s failed with session-expired error (%s); signalling transport reconnect and retrying once.zsMCP server '%s': reconnect did not ready within 15s after session-expired error; falling through to error response.zsession reconnect)r   rÈ   r™   rà   r   r²   r›   ra   rÍ   r   Ú_SESSION_OUTCOME_UNCERTAIN_MSGr)   re   rÐ   )r#   rn   rÎ   rÊ   rå   rÆ   Úreconnecteds   &&&&$  r*   Ú!_handle_session_expired_and_retryrí     s&  € ô" % S×)Ò)ÙÜ
& {ÀÔ
F€Cß!ð  �o÷ eð e¬%×*JÒ*JØ°Ð/?Ð?VÐ-WÐacô+eˆçÜ×%Ò% kÕ2ä×$Ò$ [Ô1Ü�‰ð fà"Ç;±KÐT\ô	^ô Ô8×?Ñ?Ø¾+Ñ!6ÐK^ð @ó `à"¨;ô8ð 	8ð ‚{ÙÜ
‡K�Kð %Ø&1À3ôHä×+Ò+¨KÈ^Ðeg×hÓhÜ�‰ð <Ø=Hô	JáÜ�{°Ð@SÓTÐTr,   c                   óB   a a€ ] tR tRt oRtV3R lV 3R lltRtVtV ;t# )Ú_StdioChildExitedi:  zRStdio subprocess gone when (or while) a call ran. Deliberately NOT a TimeoutError.c                ó&   <€ V ^8„  d   QhRS[ RS[/# )r"   rk   Ú	in_flightr&   )r)   Ú__classdict__s   "€r*   r+   Ú_StdioChildExited.__annotate__=  s   ø€ ÷ #ñ #¡ð #±4ñ #r,   c               ó2   <€ \         SV `  V4       W n        R # rº   )ÚsuperÚ__init__rñ   )Úselfrk   rñ   Ú	__class__s   &&$€r*   rö   Ú_StdioChildExited.__init__=  s   ø€ Ü‰Ñ˜Ô!Ø"Žr,   ©rñ   )	Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__rö   Ú__static_attributes__Ú__classdictcell__Ú__classcell__)rø   rò   s   @@r*   rï   rï   :  s   ù‡ € Ù\÷#÷ #ó #r,   rï   c                ó<   € V ^8„  d   QhR\         R\        R\         /# rÒ   )r'   r`   )r)   s   "r*   r+   r+   B  s'   € ÷ 4Cñ 4C´cð 4CÄ	ð 4CÔgjñ 4Cr,   c                ó  € \        V\        4      '       g   R# Rp\        V 4      pVe|   VP                  '       d   RMRp\        P                  RWW4       \        4       '       d)   \        P                  ! WV\        P                  R7      pM\        P                  ! V4       VP                  '       d#   \        V \        P                  V R7      RR	7      # V'       g0   \        V \        P                  V \        P                  R
7      4      #  \!        W! 4       4      #   \         d{   p\        P#                  RYT4       TP                  '       d(   \        T \        P                  T R7      RR	7      u Rp?# \        T \$        P                  T R7      4      u Rp?# Rp?i\&         d\   p\        P#                  RYT4       \        T \)        RT  R\+        T4      P,                   R\/        T4       24      4      u Rp?# Rp?ii ; i)aH  Respawn a dead stdio child; retry once only when it was dead before dispatch.

A mid-call exit is ambiguous: the server may have applied a side effect before its
response pipe disappeared. Reconnect for future calls but never replay that operation.
None means this is not our error. This function never spawns itself: it sets
``_reconnect_event`` and waits, so spawn frequency stays governed by ``run()``'s rapid-drop
budget. A pre-dispatch retry whose child dies again reports and stops.

Why retrying here cannot hot-cycle respawns: this function never spawns anything. It sets
``_reconnect_event`` (one signal, same as before) and waits for the server task to publish a fresh
session. Spawn frequency stays governed entirely by ``run()``'s rapid-drop budget, which parks a
transport that keeps dropping without proving healthy (#62212).
NFzreconnecting without replayzrespawning and retrying oncez=MCP server '%s': %s found the stdio subprocess dead (%s); %s.rÚ   )rÛ   T)rê   )rÛ   ÚtzaMCP server '%s': %s stdio subprocess exited again right after respawn (%s); not retrying further.z.MCP %s/%s retry after stdio respawn failed: %sz;MCP call failed after respawning the stdio subprocess for 'z': z: )Ú
isinstancerï   rÈ   rñ   ra   re   r¾   r™   rà   r   Ú_STDIO_RESPAWN_WAIT_SECrœ   r·   Ú_STDIO_OUTCOME_UNCERTAIN_MSGr)   Ú_STDIO_NO_RESPAWN_MSGr³   rÍ   Ú_STDIO_DIED_AGAIN_MSGr`   r   Útyperû   r   )r#   rn   rÎ   rÊ   rì   rÆ   ÚactionrÏ   s   &&&&    r*   Ú$_handle_stdio_child_exited_and_retryr  B  sÉ  € ô �cÔ,×-Ò-ÙØ€KÜ
& {Ó
3€CØ
‚Ø25·-·-°-Ñ.ÐEcˆÜ�‰ÐSØ°ô	>ä×ÒÜ×:Ò:Ø°Ì×IfÑIfôh‰Kô ×#Ò# CÔ(Ø
‡}‡}€}ÜØÜ(×/Ñ/°+Ð/Ó>Ø"ô
ð 	
÷
 Ü�{Ô$9×$@Ñ$@À;ÔRW×RoÑRoÐ$@Ó$pÓqÐqðCÜ# K°³Ó>Ð>øÜô 
Qä�‰ð "Ø#.À	ô	Kà××ÐÜØÜ,×3Ñ3°kÐ3ÓBØ"&ôõ ô
 �{Ô$9×$@Ñ$@À;Ð$@Ó$OÓPÕPûÜô CÜ�‰ÐGÈÐfoÔpÜ�{¤OØIÈ+ÈÐVYÜ�I‹×'Ñ'Ð(¨¬8°IÓ+>Ð*?ðAó%Bó Cõ 	CûðCúsD   ÄD! Ä!H
Ä,A
F!Å6H
Å<F!ÆH
Æ!H
Æ.H
Æ/AHÇ?H
ÈH
c                óˆ   € V ^8„  d   QhR\         R\        R\         R\        R\        \        .R3,          R\
        R\         /# )	r"   r#   r�   Úopr‚   Úon_final_failureNÚrecord_outcomer%   )r'   r   r„   r   rÓ   r(   )r)   s   "r*   r+   r+   y  sL   € ÷ 9ñ 9œ3ð 9¬ð 9´ð 9Ì%ð 9Ü (¬-¨¸$Ð)>Õ ?ð9ÜQUð9Übeñ9r,   c                óz  aa€ \        \        VRR4      4      '       d   VP                  4        VV3R lp V! 4       p	V'       d   \        W	4      # T	#   \         d    \        R4      u # \         dF   p
T F  pT! Y
Y‚4      pTf   K  Tu u Rp
?
# 	  T! T
4       \        \        T
4      4      u Rp
?
# Rp
?
ii ; i)a¥  Mark the call started on *server* (doubles may lack ``mark_tool_call``), run coroutine function *call*
on the MCP loop and, on failure, walk ``recoverers`` (``(server_name, exc, retry_call, op) -> Optional[str]``,
None = not its kind; order matters). Unrecovered exceptions go through ``on_final_failure`` and become the
generic call-failed error. ``record_outcome`` applies breaker bookkeeping to the FIRST attempt only.Úmark_tool_callNc                  ó4   <€ \         P                  ! S SR 7      # )r’   )r™   rß   )Úcallr‚   s   €€r*   Ú	call_onceÚ_dispatch.<locals>.call_once‚  s   ø€ Ü×%Ò% d°LÔAÐAr,   z-MCP call interrupted: user sent a new message)ÚcallableÚgetattrr  r³   ÚInterruptedErrorr   r`   r    )r#   r�   r  r  r‚   Ú
recoverersr  r  r  r­   rn   Úrecoverrâ   s   &&&ff&&&     r*   Ú	_dispatchr  y  s®   ù€ ô ”˜Ð 0°$Ó7×8Ò8Ø×ÑÔöBð9Ù“ˆß<JÔ# KÓ8ÐVÐPVÐVøÜô KÜÐIÓJÒJÜô 9Û!ˆGÙ °)Ó@ˆIØÔ$Ø × ñ "ñ 	˜ÔÜÔ2°3Ó7Ó8Õ8ûð9úsG   ·A Á
A ÁA ÁB:Á+B:Á4B:Á5B5Â	B5ÂB:ÂB5Â/B:Â5B:Ú
retry_safec                óH   € V ^8„  d   QhR\         R\        R\        R\        /# )r"   r�   r#   r  r  )r   r'   r(   )r)   s   "r*   r+   r+   ”  s)   € ÷ #ñ #¤cð #¼ð #Äð #ÔUYñ #r,   c          	    óÀ  "  € \        V RR4      \        P                  ! 4       rTVRJ;'       d    VRJpV'       d   VP                  V4        R5x €  T'       d   TP                  T4       R# R#   \        P                   d7    \        T RR4      '       d"   T'       d   RMRp\        RT RT R	T 24      Rhh i ; i  T'       d   TP                  T4       i i ; i5i)
aÚ  Register the running RPC so teardown can fail it fast. A deliberate teardown
(``_reconnecting`` set first) turns the cancel into a retryable RuntimeError; external
cancels propagate unchanged. Doubles without ``_inflight_tasks`` skip tracking.

Every user-visible request family wraps its RPC in this context (#48069 salvage). If a deliberate
reconnect/shutdown teardown cancels the task (``_fail_inflight_calls`` sets ``_reconnecting`` first),
the cancel is converted into a clean retryable RuntimeError instead of a raw CancelledError; external
cancels (caller timeout, user interrupt) propagate unchanged. ``retry_safe=False`` (a write-capable
``tools/call``) words the error as outcome-uncertain instead of inviting a replay.
Ú_inflight_tasksNÚ_reconnectingFz(retry the request on the rebuilt sessionzUthe request may already have been dispatched, so verify its effect before re-invokingzMCP z on 'z'' was aborted by a reconnect teardown; )r  ÚasyncioÚcurrent_taskÚaddÚCancelledErrorÚRuntimeErrorÚdiscard)r�   r#   r  r  ÚinflightÚtaskÚtrackedÚadvices   &&&$    r*   Ú_track_inflight_rpcr-  “  sÚ   é € ô ˜VÐ%6¸Ó=¼w×?SÒ?SÓ?UˆdØ˜$Ð×7Ð7 8°4Ð#7€GßØ�‰�TÔð
#Ý÷ Ø×Ñ˜TÖ"ñ øô ×!Ñ!ô Ü�6˜?¨E×2Ò2ßDNÑ@Ømð ä  b T¨¨{¨mÐ;bÐciÐbjÐkÓlÐrvÐvØðû÷ Ø×Ñ˜TÕ"ð üs:   ‚9C¼CÁA1 ÁCÁCÁ1/B<Â!B<Â<B? Â?CÃCc                ó<   € V ^8„  d   QhR\         R\         R\        /# )r"   r#   r$   Úargs©r'   Údict)r)   s   "r*   r+   r+   °  s'   € ÷ 3Kñ 3K¼Sð 3KÌSð 3KÔX\ñ 3Kr,   c              ƒ  ó6  "  € \        V RR4      p\        V4      '       d   V! 4       RJ d   \        RV R2RR7      hVe   RV/M/ pV P                  P                  ! V3R	V/VB p\        V R
R4      p\
        P                  ! V4      '       d   \        P                  ! V4      '       g)   \        P                  ! V4      '       d   VG Rj  x€L
 # T# \        P                  ! V4      p	\        P                  ! V! 4       4      p
 \        P                  ! Wš0\        P                  R7      G Rj  x€L
 w  r¼W«9   d8   V	P                  4       '       g"   V	P                  4        \        RV R2RR7      h V	G Rj  x€L
 V
P                  4        V	P                  4       '       g   V	P                  4        \        P                  ! WšRR7      G Rj  x€L
  #  EL L§ L_ L  \         dS   p\        T RR4      p\        T4      '       d/   T! 4       RJ d$   \!        T4      '       d   \        RT R2RR7      Thh Rp?ii ; i  T
P                  4        T	P                  4       '       g   T	P                  4        \        P                  ! YšRR7      G Rj  x€L 
  i ; i5i)a‰  ``session.call_tool`` that fails fast when the stdio child is/gets dead: pre-call (a dead
child must not hold the slot for the full timeout) and mid-call (race against
``_watch_stdio_children``). Both raise :class:`_StdioChildExited` for the respawn path, which
owns the reconnect signal; only pre-call failure is safe to replay. callable()/``is True``
because MagicMock attributes are truthy.Ú_stdio_children_deadNTzMCP stdio subprocess for 'z1' had already exited when the call was dispatchedFrú   Úprogress_callbackÚ	argumentsÚ_watch_stdio_children)Úreturn_whenz' exited mid-call)Úreturn_exceptionsÚ_is_httpz' closed its transport mid-call)r  r  rï   r˜   Ú	call_toolÚinspectÚiscoroutinefunctionr#  ÚiscoroutineÚensure_futurer£   ÚFIRST_COMPLETEDÚdonerW   Úgatherr`   r   )r�   r#   r$   r/  r4  Ú_stdio_deadrh   Ú
_call_coroÚ_watch_childrenÚrpc_taskÚ
watch_taskr@  Ú_pendingrn   r9  s   &&&&&          r*   Ú_call_tool_racing_stdio_deathrH  °  sC  é € ô ˜&Ð"8¸$Ó?€KÜ�×Ò¡£°$Ó!6ÜØ(¨¨Ð5fÐgØô
ð 	
ð 9JÒ8UÐ Ð"3Ñ4Ð[]€EØ—‘×)Ò)¨)ÑM¸tÐMÀuÑM€JÜ˜fÐ&=¸tÓD€OÜ×'Ò'¨×8Ò8¼W×=PÒ=PÐQ[×=\Ò=\ä#*×#6Ò#6°z×#BÒ#B�Z×ÐRÈ
ÐRô ×$Ò$ ZÓ0€HÜ×&Ò&¡Ó'8Ó9€JðKÜ&Ÿ|š|¨XÐ,BÔPW×PgÑPgÔh×h‰ˆØÔ h§m¡m§o¢oØ�O‰OÔÜ#Ø,¨[¨MÐ9JÐKØôð ð	Ø!—>ð 	×ÑÔØ�}‰}�ŠØ�O‰OÔÜ�nŠn˜XÀTÔJ×JÑJò=  ñ iñ "ñ  	Køô ô 
	ô ˜v z°4Ó8ˆHÜ˜×!Ò!¡h£j°EÓ&9Ô>WÐX[×>\Ò>\Ü'Ø0°°Ð=\Ð]Ø"ôð ðð ûð
	ûð 	×ÑÔØ�}‰}�ŠØ�O‰OÔÜ�nŠn˜XÀTÔJ×JÒJüsŸ   ‚B(JÂ+JÃJÃGÃ7JÄ*H= Ä/GÄ0!H= Å!H= Å4G Å9GÅ:G Å=AJÇGÇJÇH= ÇG ÇJÇH:Ç(AH5È5H:È:H= È=AJÊJÊJÊJc                ó$   € V ^8„  d   QhR\         /# r¦   rµ   )r)   s   "r*   r+   r+   è  s   € ÷ /ñ /¤#ñ /r,   c                ól   € R V P                   ;'       g    .  4       pRP                  R V 4       4      # )zzConcatenated text of an ``isError`` result's blocks (EmbeddedResource error payloads
carry text under ``.resource.text``).c              3   ó|   "  € T F2  p\        VR R4      ;'       g    \        \        VRR4      R R4      x € K4  	  R# 5i)ÚtextNÚresource)r  )Ú.0Úbs   & r*   Ú	<genexpr>Ú%_error_result_text.<locals>.<genexpr>ë  s:   é € Ð}Ñg{ÐabŒW�Q˜ Ó%×\Ð\¬´¸¸JÈÓ1MÈvÐW[Ó)\Ô\Óg{ùs   ‚<›!<Ú c              3   óJ   "  € T F  q'       g   K  \        V4      x € K  	  R # 5irº   rµ   )rN  r  s   & r*   rP  rQ  ì  s   é € Ð.¡5˜a«A”6”3�q—6�6£5ùs   ‚	#�#)Úcontentr^   )r­   Útextss   & r*   Ú_error_result_textrV  è  s7   € ñ ~Ðgm×guÑgu×g{Ðg{Ðy{Ðg{Ó}€EØ�7‰7Ñ.¡5Ó.Ó.Ð.r,   c                ór   € V ^8„  d   QhR\         R\        \         \        \        \         ,          3,          /# rp   )r'   Útuplerz   r7   )r)   s   "r*   r+   r+   ï  s.   € ÷ 'Rñ 'R´ð 'R¼¼cÄ3ÌÌSÍ	Ð>QÕ8Rñ 'Rr,   c                óR  € . p^ p. pV P                   ;'       g    .  EFk  p\        VRR4      '       dP   VP                  \        VP                  4      4       VP                  P                  4       '       d
   V^,          pKf  \        V4      pVP                  R4      '       d   VP                  V\        R4      R 4       T;'       g    \        V4      ;'       g    \        WQ4      pV'       d   VP                  V4       V^,          pKñ  \        VRR4      ;'       g    \        V4      P                  pVR9   d   \        P                  RW4       EK;  \        P                  RW4       VP                  \!        WX4      4       EKn  	  \#        RP%                  V4      4      W43# )	u%  Text passes through; image/audio blocks are cached (MEDIA: tags); resource blocks are
materialized rather than silently dropped; unsupported blocks become an inline drop notice
(kimi-code#3227). Returns ``(text, usable_parts, image_paths)``: ``usable_parts`` counts REAL
rendered blocks (whitespace-only text and drop notices excluded) for the structuredContent
arbitration; ``image_paths`` are the files THIS call's image blocks were cached to â€” never
parsed back out of the text, where a server-written ``MEDIA:`` line could name any local file.rL  NzMEDIA:r  z,MCP %s: content block type %r rendered emptyz2MCP %s: dropping unsupported content block type %rÚ
>   rL  ÚaudioÚimagerM  )rT  r  rF   r   rL  Ústripr   Ú
startswithÚlenr   r   r  rû   ra   ÚdebugrÍ   r   r   r^   )	r­   r#   ÚpartsÚusable_partsÚimage_pathsÚblockr\  ÚrenderedÚ
block_types	   &&       r*   Ú_render_content_blocksrg  ï  s\  € ð €EØ€LØ€Kð —.‘.×&Ð& BÓ&ˆÜ�5˜& $×'Ò'Ø�L‰LÔ+¨E¯J©JÓ7Ô8Ø�z‰z×Ñ×!Ò!Ø Õ!�ÙÜ& uÓ-ˆØ×Ñ˜H×%Ò%Ø×Ñ˜u¤S¨£] ^Ð4Ô5Ø×kÐkÔ2°5Ó9×kÐkÔ=WÐX]Ó=kˆßØ�L‰L˜Ô"Ø˜AÕˆLÙÜ˜U F¨DÓ1×IÐI´T¸%³[×5IÑ5Iˆ
ØÐ?Ô?Ü�L‰LÐGÈ×aä�N‰NÐOÐQ\Ôið �L‰LÔ9¸%ÓL×Mñ+ 'ô. % T§Y¡Y¨uÓ%5Ó6¸ÐQÐQr,   c                óØ   € \        V RR4      p Ve   \        P                  ! VR\        R7      MRp\        T4      \        8”  d   \        T4      # T#   \        \
        3 d    Tu # i ; i)z‚``structuredContent`` (or None); over the hard cap it degrades to the head+tail
truncated JSON string (multi-MB JSON flood guard).Ústructured_contentÚstructuredContentF)Úensure_asciiÚdefaultrR  )	r   r©   Údumpsr'   r¬   Ú
ValueErrorr_  r   r   )r­   Ú
structuredÚas_jsons   &  r*   Ú_capped_structured_contentrq    so   € ô ˜6Ð#7Ð9LÓM€JðØMWÒMc”$—*’*˜Z°eÄSÕIÐikˆô 25°W³Ô@ZÔ1ZÔ$ WÓ-ÐjÐ`jÐjøô ”zÐ"ô ØÒðús   �#A ÁA)Á(A)c                ó$   € V ^8„  d   QhR\         /# r¦   r§   )r)   s   "r*   r+   r+   .  s   € ÷ ñ ¼$ñ r,   c                óÜ   € V P                   ;'       g    .  F9  p\        VRR4      pV'       g   K   \        P                  ! V4      V8X  d    R# K;  	  R#   \        \
        3 d     KS  i ; i)uA  True when some text block is ``structuredContent`` serialized as JSON â€” the spec's
backwards-compat dual-emit ("a tool that returns structured content SHOULD also return the
serialized JSON in a TextContent block"). Compared as parsed JSON so whitespace, indent, key
order and ``ensure_ascii`` escaping do not matter; checked per block because the spec puts the
copy in *a* block and a server may add a status line next to it. Deterministic equality, not a
richness heuristic: a prose summary or a reorganised rendering fails it and keeps its
``structuredContent`` (#115430).rL  NTF)rT  r  r©   rª   r¬   rn  )r­   ro  rd  rL  s   &&  r*   Ú_content_dual_emits_structuredrt  .  sm   € ð —.‘.×&Ð& BÒ&ˆÜ�u˜f dÓ+ˆßÙð	Ü�zŠz˜$Ó :Ô-Úñ .ñ 'ñ øô œ:Ð&ô 	Úð	ús   ²AÁA+Á*A+c                óh   € V ^8„  d   QhR\         R\        \        \         ,          ,          R\         /# )r"   r#   rc  r%   r6   )r)   s   "r*   r+   r+   B  s1   € ÷ &Gñ &G´#ð &GÄHÌTÔRUÍYÕDWð &GÔcfñ &Gr,   c           	     óÆ  € \        V RRR4      '       d1   \        \        \        \	        V 4      ;'       g    R4      4      4      # \        W4      w  r4pVe   VP                  V4       \        V 4      p\        \        V RR4      4      pVe1   V^ 8”  d*   \        V\        4      '       g   \        W4      '       d   RpVf   Vf   \        P                  ! RV/RR7      # V'       d   RV/M/ pVe   YhV'       d   R	MR&   Ve   WxR
&   VP                  RV4        \        P                  ! VRR7      #   \        \         3 d    \        P                  ! RT/RR7      u # i ; i)uä  Pure: ``CallToolResult`` -> handler JSON (``image_paths``, when given, receives the files this
call's image blocks were cached to). ``content`` and ``structuredContent`` are both
forwarded, except that a ``structuredContent`` whose JSON also sits verbatim in a text block
(the spec's backwards-compat dual-emit; compared as parsed JSON) is dropped, because that copy
would reach the model twice (kimi-code#3234). Any other usable text â€” a status line, a prose
summary, a reorganised rendering â€” keeps ``structuredContent`` alongside it (#115430): the
earlier "content wins whenever it rendered anything" rule irreversibly lost servers whose
data lived only in ``structuredContent``, while the residual duplicate for a faithful
reorganisation costs only tokens, so data-preservation wins. No richness or size heuristic is
used. ``structuredContent`` fills ``result`` when the blocks rendered effectively empty
(structuredContent-only servers); ``_meta`` minus reserved keys is always surfaced.Úis_errorÚisErrorFzMCP tool returned an errorNÚmetar­   ©rk  rj  Ú_meta)r   r   r   r   rV  rg  Úextendrq  r   r  r'   rt  r©   rm  Ú
setdefaultr¬   rn  )	r­   r#   rc  Útext_resultrb  Úcached_imagesro  ry  Úpayloads	   &&&      r*   Ú_render_call_tool_resultr�  B  s\  € ô �˜ Y°×6Ò6Üœ/Ô*CÔDVÐW]ÓD^×D~ÐD~Ðb~Ó*ó  Aó  Bð  	BÜ/EÀfÓ/ZÑ,€K˜}ØÒØ×Ñ˜=Ô)Ü+¨FÓ3€JÜ$¤Y¨v°v¸vÓ%FÓG€Dð Ò ,°Ô"2¼
À:Ìs×8SÒ8SÔWuÐv|÷  XJò  XJØˆ
ØÒ˜dšlÜ�zŠz˜8 [Ð1ÀÔFÐFç9D˜x¨Ñ5È"€Gð ÒØDN§{Ñ#¸ÑAØÒØ�ÑØ×Ñ�x Ô-ðGÜ�zŠz˜'°Ô6Ð6øÜ”zÐ"ô GÜ�zŠz˜8 [Ð1ÀÔFÒFðGús   ÄD2 Ä2+E ÅE Únative_imagesc                óH   € V ^8„  d   QhR\         R\         R\        R\        /# )r"   r#   r$   r‚   r‚  )r'   r„   r(   )r)   s   "r*   r+   r+   k  s)   € ÷ 7ñ 7¤Cð 7´Cð 7Äuð 7Ô`dñ 7r,   c               ó4   a aaaa€ RS 2oR VVV VV3R llpV# )a—  Sync handler (``handler(args_dict, **kwargs)``) calling an MCP tool via the background loop. Always a JSON
string, except with ``native_images`` (the registry handler the agent loop dispatches): a result carrying
images then becomes the ``_multimodal`` envelope when the active route takes images in tool results.
Direct callers (plugins' ``ctx.call_mcp``) keep the string contract and the ``MEDIA:`` paths.ztools/call c                ó0   € V ^8„  d   QhR\         R\        /# ©r"   r/  r%   )r1  r   )r)   s   "r*   r+   Ú(_make_tool_handler.<locals>.__annotate__r  s   € ÷ /{ñ /{”tð /{¬#ñ /{r,   c                 óÜ  <a a
aaaa€ . p\        SSV4      pVe   V# R \        S4      uopVf   \        SS4      w  opSf   V F  pVP                  4        K  	  V# \	        SS4      o. o^ RIHp V! 4       oV3R lo
V
V VVVVVVV3	R lpVV3R lp\        \        S'       * R7      p\        SSSVS\        \        V3VRR7      p	S'       d   \        V	4      '       g   \        V	S4      # T	# )N)Úcurrent_tool_progressc              “   ó.   <"  € Se   S! WV4       R # R # 5irº   r½   )ÚprogressÚtotalrk   Úreports   &&&€r*   Ú_on_progressÚ:_make_tool_handler.<locals>._handler.<locals>._on_progress‡  s   øé € ØÒ!Ù�x¨Ö0ñ "ùs   ƒc               “   óX  <	"  € SP                   ;_uu_4       GR j  x€L
  \        SSSSR7      ;_uu_4       GR j  x€L
  \        P                  ! 4       Sn         \        SSS	SSe   SMR 4      G R j  x€L
 p R Sn        R R R 4      GR j  x€L
  R R R 4      GR j  x€L
  \        SRR 4      e   SP                  4        SP                  4        \        X SS4      #  L¿ L¡ Lk  R Sn        i ; i Lb  + GR j  x€L 
 '       g   i     Ly; i Lp  + GR j  x€L 
 '       g   i     L‡; i5i)N)r  Ú_mark_session_proven)
Ú	_rpc_lockr-  ÚcontextvarsÚcopy_contextÚ_pending_call_contextrH  r  r‘  Úclearr�  )
r­   rŽ  r/  rc  r  Ú	read_onlyr�  r�   r#   r$   s
    €€€€€€€€€r*   Ú_callÚ3_make_tool_handler.<locals>._handler.<locals>._call‹  sí   øé € Ø×'×'×'Ó'Ô)<¸VÀ[ÐRTÐaj×)k×)kÖ)kÜ/:×/GÒ/GÓ/I�Ô,ð8Ü#@Ø ¨Y¸ÈfÒN`¹lÐfjó$l÷ l�Fð 48�FÔ0÷ *l×)k×'×'ô �vÐ5°tÓ<ÒHØ×+Ñ+Ô-Ø×ÑÔÜ+¨F°KÀÓMÐMñ (Ñ)kñløð 48�FÕ0ú÷ *l×)k×)kÒ)kú×'×'×'Ò'üsÁ   ƒD*œC�D* D¼C½DÁ C0	ÁC"Á4C Á5C"Á9C0	Â DÂC.ÂDÂD*ÂDÂAD*ÃDÃ C"Ã"	C+Ã+C0	Ã.DÃ0D	Ã6C9Ã7
D	ÄD	ÄDÄD*ÄD'	ÄDÄ
D'	Ä D'	Ä"D*c                 ód   <€ \         P                  ! S4       \        P                  R SSV 4       R# )zMCP tool %s/%s call failed: %sN)r   r›   ra   rb   )rn   r#   r$   s   &€€r*   Ú_on_failureÚ9_make_tool_handler.<locals>._handler.<locals>._on_failure˜  s%   ø€ Ü×$Ò$ [Ô1Ü�L‰LÐ9¸;È	ÐSVÖWr,   )rå   T)r  )rL   r   r¤   Úrefundr3   Úagent.tool_progress_relayr‰  r   rí   r  r  rä   r®   r   )r/  Úkwargsr5   rb   rK   r‰  r˜  r›  Úsession_expiredrL  rŽ  rc  r—  r�  r�   r‚  r  r#   r$   r‚   s   f,        @@@@@€€€€€r*   Ú_handlerÚ$_make_tool_handler.<locals>._handlerr  sø   þ€ àˆÜ! +¨y¸&ÓAˆØÒØˆLØÔ4°[ÓAˆˆ�ØŠ=Ü0°¸lÓK‰MˆF�EØŠ>Û �Ø—‘–ñ !àˆLô ' {°IÓ>ˆ	Ø!#ˆåCÙ&Ó(ˆõ	1÷	Nõ 	Nö	Xô "Ô"CÐdmÔ`mÔnˆÜØ˜  U¨LÜ1Ô3OÐQ`ÐaØ¨ô.ˆ÷
 ERÔZjÐko×ZpÒZpÔ-¨d°KÓ@ÐzÐvzÐzr,   r½   )r#   r$   r‚   r‚  r¡  r  s   fffd @r*   Ú_make_tool_handlerr£  k  s%   ü€ ð
 �y�kÐ	"€B÷/{ô /{ð` €Or,   c                óR   € V ^8„  d   QhR\         R\         R\        \         ,          /# )r"   r  Ú	log_labelÚrequiredrq   )r)   s   "r*   r+   r+   ¥  s&   € ÷ ñ œcð ¬cð Ì(ÔSVÍ-ñ r,   c                ó*   a aaaa€ R VV VVV3R llpV# )zî``(server_name, tool_timeout) -> sync handler`` for one utility tool: ``rpc(session, args,
server_name)`` awaited under ``_rpc_lock``, ``render(result, server_name)`` -> JSON-able
payload, ``required`` validated before any transport work.c                ó0   € V ^8„  d   QhR\         R\        /# r�   rƒ   )r)   s   "r*   r+   Ú+_make_utility_handler.<locals>.__annotate__©  s   € ÷ ñ œcð ´ñ r,   c                 ó*   <a a€ R  VVVVVV V3R llpV# )c                ó0   € V ^8„  d   QhR\         R\        /# r†  )r1  r'   )r)   s   "r*   r+   Ú=_make_utility_handler.<locals>._factory.<locals>.__annotate__ª  s   € ÷ 	_ñ 	_œ4ð 	_¬cñ 	_r,   c           
      ó8  <a a€ ^ RI Hp VP                  S
4      oS'       d   SP                  '       g   \	        RS
 R24      # S'       d'   S P                  S4      '       g   \	        RS R24      # V VV	VV
3R lp\        S
SSVS\        \        3VV
3R l4      # )é    r†   rQ   rˆ   zMissing required parameter 'Ú'c               “   ó   <"  € SP                   ;_uu_4       GR j  x€L
  S! SP                  SS4      G R j  x€L
 p R R R 4      GR j  x€L
  \        P                  ! S! X S4      RR7      #  LO L5 L'  + GR j  x€L 
 '       g   i     L>; i5i)NFrz  )r’  r˜   r©   rm  )r­   r/  ÚrenderÚrpcr�   r#   s    €€€€€r*   r˜  ÚH_make_utility_handler.<locals>._factory.<locals>._handler.<locals>._call²  s`   øé € Ø!×+×+×+Ó+Ù#& v§~¡~°t¸[Ó#I×I�F÷ ,×+ä—z’z¡&¨°Ó"=ÈEÔRÐRñ ,ÙI÷ ,×+×+Ò+üsY   ƒBœA,�B A2¸A.¹A2½BÁA0Á	$BÁ.A2Á0BÁ2B	Á8A;Á9
B	ÂB	ÂBc                 ó4   <€ \         P                  R SSV 4      # )zMCP %s/%s failed: %s)ra   rb   )rn   r¥  r#   s   &€€r*   rØ   ÚK_make_utility_handler.<locals>._factory.<locals>._handler.<locals>.<lambda>¹  s   ø€ œFŸL™LÐ)?ÀÈiÐY\Ô]r,   )	r=   r‡   r–   r˜   r   r2   r  rä   rí   )r/  rŸ  r�   r˜  r�   r¥  r  r±  r¦  r²  r#   r‚   s   f,  @€€€€€€€r*   r¡  Ú9_make_utility_handler.<locals>._factory.<locals>._handlerª  s�   ú€ Ý>Ø×>Ñ>¸{ÓKˆFß §§ Ü! L°°Ð=OÐ"PÓQÐQß §¡¨× 2Ò 2Ü!Ð$@ÀÀ
È!Ð"LÓMÐM÷Sñ Sô Ø˜V R¨°Ü-Ô/PÐQÝ]ó_ð _r,   r½   )r#   r‚   r¡  r¥  r  r±  r¦  r²  s   ff €€€€€r*   Ú_factoryÚ'_make_utility_handler.<locals>._factory©  s   ú€ ÷	_ö 	_ð  ˆr,   r½   )r  r¥  r²  r±  r¦  r·  s   fffff r*   Ú_make_utility_handlerr¹  ¥  s   ü€ ÷ô ð$ €Or,   c                ó$   € V ^8„  d   QhR\         /# r¦   )r1  )r)   s   "r*   r+   r+   ¾  s   € ÷ ñ œ$ñ r,   c                ó¢   € / pV FF  vr4p\        W\        4      pV\        Jg   K!  V'       g   V'       d   V^ ,          '       d   KB  WbV&   KH  	  V# )z¸``{out_key: value}`` for each ``(out_key, attr[, truthy])`` present on *obj* (presence check so SDK models
and stubs behave alike; ``truthy`` also skips falsy). Key order = spec order.)r  Ú_MISSING)ÚobjÚspecsÚentryÚout_keyÚattrÚtruthyÚvalues   &*     r*   Ú_pickrÄ  ¾  sF   € ð €EÛ"'Ðˆ˜Ü˜¤8Ó,ˆØœÕ §e·F¸vÀa¿y¾yØ"�'‹Nñ #(ð €Lr,   c                ó0   € V ^8„  d   QhR\         R\        /# rp   r0  )r)   s   "r*   r+   r+   É  s   € ÷ 
$ñ 
$´cð 
$¼dñ 
$r,   c                 óÈ   € . pV  FW  p\        VRRR4      pR V9   d   \        VR ,          4      VR &   \        VRR4      pV'       d   WTR&   VP                  V4       KY  	  RV/# )ÚuriÚ	mime_typeÚmimeTypeÚ	resources)rÇ  rÇ  ©rŠ   rŠ   ©rl   rl   T)rÄ  r'   r   rF   )Úall_resourcesr#   rÊ  Úrr¿  Úmimes   &&    r*   Ú_render_resource_listrÐ  É  sp   € Ø€IÛˆÜ�a˜Ð)9Ð;_Ó`ˆØ�EŒ>Ü˜u U�|Ó,ˆE�%‰LÜ˜˜K¨Ó4ˆßØ $�*ÑØ×Ñ˜Öñ ð ˜Ð#Ð#r,   c                ó0   € V ^8„  d   QhR\         R\        /# rp   r0  )r)   s   "r*   r+   r+   Ö  s   € ÷ (ñ (¬sð (´tñ (r,   c                 ór  € . p\        V R . 4       F’  p\        VRR4      e'   VP                  \        VP                  4      4       K8  \        VRR4      f   KI  \	        \        RVR7      V4      pTP                  T;'       g    R\        VP                  4       R24       K”  	  RR	P                  V4      /# )
ÚcontentsrL  NÚblobrM  )r  rM  z[binary data, z bytes]r­   rZ  )	r  rF   r   rL  r   r   r_  rÔ  r^   )r­   r#   ra  rd  re  s   &&   r*   Ú_render_read_resourcerÕ  Ö  sŸ   € Ø€EÜ˜ ¨RÖ0ˆÜ�5˜& $Ó'Ò3Ø�L‰LÔ+¨E¯J©JÓ7Ö8Ü�U˜F DÓ)Ô5Ü1´/ÀzÐ\aÔ2bÐdoÓpˆHØ�L‰L˜×NÐN ~´c¸%¿*¹*³oÐ5FÀgÐ%NÖOñ 1ð �d—i‘i Ó&Ð'Ð'r,   c                ó0   € V ^8„  d   QhR\         R\        /# rp   r0  )r)   s   "r*   r+   r+   á  s   € ÷  ñ  ´#ð  ¼$ñ  r,   c           
      óü   € . pV  Fl  p\        VRR4      p\        VRR4      '       d9   VP                   Uu. uF  pR VP                  /\        VRR4      CNK   	  upVR&   VP	                  V4       Kn  	  RV/# u upi )rŠ   r5  NÚpromptsrË  rÌ  )r¦  r¦  )rÄ  r  r5  rŠ   rF   )Úall_promptsr#   rØ  Úpr¿  Úas   &&    r*   Ú_render_prompt_listrÜ  á  s�   € Ø€GÛˆÜ�aÐ)Ð+OÓPˆÜ�1�k 4×(Ò(à+,¯;ª;ó"8Ù+6 að $*¨1¯6©6Ð"~´U¸1Ð>bÐd|Ó5}Ó"~Ù+6ñ"8ˆE�+Ñà�‰�uÖñ ð �wÐÐùò"8s   ¶$A9c                ó0   € V ^8„  d   QhR\         R\        /# rp   r0  )r)   s   "r*   r+   r+   ì  s   € ÷ Yñ Y¬Cð Y´Dñ Yr,   c                 óR  € . p\        V R . 4       F…  p\        VR4      p\        VR4      '       dT   \        \        VP                  R4      '       d   VP                  P
                  M\        VP                  4      4      VR&   VP                  V4       K‡  	  R V/\        V R4      C# )ÚmessagesrT  rL  )Úrolerà  rÌ  )r  rÄ  rÅ   r   rT  rL  r'   rF   )r­   r#   rß  Úmsgr¿  s   &&   r*   Ú_render_get_promptrâ  ì  s“   € Ø€HÜ�v˜z¨2Ö.ˆÜ�cÐ+Ó,ˆÜ�3˜	×"Ò"Ü1ÄgÈcÏkÉkÐ[a×FbÒFb°#·+±+×2BÒ2BÔhkÐlo×lwÑlwÓhxÓyˆE�)ÑØ�‰˜Öñ	 /ð
 ˜ÐX¤E¨&Ð2VÓ$WÐXÐXr,   zresources/listÚlist_resourcesc                 óF   € \         P                  ! V P                  R V4      # )rÊ  )r   Ú_paginate_full_listrã  ©r˜   r/  Úsns   &&&r*   rØ   rØ   ø  s   € œe×7Ò7¸×8NÑ8NÐP[Ð]_Ô`r,   zresources/readÚread_resourcec                 ó2   € V P                  VR ,          4      # )rÇ  )rè  ræ  s   &&&r*   rØ   rØ   û  s   € ˜g×3Ñ3°D¸µKÔ@r,   rÇ  )r¦  zprompts/listÚlist_promptsc                 óF   € \         P                  ! V P                  R V4      # )rØ  )r   rå  rê  ræ  s   &&&r*   rØ   rØ   þ  s   € œe×7Ò7¸×8LÑ8LÈiÐY[Ô\r,   zprompts/getÚ
get_promptc                 óV   € V P                  VR ,          VP                  R/ 4      R7      # )rŠ   r5  )r5  )rì  r2   ræ  s   &&&r*   rØ   rØ     s%   € ˜g×0Ñ0°°fµÈÏÉÐR]Ð_aÓIbÐ0Ôcr,   rŠ   c                ó$   € V ^8„  d   QhR\         /# )r"   r#   rµ   )r)   s   "r*   r+   r+     s   € ÷ ñ ¤ñ r,   c                ó@   a aa€ ^ RI Ho R VV 3R lloR VV 3R llpV# )a�  Connection-alive check; lazy (schema-cache registered) servers count as available.

When the server's owner registered an application declaration (`requires.app`), the
application must also be present on this host, or the tools are not offered even while a
stale connection lingers. With no declaration registered the check is the connection check
alone. Returns a plain bool: the registry caches ``bool(fn())``.
r.   c                ó$   € V ^8„  d   QhR\         /# r¦   r§   )r)   s   "r*   r+   Ú$_make_check_fn.<locals>.__annotate__  s   € ÷ :ñ :œñ :r,   c                  óZ  <€ \         P                  ;_uu_ 4        S! S4      p \         P                  P                  V 4      pVR J;'       d/    VP                  R J;'       g,    VP                  4       ;'       g    V \         P                  9   uuR R R 4       #   + '       g   i     R # ; irº   )r   rÃ   rÄ   r2   r˜   Ú_is_recycled_stdioÚ_lazy_server_configs)rI   r�   r/   r#   s     €€r*   Ú
_connectedÚ"_make_check_fn.<locals>._connected  sz   ø€ Ü�[�[‹[Ù% kÓ2ˆCÜ—^‘^×'Ñ'¨Ó,ˆFØ 4Ð'×gÐg¨V¯^©^À4Ð-G÷ 9Ð-fÈ6×KdÑKdÓKf÷ 9ð 9Øœe×8Ñ8Ñ8÷	 �[�[‹[ús   šABÁ#BÁ;BÂB*	c                ó$   € V ^8„  d   QhR\         /# r¦   r§   )r)   s   "r*   r+   rñ    s   € ÷ 4ñ 4”Dñ 4r,   c                  ó8   <€ S ! 4       '       g   R # \        S4      # ©F)Ú_declared_app_offerable)rõ  r#   s   €€r*   Ú_checkÚ_make_check_fn.<locals>._check  s   ø€ Ù�|Š|ÙÜ& {Ó3Ð3r,   )r0   r/   )r#   rû  rõ  r/   s   f @@r*   Ú_make_check_fnrý    s#   ú€ õ 9÷:ñ :÷4ñ 4ð €Mr,   c                ó0   € V ^8„  d   QhR\         R\        /# rp   r&   )r)   s   "r*   r+   r+     s   € ÷ 	.ñ 	.¬ð 	.´ñ 	.r,   c                ó€   € ^ RI Hp ^ RIHp VP                  ! V 4      pVf   R# \        V! V4      P                  4      # )z«True unless the registered declaration is unavailable on this host. Called only for a
connected server, so a reachable loopback port outranks the interactive-session rule.r   )r•   T)Úhermes_platformr   Ú%hermes_platform.resolver.availabilityr•   Úlookupr(   Ú	offerable)r#   r   r•   r    s   &   r*   rú  rú    s8   € õ ,ÝBà×Ò˜kÓ*€DØ‚|ÙÜ‘˜TÓ"×,Ñ,Ó-Ð-r,   rº   rù  )`rÿ   Úloggingr#  r“  r;  r©   rt   Ú
contextlibr   Ú	functoolsr   Útypesr   Útypingr   r   r   r   r	   r
   r   r   Útools.registryr   r   Útools.ansi_stripr   Útools.mcp_tool_commonr   r   r   r   r=   r   r™   Útools.mcp_tool_contentr   r   r   r   r   r   r   r   Útools.mcp_tool_errorsr   r   r   r    Ú	getLoggerra   Úobjectr¼  Ú	on_changerá   r	  r
  r  rë   r3   rL   rD   r   r¤   r®   r³   r·   r¾   rÈ   rÐ   rä   rí   r'  rï   r  r  r-  rH  rV  rg  rq  rt  r�  r£  r¹  rÄ  rÐ  rÕ  rÜ  râ  Ú_make_list_resources_handlerÚ_make_read_resource_handlerÚ_make_list_prompts_handlerÚ_make_get_prompt_handlerrý  rú  r½   r,   r*   Ú<module>r     s  ðñvó Û Û Û Û Û Ý *Ý Ý !ß =× =å 'ß @Ý /ß MÓ MÝ (÷÷ ó ÷]ó ]ð 
×	Ò	Ð+Ó	,€Ù‹8€à1€Ô ðfð ðCð ð
ið ð^ð ð4ð õh÷Rð22rØ $÷2rõjpõ*õBõõ(õH÷õ	5õ:ð4+UØLQ÷+Uô\#˜ô #õ4C÷n9ð4 ð#Ð\`ö #ó ð#÷83Kõp/õ'RòTkõ*÷(&GðR7Ðgl÷ 7÷tõ2õ
$õ(õ õYñ  5ØÐ&Ù`Ðbwó yÐ ñ 4Ø�oÙ@ÐBWÐbgôiÐ ñ 3Ø�NÙ\Ð^qósÐ ñ 1Ø�<ÙcØ ô)Ð õ÷0	.r,   