Ë
    ãß²jgÇ  ã                   óö  — U d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZ ddlmZ ddlmZmZmZmZmZ ddlmZ  ej,                  e«      ZdZdZd	Zd
edefd„Zdedefd„Zdej>                  de fd„Z!dede fd„Z"dedee   fd„Z#dCdee   dee   fd„Z$dee   fd„Z%deee&f   fd„Z'deee&f   ddfd„Z( edd¬«       G d„ d«      «       Z) G d „ d!«      Z*d"Z+d#Z,d$Z-d%Z.i Z/ee0eee   f   e0e1e f   f   e2d&<   i Z3ee0eee   f   e1f   e2d'<    e4«       Z5ee0eee   f      e2d(<    e4«       Z6ee0eee   f      e2d)<    ejn                  «       Z8d*Z9 e4«       Z:ee   e2d+<   d,Z;d-edefd.„Z<d-ede=fd/„Z>d0e1ddfd1„Z?dee   fd2„Z@d-ede fd3„ZAd-ede fd4„ZBd-edee   fd5„ZCd-ed6eee f   de fd7„ZDdDd8„ZEd-edee    fd9„ZF G d:„ d;«      ZGd<ee)   de&fd=„ZH eG«       ZIdefd>„ZJdCdefd?„ZKd@edAeLdeLfdB„ZMy)Ea¹  Central registry for all hermes-agent tools: each tool file calls ``registry.register()``
at import to declare schema, handler, toolset membership and availability check;
``model_tools.py`` queries the registry instead of keeping parallel data structures.
Cycle-safe import chain: this module imports nothing from model_tools or tool files;
tools/*.py import it at module level; model_tools.py imports both; run_agent/cli import
model_tools.é    N)Ú	dataclass)ÚPath)ÚCallableÚDictÚListÚOptionalÚSet©Úhermes_home_keyi   u   â€¦ [truncated]i    ÚtextÚreturnc                 ó˜   — t        | «      t        k  r| S t        j                  dt        | «      | dt         «       | dt         t
        z   S )zJBound an error body destined for model context; logs keep a longer prefix.z4tool error body truncated for context (%d chars): %sN)ÚlenÚ_MAX_TOOL_ERROR_CHARSÚloggerÚdebugÚ_MAX_LOGGED_ERROR_CHARSÚ_TOOL_ERROR_TRUNCATION_MARKER)r   s    ú3/home/ubuntu/.hermes/hermes-agent/tools/registry.pyÚ_bound_error_textr       sL   € ä
ˆ4ƒyÔ)Ò)ØˆÜ
‡L�LØ>ÜˆD‹	�4Ð0Ô0Ð1ô3ð Ð&Ô&Ð'Ô*GÑGÐGó    Úresultc                 óX  — t        | «      t        k  sd| vr| S 	 t        j                  | «      }t        |t        «      r|j                  d«      nd}t        |t        «      rt        |«      t        k  r| S t        |«      |d<   t        j                  |d¬«      S # t        $ r | cY S w xY w)zòTrim an oversized ``error`` field in a JSON string result: handlers that
    ``json.dumps({"error": str(exc)})`` directly bypass ``tool_error``'s cap, so this runs
    at the dispatch boundary to stop unbounded errors stacking across retries.z"error"ÚerrorNF©Úensure_ascii)r   r   ÚjsonÚloadsÚ
ValueErrorÚ
isinstanceÚdictÚgetÚstrr   Údumps)r   Úpayloadr   s      r   Ú_bound_json_error_resultr&   *   sœ   € ô ˆ6ƒ{Ô+Ò+¨yÀÑ/FØˆðÜ—*‘*˜VÓ$ˆô %/¨w¼Ô$=ˆG�K‰K˜Ô À4€EÜ�eœSÔ!¤S¨£ZÔ3HÒ%HØˆÜ(¨Ó/€GˆGÑÜ�:‰:�g¨EÔ2Ð2øô ò ØŠðús   šB ÂB)Â(B)Únodec                 ó„  — t        | t        j                  «      r$t        | j                  t        j                  «      sy| j                  j
                  }t        |t        j                  «      xrP |j                  dk(  xr? t        |j                  t        j                  «      xr |j                  j                  dk(  S )zATrue when *node* is a ``registry.register(...)`` call expression.FÚregisterÚregistry)
r    ÚastÚExprÚvalueÚCallÚfuncÚ	AttributeÚattrÚNameÚid)r'   r/   s     r   Ú_is_registry_register_callr4   ;   s„   € ä�dœCŸH™HÔ%¬Z¸¿
¹
ÄCÇHÁHÔ-MØØ�:‰:�?‰?€Dä�4œŸ™Ó'ò 	M¨D¯I©I¸Ñ,Cò 	MÜ�t—z‘z¤3§8¡8Ó,ò	MØ15·±·±À*Ñ1LðNr   Úmodule_pathc                 óÜ   — 	 | j                  d¬«      }d|vsd|vryt        j                  |t        | «      ¬«      }t        d„ |j                  D «       «      S # t        t
        f$ r Y yw xY w)züTrue when the module body (or a module-level ``for``) calls ``registry.register(...)``.
    Only module-body statements count, so helpers registering inside a function are skipped;
    a text prefilter avoids ``ast.parse`` for files lacking both words.úutf-8©Úencodingr*   r)   F)Úfilenamec              3   ó¦   K  — | ]I  }t        |«      xs8 t        |t        j                  «      xr t	        d „ |j
                  D «       «      –— ŒK y­w)c              3   ó2   K  — | ]  }t        |«      –— Œ y ­w©N)r4   )Ú.0Úss     r   ú	<genexpr>z4_module_registers_tools.<locals>.<genexpr>.<genexpr>S   s   è ø€ Ò-_ÐPQÔ.HÈ×.KÑ-_ùs   ‚N)r4   r    r+   ÚForÚanyÚbody)r>   Ústmts     r   r@   z*_module_registers_tools.<locals>.<genexpr>Q   sP   è ø€ ò ð ô 	# 4Ó(ò 	aÜ�tœSŸW™WÓ%Ò_¬#Ñ-_ÐUY×U^ÑU^Ô-_Ó*_ó	añùs   ‚AA)Ú	read_textr+   Úparser#   ÚOSErrorÚSyntaxErrorrB   rC   )r5   ÚsourceÚtrees      r   Ú_module_registers_toolsrK   E   s|   € ðØ×&Ñ&°Ð&Ó8ˆØ˜VÑ# z¸Ñ'?ØÜ�y‰y˜¬#¨kÓ*:Ô;ˆô ñ ð —I‘Iôó ð øô ”[Ð!ò Ùðús   ‚A � A ÁA+Á*A+Ú
tools_pathc                 ó‚   — t        | j                  d«      «      t        | j                  d«      «      z   }t        |«      S )ah  Flat ``tools/*.py`` modules plus the package entry point ``tools/<pkg>/tool.py``, in one
    sorted list. Only ``tool.py`` is scanned in a package, so every other file in it is a library
    by construction. Sorted after merging: ``register()`` lets a same-name, same-toolset duplicate
    overwrite silently, so the import order must not depend on file depth.z*.pyz	*/tool.py)ÚlistÚglobÚsorted)rL   Ú
candidatess     r   Ú_tool_module_candidatesrR   W   s5   € ô
 �j—o‘o fÓ-Ó.´°j·o±oÀkÓ6RÓ1SÑS€JÜ�*ÓÐr   Ú	tools_dirc                 óÄ  — | �t        | «      n&t        t        «      j                  «       j                  j                  «       }t	        «       }i }d}g }t        |«      D �]m  }|j                  dv rŒ|j                  |«      j                  d«      j                  }t        |«      dkD  rI|j                  dz  j                  «       s,t        j                  d||j                  j                  «       Œ”t        |j                  «       «      }	 |j                  «       }	|	j                   |	j"                  f}
|j'                  |«      }t)        |t*        t,        f«      r.t        |«      dk(  r t-        |dd	 «      |
k(  rt/        |d	   «      }nt1        |«      }d
}|
d   |
d   |g||<   |s�ŒJ|j3                  dj5                  dg|¢­«      «       �Œp |st7        |«      t7        |«      k7  rt9        |«       g }|D ])  }	 t;        j<                  |«       |j3                  |«       Œ+ |S # t$        $ r Y �ŒÓw xY w# t>        $ r!}t        j                  d||«       Y d}~Œcd}~ww xY w)aK  Import built-in self-registering tool modules and return their module names. The
    per-file AST scan costs ~145 ms over ~100 files, so verdicts are memoized on disk keyed
    by ``(mtime_ns, size)``; a mismatch or corrupt cache re-scans that file. The write is
    best-effort and atomic, so concurrent processes race harmlessly.NF>   úmcp_tool.pyúregistry.pyú__init__.pyÚ é   rW   z*Skipping %s: package %s has no __init__.pyé   é   Tr   ú.Útoolsz#Could not import tool module %s: %s) r   Ú__file__ÚresolveÚparentÚ_load_discovery_cacherR   ÚnameÚrelative_toÚwith_suffixÚpartsr   Úexistsr   Úwarningr#   ÚstatÚst_mtime_nsÚst_sizerG   r"   r    rN   ÚtupleÚboolrK   ÚappendÚjoinÚsetÚ_save_discovery_cacheÚ	importlibÚimport_moduleÚ	Exception)rS   rL   ÚcacheÚfresh_cacheÚcache_dirtyÚmodule_namesÚpathÚ	rel_partsÚabs_pathÚstÚstat_keyÚcachedÚ	registersÚimportedÚmod_nameÚes                   r   Údiscover_builtin_toolsr‚   `   s*  € ð
 &/Ð%:”$�y”/ÄÄXÃ×@VÑ@VÓ@X×@_Ñ@_×hÑhÓj€JÜ!Ó#€EØ#%€KØ€KØ €LÜ'¨
Ó3ó AˆØ�9‰9ÐEÑEØØ×$Ñ$ ZÓ0×<Ñ<¸RÓ@×FÑFˆ	Üˆy‹>˜AÒ t§{¡{°]Ñ'B×&JÑ&JÔ&Lô �N‰NÐGÈÈtÏ{É{×O_ÑO_Ô`ØÜ�t—|‘|“~Ó&ˆð	Ø—‘“ˆBØŸ™¨¯
©
Ð3ˆHð —‘˜8Ó$ˆÜ�fœt¤U˜mÔ,´°V³ÀÒ1AÄeÈFÐSUÐTUÈJÓFWÐ[cÒFcÜ˜V A™Y›‰Iä/°Ó5ˆIØˆKØ!)¨!¡¨h°q©k¸9Ð Eˆ�HÑÛØ×Ñ §¡¨'Ð)>°IÑ)>Ó ?Ö@ð/Añ4 ”c˜+Ó&¬#¨e«*Ò4Ü˜kÔ*Ø€HØ ò Oˆð	OÜ×#Ñ# HÔ-Ø�O‰O˜HÕ%ðOð €Oøô- ò 	Úð	ûô( ò 	OÜ�N‰NÐ@À(ÈA×NÑNûð	Oús*   Ä(H%Ç;&H5È%	H2È1H2È5	IÈ>IÉIc                  óZ   — 	 ddl m}  t         | «       «      dz  dz  S # t        $ r Y yw xY w)zBPath of the tool-discovery verdict cache, or None if unresolvable.r   ©Úget_hermes_homert   ztool_discovery_cache.jsonN)Úhermes_constantsr…   r   rs   r„   s    r   Ú_discovery_cache_pathr‡   �   s5   € ðå4Ü‘OÓ%Ó&¨Ñ0Ð3NÑNÐNøÜò Ùðús   ‚ ž	*©*c                  óæ   — t        «       } | €i S 	 t        | dd¬«      5 }t        j                  |«      }ddd«       t	        t
        «      r|S i S # 1 sw Y   ŒxY w# t        t        f$ r i cY S w xY w)u?   Read the discovery cache; any error â†’ empty dict (full scan).NÚrr7   r8   )r‡   Úopenr   Úloadr    r!   rG   r   )rx   ÚfhÚdatas      r   ra   ra   š   sw   € ä Ó"€DØ€|Øˆ	ðÜ�$˜ gÔ.ð 	!°"Ü—9‘9˜R“=ˆD÷	!ä! $¬Ô-ˆtÐ5°2Ð5÷	!ð 	!ûô ”ZÐ ò ØŠ	ðús-   �A žA´A ÁA ÁAÁA ÁA0Á/A0rt   c                 óÌ   — t        «       }|€y	 ddlm} ddlm}  ||j
                  «        ||| d¬«       y# t        $ r!}t        j                  d||«       Y d}~yd}~ww xY w)z>Best-effort atomic write of the discovery cache. Never raises.Nr   )Úatomic_json_write)Úmkdir_under_hermes_home)Úindentz+Could not write tool discovery cache %s: %s)	r‡   Úutilsr�   r†   r�   r`   rs   r   r   )rt   rx   r�   r�   r�   s        r   rp   rp   §   s\   € ä Ó"€DØ€|ØðMÝ+Ý<Ù §¡Ô,Ù˜$ ¨aÖ0øÜò MÜ�‰ÐBÀDÈ!×LÑLûðMús   �)9 ¹	A#ÁAÁA#FT)ÚeqÚslotsc                   ó    — e Zd ZU dZeed<   eed<   eed<   eed<   ee   ed<   e	ed<   e
ed<   eed	<   eed
<   dZeez  dz  ed<   dZee   ed<   y)Ú	ToolEntryzXMetadata for one registered tool (identity semantics: restore/CAS paths compare ``is``).rb   ÚtoolsetÚschemaÚhandlerÚcheck_fnÚrequires_envÚis_asyncÚdescriptionÚemojiNÚmax_result_size_charsÚdynamic_schema_overrides)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r#   Ú__annotations__r!   r   r   rN   rl   rŸ   ÚintÚfloatr    © r   r   r–   r–   µ   sa   … ábà
ƒIØƒLØƒLØÓØ�xÑ Ó ØÓØƒNØÓØƒJØ04Ð˜3 ™;¨Ñ-Ó4ð 48Ð˜h xÑ0Ô7r   r–   c                   ó$   — e Zd ZdZdZdeddfd„Zy)Ú_PluginOverridePolicyz@Identity-bearing authorization record for one plugin generation.)Úallowedr«   r   Nc                 ó$   — t        |«      | _        y r=   )rl   r«   )Úselfr«   s     r   Ú__init__z_PluginOverridePolicy.__init__Í   s   € Ü˜G“}ˆ�r   )r¡   r¢   r£   r¤   Ú	__slots__rl   r®   r¨   r   r   rª   rª   È   s   „ ÙJà€Ið% ð %¨ô %r   rª   zmPlugin module {owner!r} cannot override built-in tool {name!r} without operator opt-in (allow_tool_override).g      >@g      N@i   Ú_check_fn_cacheÚ_check_fn_last_goodÚ_check_fn_ever_goodÚ_check_fn_core_drop_warnedrX   Ú_NO_CACHE_CHECK_FNS)ÚHERMES_SESSION_IDÚ HERMES_BROWSER_CONTROL_PRINCIPALÚ'HERMES_BROWSER_CONTROL_TRANSPORT_FAMILYÚfnc                 ó0   — t         j                  | «       | S )z;Mark a local, config-backed availability check as uncached.)r´   Úadd©r¸   s    r   Úno_cache_check_fnr¼   ñ   s   € ä×Ñ˜BÔØ€Ir   c                 ó   — t        | d| «      S )Nr£   )Úgetattrr»   s    r   Ú	_fn_labelr¿   ÷   s   € Ü�2�~ rÓ*Ð*r   Únowc                 ód  — t         t        d„ ft        t        d„ ffD ]‘  \  }}}t	        |j                  «       «      D ]&  \  }}|  ||«      z
  |k\  sŒ|j                  |d«       Œ( t        |«      t        k\  sŒ\|j                  t        t        |«      «      «       t        |«      t        k\  rŒ6Œ“ y)zUExpire stale entries and cap profile-dimensional cache growth. Caller holds the lock.c                 ó   — | d   S ©Nr   r¨   ©Úvs    r   ú<lambda>z(_prune_check_fn_caches.<locals>.<lambda>þ   s
   € ¸1¸Q¹4€ r   c                 ó   — | S r=   r¨   rÄ   s    r   rÆ   z(_prune_check_fn_caches.<locals>.<lambda>ÿ   s   € È€ r   N)r°   Ú_CHECK_FN_TTL_SECONDSr±   Ú_CHECK_FN_FAILURE_GRACE_SECONDSrN   ÚitemsÚpopr   Ú_CHECK_FN_CACHE_MAXÚnextÚiter)rÀ   rt   ÚttlÚstampÚkeyr-   s         r   Ú_prune_check_fn_cachesrÒ   û   s¥   € ô 
Ô/±Ð@Ü	Ô=¹{ÐKðMò )Ñˆˆs�Eô ˜uŸ{™{›}Ó-ò 	%‰JˆC�Ø‘U˜5“\Ñ! SÓ(Ø—	‘	˜#˜tÕ$ð	%ô �%‹jÔ/Ó/Ø�I‰I”dœ4 ›;Ó'Ô(ô �%‹jÔ/Ô/ñ)r   c                  óX  ‡— 	 ddl mŠ t        ˆfd„t        D «       «      rddlm}   | «       rt        S 	 ddlm	} ddl
m}  |«       sy |«       }|r0t        t        |«      j                  «       j                  «       «      S t        S # t        $ r Y Œ_w xY w# t        $ r	 t        cY S w xY w)u	  Return the active profile key when availability is profile-scoped. Browser-controller
    availability is request-bound (changes on every attach/detach), so a fully bound
    browser-control request bypasses this cache AND model_tools' outer definition cache (same
    sentinel) â€” one Browser session's live tools must not leak into another. Single-profile
    processes keep the process-wide cache; a multiplex gateway installs a Hermes-home override
    per profile turn, so the canonical profile key is the boundary.r   )Úget_session_envc              3   óf   •K  — | ](  }t         ‰|d «      xs d «      j                  «       –— Œ* y­w)rX   N)r#   Ústrip)r>   ÚkrÔ   s     €r   r@   z'check_fn_cache_scope.<locals>.<genexpr>  s+   øè ø€ ÒY¸QŒs‘? 1 bÓ)Ò/¨RÓ0×6Ñ6×8ÑYùs   ƒ.1)Úbrowser_control_enabled)Úserves_routed_profile)Úget_hermes_home_overrideN)Úgateway.session_contextrÔ   ÚallÚ_BROWSER_IDENTITY_KEYSÚgateway.browser_control_brokerrØ   ÚCHECK_FN_CACHE_BYPASSrs   Úagent.secret_scoperÙ   r†   rÚ   r#   r   Ú
expanduserr_   )rØ   rÙ   rÚ   ÚoverriderÔ   s       @r   Úcheck_fn_cache_scoperã     s�   ø€ ð
Ý;ÜÓYÔBXÔYÔYõ OÙ&Ô(Ü,Ð,ð
%Ý<Ý=Ù$Ô&ØÙ+Ó-ˆÙ=EŒs”4˜“>×,Ñ,Ó.×6Ñ6Ó8Ó9Ð`ÔK`Ð`øô ò Ùðûô ò %ô %Ò$ð%ús.   ƒ0B µB Á	8B ÂB Â	BÂBÂB)Â(B)c                 ó2  — ddl m}m} 	 t         | «       «      S # |$ rL  |«       €!t        j                  dt        | «      «       Y yt        j                  dt        | «      d¬«       Y yt        $ r$ t        j                  dt        | «      d¬«       Y yw xY w)	z7Run an availability check without cache/grace handling.r   )ÚUnscopedSecretErrorÚcurrent_secret_scopez…check_fn %s hit the multiplex fail-closed path with no profile secret scope active; dependent tools re-probe on the first scoped turnz€check_fn %s raised UnscopedSecretError while the profile cache scope was resolved; dependent tools will be unavailable this turnT©Úexc_infozAcheck_fn %s raised; dependent tools will be unavailable this turnF)	rà   rå   ræ   rl   r   r   r¿   rg   rs   )r¸   rå   ræ   s      r   Ú_run_check_fn_uncachedré   &  s£   € çLð*Ü‘B“D‹zÐøØò .ñ  Ó!Ð)ô �L‰Lðaä˜"“õð ô �N‰NðTä˜"“¨ð õ .ð ô	 ò *Ü�‰ØOÜ�b‹M Dð 	õ 	*ð ð	*ús   Š š+BÁ!BÁ*)BÂBc           	      óX  — t        j                  «       }| t        v rt        | «      S t	        «       }|t
        k(  rt        | «      S | |f}t        5  t        |«       t        j                  |«      }|�|d   cddd«       S 	 ddd«       d}	 t         | «       «      d}}|st        t        | «      «      ng }	t        5  t        |«       |r3|t        |<   t        j!                  |«       |dft        |<   	 ddd«       yt        j                  |«      }
|
�;||
z
  t"        k  r/t$        j'                  dt)        | «      |t"        «       	 ddd«       y|	rX|t        v rP|t*        vrHt*        j!                  |«       t$        j'                  dt)        | «      |d	j-                  |	«      |¬
«       n7|rt$        j&                  nt$        j.                  } |dt)        | «      ||¬
«       |dft        |<   	 ddd«       y# 1 sw Y   �ŒvxY w# t        $ r}dd|}}}Y d}~�Œyd}~ww xY w# 1 sw Y   yxY w)z+Return bool(fn()), TTL-cached across calls.NrY   zreturned FalseFÚraisedTzicheck_fn %s failed (%s) within %.0fs of last success; treating as transient and keeping tool(s) availablez–check_fn %s %s; previously available core tool(s) %s dropped (non-deferrable, so not searchable either); dependent tools will be unavailable this turnz, rç   z=check_fn %s %s; dependent tools will be unavailable this turn)ÚtimeÚ	monotonicr´   ré   rã   rß   Ú_check_fn_cache_lockrÒ   r°   r"   rl   rs   rP   Ú_core_tools_gated_byr±   r²   rº   rÉ   r   rg   r¿   r³   rn   Úinfo)r¸   rÀ   ÚscopeÚ	cache_keyr}   rè   r-   ÚoutcomeÚexcÚcore_droppedÚ	last_goodÚlogs               r   Ú_check_fn_cachedrø   E  s&  € ä
�.‰.Ó
€CØ	Ô Ñ Ü% bÓ)Ð)Ü Ó"€EØÔ%Ò%Ü% bÓ)Ð)Ø�U�€IÜ	ñ Ü˜sÔ#Ü ×$Ñ$ YÓ/ˆØÐØ˜!‘9÷	ñ ð ÷ð
 €Hð8Ü™b›d›Ð%5ˆwˆñ <A”6Ô.¨rÓ2Ô3Àb€LÜ	ñ $Ü˜sÔ#ÙØ-0Ô 	Ñ*Ü×#Ñ# IÔ.Ø*-¨t¨ŒO˜IÑ&Ø÷$ð $ô (×+Ñ+¨IÓ6ˆ	ØÐ  S¨9¡_Ô7VÒ%Vä�N‰NðFä˜"“˜wÔ(GôIð ÷$ð $ñ0 ˜IÔ)<Ñ<ÀÔRlÑAlÜ&×*Ñ*¨9Ô5Ü�N‰Nð[ä˜"“˜w¨¯	©	°,Ó(?È(ð õ Tñ
 %-”&—.’.´&·+±+ˆCÙØOÔQZÐ[]ÓQ^Ð`gØ!õ#ð '*¨5 \Œ˜	Ñ"Ø÷I$ð $÷ñ ûô ò 8ð $)¨(°C˜ˆwŽûð	8ú÷$ð $ús>   Á'G6ÂH Â=8H Ã>A	H ÅBH Ç6H È	HÈHÈHÈ H)c                 óö   — 	 ddl m} t        |«      }t
        j                  «       D �ch c],  }|j                  | u sŒ|j                  |v sŒ!|j                  ’Œ. c}S # t        $ r t	        «       cY S w xY wc c}w )zNNames of ``_HERMES_CORE_TOOLS`` members whose registered ``check_fn`` is *fn*.r   )Ú_HERMES_CORE_TOOLS)	Útoolsetsrú   Ú	frozensetrs   ro   r*   Ú_snapshot_entriesrš   rb   )r¸   rú   Úcorer�   s       r   rï   rï   „  si   € ðÝ/ÜÐ+Ó,ˆô %×6Ñ6Ó8Ö`�q¸A¿J¹JÈ"Ò<LÐQR×QWÑQWÐ[_ÒQ_ˆA�F‹FÒ`Ð`øô ò Ü‹uŠðüâ`s!   ‚A ©A6½A6ÁA6ÁA3Á2A3Úmemoc                 ó0   — | |vrt        | «      || <   ||    S )zGPer-pass memo on top of the TTL cache: one probe per distinct check_fn.)rø   )r¸   rÿ   s     r   Ú_memo_checkr  Ž  s    € à	��~Ü# BÓ'ˆˆR‰Ø�‰8€Or   c                  óÚ   — t         5  t        j                  «        t        j                  «        t        j                  «        t
        j                  «        ddd«       y# 1 sw Y   yxY w)zYDrop all cached ``check_fn`` results (after config changes like ``hermes tools enable``).N)rî   r°   Úclearr±   r²   r³   r¨   r   r   Úinvalidate_check_fn_cacher  •  sJ   € ä	ñ +Ü×ÑÔÜ×!Ñ!Ô#Ü×!Ñ!Ô#Ü"×(Ñ(Ô*÷	+÷ +ñ +ús   ‡AA!Á!A*c                 óæ   — t        j                  «       }t        «       }|t        k(  ryt        5  t
        j                  | |f«      }ddd«       �||d   z
  t        k  r|d   S dS # 1 sw Y   Œ!xY w)z©Cached verdict for *fn* if its TTL is still valid, else None. NEVER runs the probe:
    for read-only surfaces (dashboard panels) that must not do network/auth/SDK work.Nr   rY   )rì   rí   rã   rß   rî   r°   r"   rÈ   )r¸   rÀ   rñ   r}   s       r   Úget_cached_check_fn_resultr  ž  su   € ô �.‰.Ó
€CÜ Ó"€EØÔ%Ò%àÜ	ñ 2Ü ×$Ñ$ b¨% [Ó1ˆ÷2àÐ*¨s°V¸A±Y©ÔAVÒ/Vˆ6�!‰9Ð`Ð\`Ð`÷2ð 2ús   ¯A'Á'A0c                   ó8  — e Zd ZdZd„ Zedefd„«       Zedee	   de
eee	   f   fd„«       Zddœd	ee   d
ede
ee	f   fd„Zdeddfd„ZdPd	ee   de
ee	f   fd„Zded	ee   dee	   fd„Z	 dPd	ee   deee	   e
eef   f   fd„Zdee	   fd„Zdedee	   defd„Zddœded	ee   dee	   fd„Zddœded	ee   dee	   fd„Zdee   fd„Zdee	   fd„Zdedee   fd„Zdededdfd„Zde
eef   fd„Zdedee   fd„Zddœded ed	ee   defd!„Z ddœded	ee   dee   fd"„Z!ddœded#ed$ee   d	ee   def
d%„Z"d	ee   dedefd&„Z#d'edee   fd(„Z$ed'edefd)„«       Z%dedee   fd*„Z&dedee   fd+„Z'dedee   fd,„Z(d-edee   fd.„Z)edefd/„«       Z*	 	 	 	 dQdeded0e+d'ed1ed2e,d3ed4ed5ed6e-e.z  dz  d7ed8ed	ee   fd9„Z/ddœded	ee   ddfd:„Z0ddœded#e	d$ee	   d	ee   def
d;„Z1dRd<e2e   d=edee+   fd>„Z3edefd?„«       Z4ddœded@e+d	ee   dee+z  fdA„Z5dedBefdC„Z6dPdedDe-e.z  dz  de-e.z  fdE„Z7dee   fdF„Z8dedee+   fdG„Z9dedee   fdH„Z:dSdedDedefdI„Z;de
eef   fdJ„Z<dedefdK„Z=de
eef   fdL„Z>de
ee+f   fdM„Z?de
ee+f   fdN„Z@dRd=efdO„ZAy)TÚToolRegistryzISingleton registry that collects tool schemas + handlers from tool files.c                 ó˜   — i | _         i | _        i | _        i | _        i | _        i | _        t        j                  «       | _        d| _	        y rÃ   )
Ú_toolsÚ_scoped_toolsÚ_plugin_override_policyÚ_plugin_module_scopesÚ_toolset_checksÚ_toolset_aliasesÚ	threadingÚRLockÚ_lockÚ_generation©r­   s    r   r®   zToolRegistry.__init__®  sK   € Ø,.ˆŒà>@ˆÔð `bˆÔ$ØDFˆÔ"Ø46ˆÔØ02ˆÔä—_‘_Ó&ˆŒ
à !ˆÕr   r   c                  ó   — t        «       S r=   r
   r¨   r   r   Úcurrent_scope_keyzToolRegistry.current_scope_key¾  s   € äÓ Ð r   Úentriesc                 ón   — i }| D ]-  }|j                  |j                  g «      j                  |«       Œ/ |S )z1``{toolset: entries}`` in first-appearance order.)Ú
setdefaultr—   rm   )r  ÚgroupsÚentrys      r   Ú_groupedzToolRegistry._groupedÂ  s<   € ð .0ˆØò 	?ˆEØ×Ñ˜eŸm™m¨RÓ0×7Ñ7¸Õ>ð	?àˆr   F©Úcreaterñ   r  c                ó’   — |€| j                   S |r| j                  j                  |i «      S | j                  j                  |i «      S )zPThe registration map for *scope*: global when None, else that profile's overlay.)r
  r  r  r"   )r­   rñ   r  s      r   Ú_slotzToolRegistry._slotÊ  sF   € àˆ=Ø—;‘;ÐÙØ×%Ñ%×0Ñ0°¸Ó;Ð;Ø×!Ñ!×%Ñ% e¨RÓ0Ð0r   r—   Nc                 ó‚   — | j                   j                  «       D ��ci c]  \  }}||k7  sŒ||“Œ c}}| _         y c c}}w r=   )r  rÊ   )r­   r—   ÚaliasÚtargets       r   Ú_drop_toolset_aliasesz"ToolRegistry._drop_toolset_aliasesÒ  sB   € à/3×/DÑ/D×/JÑ/JÓ/L÷!cÙ+˜e VÐPVÐZaÓPaˆE�6‰Mó!cˆÕùó !cs   ž;¬;c                 óz   — i | j                   ¥| j                  j                  |xs | j                  «       i «      ¥S )z=Return global tools overlaid with one profile's plugin tools.)r
  r  r"   r  )r­   rñ   s     r   Ú_merged_toolszToolRegistry._merged_toolsÖ  s8   € à_�$—+‘+Ð_ ×!3Ñ!3×!7Ñ!7¸Ò8YÀ×AWÑAWÓAYÐ[]Ó!^Ð_Ð_r   c                 ó~   — | j                  | j                  |«      j                  «       «      j                  |g «      S r=   )r  r&  Úvaluesr"   )r­   r—   rñ   s      r   Ú_toolset_entrieszToolRegistry._toolset_entriesÚ  s2   € Ø�}‰}˜T×/Ñ/°Ó6×=Ñ=Ó?Ó@×DÑDÀWÈbÓQÐQr   c                 óT  — | j                   5  t        | j                  |«      j                  «       «      }t	        | j
                  «      }|j                  |D �ci c]&  }|j                  €Œ|j                  |j                  “Œ( c}«       ||fcddd«       S c c}w # 1 sw Y   yxY w)zBReturn a coherent snapshot of registry entries and toolset checks.N)	r  rN   r&  r(  r!   r  Úupdaterš   r—   )r­   rñ   r  Úchecksr�   s        r   Ú_snapshot_statezToolRegistry._snapshot_stateÝ  s�   € ð �Z‰Zñ 	#Ü˜4×-Ñ-¨eÓ4×;Ñ;Ó=Ó>ˆGÜ˜$×.Ñ.Ó/ˆFØ�M‰M¸'Ö\°QÀQÇZÁZÑE[˜1Ÿ9™9 a§j¡jÑ0Ò\Ô]Ø˜F�?÷		#ñ 	#ùò ]÷	#ð 	#ús$   �ABÁB
Á,B
Â
BÂBÂB'c                 ó(   — | j                  «       d   S rÃ   )r-  r  s    r   rý   zToolRegistry._snapshot_entriesæ  s   € Ø×#Ñ#Ó% aÑ(Ð(r   c                 óH   ‡‡— i Šˆfd„|D «       }t        ˆfd„|D «       «      S )a  True when at least one tool in *toolset* would be exposed. Mirrors
        :meth:`get_definitions` per-tool filtering so doctor/banners agree with runtime:
        mixed toolsets (``terminal`` + desktop-only ``read_terminal``) must not be gated
        by the first ``check_fn``.c              3   óB   •K  — | ]  }|j                   ‰k(  sŒ|–— Œ y ­wr=   ©r—   ©r>   r�   r—   s     €r   r@   z<ToolRegistry._toolset_has_exposable_tools.<locals>.<genexpr>ï  s   øè ø€ Ò>˜¨¯©°gÓ)=”1Ñ>ùs   ƒ˜c              3   óh   •K  — | ])  }|j                    xs t        |j                   ‰«      –— Œ+ y ­wr=   )rš   r  )r>   r�   rÿ   s     €r   r@   z<ToolRegistry._toolset_has_exposable_tools.<locals>.<genexpr>ð  s*   øè ø€ ÒTÀq�q—z‘z�>ÒB¤[°·±¸TÓ%BÓBÑTùs   ƒ/2)rB   )r­   r—   r  Úmembersrÿ   s    `  @r   Ú_toolset_has_exposable_toolsz)ToolRegistry._toolset_has_exposable_toolsé  s%   ù€ ð
 &(ˆÛ>˜gÔ>ˆÜÓTÈGÔTÓTÐTr   ©rñ   rb   c                ó†   — | j                   5  | j                  |«      j                  |«      cddd«       S # 1 sw Y   yxY w)z7Active profile's entry by name, falling back to global.N)r  r&  r"   ©r­   rb   rñ   s      r   Ú	get_entryzToolRegistry.get_entryò  s7   € à�Z‰Zñ 	7Ø×%Ñ% eÓ,×0Ñ0°Ó6÷	7÷ 	7ò 	7úó	   � 7·A c                ó†   — | j                   5  | j                  |«      j                  |«      cddd«       S # 1 sw Y   yxY w)u-   Local slot state only â€” no global fallback.N)r  r   r"   r8  s      r   Úsnapshot_registrationz"ToolRegistry.snapshot_registration÷  s7   € ð �Z‰Zñ 	/Ø—:‘:˜eÓ$×(Ñ(¨Ó.÷	/÷ 	/ò 	/úr:  c                 óR   — t        | j                  | j                  «       «      «      S r=   )rP   r  rý   r  s    r   Úget_registered_toolset_namesz)ToolRegistry.get_registered_toolset_namesý  s   € Ü�d—m‘m D×$:Ñ$:Ó$<Ó=Ó>Ð>r   c                 ó"   — | j                  «       S r=   )rý   r  s    r   Úget_all_entrieszToolRegistry.get_all_entries   s   € Ø×%Ñ%Ó'Ð'r   c                 ó€   — t        d„ | j                  | j                  «       «      j                  |g «      D «       «      S )Nc              3   ó4   K  — | ]  }|j                   –— Œ y ­wr=   ©rb   )r>   r�   s     r   r@   z:ToolRegistry.get_tool_names_for_toolset.<locals>.<genexpr>  s   è ø€ Ò_ �a—f•fÑ_ùó   ‚)rP   r  rý   r"   ©r­   r—   s     r   Úget_tool_names_for_toolsetz'ToolRegistry.get_tool_names_for_toolset  s4   € ÜÑ_ d§m¡m°D×4JÑ4JÓ4LÓ&M×&QÑ&QÐRYÐ[]Ó&^Ô_Ó_Ð_r   r"  c                 ó  — | j                   5  | j                  j                  |«      }|r||k7  rt        j	                  d|||«       || j                  |<   | xj
                  dz  c_        ddd«       y# 1 sw Y   yxY w)z8Register an explicit alias for a canonical toolset name.z4Toolset alias collision: '%s' (%s) overwritten by %srY   N)r  r  r"   r   rg   r  )r­   r"  r—   Úexistings       r   Úregister_toolset_aliasz#ToolRegistry.register_toolset_alias  sx   € à�Z‰Zñ 	"Ø×,Ñ,×0Ñ0°Ó7ˆHÙ˜H¨Ò/Ü—‘ØJÈEÐS[Ð]dôð ,3ˆD×!Ñ! %Ñ(Ø×Ò Ñ!Õ÷	"÷ 	"ñ 	"ús   �AA5Á5A>c                 óp   — | j                   5  t        | j                  «      cd d d «       S # 1 sw Y   y xY wr=   )r  r!   r  r  s    r   Úget_registered_toolset_aliasesz+ToolRegistry.get_registered_toolset_aliases  s,   € Ø�Z‰Zñ 	/Ü˜×-Ñ-Ó.÷	/÷ 	/ò 	/ús   �,¬5c                 ó|   — | j                   5  | j                  j                  |«      cd d d «       S # 1 sw Y   y xY wr=   )r  r  r"   )r­   r"  s     r   Úget_toolset_alias_targetz%ToolRegistry.get_toolset_alias_target  s2   € Ø�Z‰Zñ 	4Ø×(Ñ(×,Ñ,¨UÓ3÷	4÷ 	4ò 	4ús   �2²;Úmodule_namespacer«   c                óè   — | j                   5  t        |«      }|| j                  ||f<   | j                  j	                  |t        «       «      j                  |«       |cddd«       S # 1 sw Y   yxY w)z®Bind a plugin module namespace to its current operator opt-in. The identity-bearing
        result lets unload/reload revoke a stale authorization without losing attribution.N)r  rª   r  r  r  ro   rº   )r­   rN  r«   rñ   Úpolicys        r   Úregister_plugin_override_policyz,ToolRegistry.register_plugin_override_policy  sg   € ð
 �Z‰Zñ 	Ü*¨7Ó3ˆFØFLˆD×(Ñ(¨%Ð1AÐ)BÑCØ×&Ñ&×1Ñ1Ð2BÄCÃEÓJ×NÑNÈuÔUØ÷		÷ 	ò 	ús   �AA(Á(A1c                ó€   — | j                   5  | j                  j                  ||f«      cddd«       S # 1 sw Y   yxY w)z;Return one local authorization generation without fallback.N)r  r  r"   )r­   rN  rñ   s      r   Úsnapshot_plugin_override_policyz,ToolRegistry.snapshot_plugin_override_policy&  s>   € ð �Z‰Zñ 	OØ×/Ñ/×3Ñ3°UÐ<LÐ4MÓN÷	O÷ 	Oò 	Oús   �4´=ÚcurrentÚpreviousc                óú   — | j                   5  ||f}| j                  j                  |«      |ur
	 ddd«       y|€| j                  j                  |d«       n|| j                  |<   	 ddd«       y# 1 sw Y   yxY w)zCCAS-restore policy state while retaining durable scope attribution.NFT)r  r  r"   rË   )r­   rN  rT  rU  rñ   rÑ   s         r   Úrestore_plugin_override_policyz+ToolRegistry.restore_plugin_override_policy-  s‚   € ð �Z‰Zñ 	ØÐ*Ð+ˆCØ×+Ñ+×/Ñ/°Ó4¸GÑCØ÷	ð 	ð ÐØ×,Ñ,×0Ñ0°°dÕ;à4<�×,Ñ,¨SÑ1Ø÷	÷ 	ñ 	ús   �#A1¹/A1Á1A:c                 ó°   — | j                   j                  ||f«      }|€|�| j                   j                  d |f«      }t        |xr |j                  «      S r=   )r  r"   rl   r«   )r­   rñ   rN  rP  s       r   Ú_plugin_override_allowedz%ToolRegistry._plugin_override_allowed;  sX   € Ø×-Ñ-×1Ñ1°5Ð:JÐ2KÓLˆØˆ>˜eÐ/Ø×1Ñ1×5Ñ5°tÐ=MÐ6NÓOˆFÜ�FÒ-˜vŸ~™~Ó.Ð.r   r™   c                 óN   — | j                  |«      }|r| j                  |«      S dS )a9  Plugin namespace that DEFINED *handler* (None for built-in/MCP handlers). Bound to
        ``handler.__globals__["__name__"]``, fixed at definition time so it cannot drift with
        call site/thread/timing; lambdas and nested functions inherit it, so a plugin cannot
        launder an override via a callback.N)Ú_callable_moduleÚ_plugin_namespace_of_module)r­   r™   Úmods      r   Ú_plugin_owner_ofzToolRegistry._plugin_owner_ofA  s,   € ð
 ×#Ñ# GÓ,ˆÙ8;ˆt×/Ñ/°Ó4ÐEÀÐEr   c                 ó  — | }t        «       }t        |«      |vrÁ|j                  t        |«      «       t        |dd«      }t	        |t
        j                  «      r|j                  }net        |dd«      �|j                  }nKt	        |t        «      r |j                  dd«      rt        |d   «      S t        |dd«      �|j                  }nnt        |«      |vrŒÁt        |dd«      }t        |xs t        t        |«      dd«      xs d«      S )z@Resolve defining module through wrappers, partials, and objects.Ú__globals__NÚ__func__r¡   rX   Ú__wrapped__r¢   )ro   r3   rº   r¾   r    Ú	functoolsÚpartialr/   ra  r!   r"   r#   rb  Útype)r™   rT  ÚseenÚglobals_dictÚmodule_names        r   r[  zToolRegistry._callable_moduleI  sô   € ð ˆÜ›ˆÜ�‹k Ñ%Ø�H‰H”R˜“[Ô!Ü" 7¨M¸4Ó@ˆLÜ˜'¤9×#4Ñ#4Ô5Ø!Ÿ,™,‘Ü˜ *¨dÓ3Ð?Ø!×*Ñ*‘Ü˜L¬$Ô/°L×4DÑ4DÀZÐQSÔ4TÜ˜<¨
Ñ3Ó4Ð4Ü˜ -°Ó6ÐBØ!×-Ñ-‘àô �‹k Ò%ô ˜g |°RÓ8ˆÜ�;ÒP¤'¬$¨w«-¸ÀrÓ"JÒPÈbÓQÐQr   c                 óV  — | j                   5  | j                  D �cg c]  }||k(  s|j                  |› d�«      r|‘Œ }}|rt        |t        ¬«      cddd«       S 	 ddd«       |j                  d«      r#dj                  |j                  d«      dd «      S yc c}w # 1 sw Y   ŒCxY w)z;Resolve a module/submodule to its durable plugin namespace.r\   )rÑ   Nzhermes_plugins.r[   )r  r  Ú
startswithÚmaxr   rn   Úsplit)r­   rN  Ú	namespaceÚmatchess       r   r\  z(ToolRegistry._plugin_namespace_of_module^  s¾   € à�Z‰Zñ 	-à+/×+EÑ+EöbØ'Ø# yÒ0Ð4D×4OÑ4OÐS\ÐR]Ð]^ÐP_Ô4`ò ðbˆGð bñ Ü˜7¬Ô,÷	-ñ 	-ð ÷		-ð ×&Ñ&Ð'8Ô9Ø—8‘8Ð,×2Ñ2°3Ó7¸¸Ð;Ó<Ð<Øùòb÷	-ð 	-ús   �Bœ"B¾BÂBÂB(c                 ó4  — | j                   5  | j                  j                  |«      }|s
	 ddd«       y| j                  «       }||v r|cddd«       S t	        |«      dk(  rt        t        |«      «      cddd«       S t        d|›d�«      ‚# 1 sw Y   yxY w)z9Return the profile scope bound to a loaded plugin module.NrY   úPlugin module zP is active in multiple profiles and cannot register outside one of those scopes.)r  r  r"   r  r   rÍ   rÎ   ÚPermissionError)r­   rN  ÚscopesÚactive_scopes       r   Ú_plugin_scope_ofzToolRegistry._plugin_scope_ofl  s«   € à�Z‰Zñ 	9Ø×/Ñ/×3Ñ3Ð4DÓEˆFÙØ÷	9ð 	9ð  ×1Ñ1Ó3ˆLØ˜vÑ%Ø#÷	9ñ 	9ô �6‹{˜aÒÜœD ›LÓ)÷	9ñ 	9ô "Ø Ð!1Ð 4ð 58ð 8ó9ð 9÷	9ð 	9ús   �BµBÁ!BÁ?BÂBc                 óN   — | j                  |«      }| j                  |xs |«      S )z@Public host lookup for a loaded plugin module's immutable scope.)r\  rt  )r­   rN  Úowners      r   Úplugin_scope_for_modulez$ToolRegistry.plugin_scope_for_module{  s*   € à×0Ñ0Ð1AÓBˆØ×$Ñ$ UÒ%>Ð.>Ó?Ð?r   Úcallbackc                 óN   — | j                  |«      }|r| j                  |«      S dS )zAReturn the durable plugin scope for any supported callable shape.N)r[  rw  )r­   rx  rh  s      r   Úplugin_scope_for_callablez&ToolRegistry.plugin_scope_for_callable€  s*   € à×+Ñ+¨HÓ5ˆÙ<Gˆt×+Ñ+¨KÓ8ÐQÈTÐQr   c                  óˆ   — 	 t        j                  d«      j                  j                  dd«      xs dS # t        $ r Y yw xY w)uç   Best-effort module name of the registry method's caller (two frames up).
        ``deregister()`` takes only a tool name â€” no handler for ``_plugin_owner_of`` â€”
        so frame inspection is the only way to know who is asking.r[   r¡   rX   )ÚsysÚ	_getframeÚ	f_globalsr"   rs   r¨   r   r   Ú_caller_modulezToolRegistry._caller_module…  s@   € ð
	Ü—=‘= Ó#×-Ñ-×1Ñ1°*¸bÓAÒGÀRÐGøÜò 	Ùð	ús   ‚25 µ	AÁ Ar˜   rš   r›   rœ   r�   rž   rŸ   r    râ   c                 ón  — t        |t        «      s$t        d|›dt        |«      j                  › �«      ‚|j                  d«      }|�4t        |t        «      s$t        d|›dt        |«      j                  › �«      ‚| j                  |«      }| j                  | j                  «       «      }|xs |}|€|�| j                  |«      }| j                  5  | j                  |d¬«      }|€| j                  n| j                  |«      j                  |«      }|duxr | j                  ||«       }|duxr |duxr ||vxr || j                  v }|rE|s!t        j!                  d||«       	 ddd«       y|r t#        t$        j'                  ||¬	«      «      ‚|r¤|j(                  |k7  r•|rg|rBt        j!                  d
|||j(                  «       t#        t$        j'                  ||¬	«      «      ‚t        j+                  d|||j(                  «       n,t        j!                  d|||j(                  «       	 ddd«       yt-        ||||||xs g ||xs |j                  dd«      |	|
|¬«      ||<   |€|r|| j.                  vr|| j.                  |<   | xj0                  dz  c_        ddd«       y# 1 sw Y   yxY w)zûRegister a tool (called at import time by each tool file). ``override=True`` is an
        explicit opt-in for plugins replacing a built-in implementation (e.g. a headed-Chrome
        browser backend); without it, cross-toolset shadowing is rejected.zTool z: schema must be a dict, got Ú
parametersNzA: schema['parameters'] must be an object (JSON Schema dict), got Tr  z^Tool registration REJECTED: plugin %r attempted to shadow global tool %r without override=True)rv  rb   zÑTool registration REJECTED: plugin %r attempted to override built-in tool %r (existing toolset %r) without operator opt-in. Set plugins.entries.<plugin_id>.allow_tool_override: true in config.yaml to allow it.zOTool '%s': toolset '%s' overriding existing toolset '%s' (override=True opt-in)zÈTool registration REJECTED: '%s' (toolset '%s') would shadow existing tool from toolset '%s'. Pass override=True to register() if the replacement is intentional, or deregister the existing tool first.r�   rX   )rb   r—   r˜   r™   rš   r›   rœ   r�   rž   rŸ   r    rY   )r    r!   r   re  r¡   r"   r^  r\  r  rt  r  r   r
  r&  rY  r   r   rq  Ú_OVERRIDE_DENIED_MSGÚformatr—   rð   r–   r  r  )r­   rb   r—   r˜   r™   rš   r›   rœ   r�   rž   rŸ   r    râ   rñ   ÚparamsÚhandler_ownerÚcaller_ownerrv  r#  rH  Úplugin_override_deniedÚshadows_globals                         r   r)   zToolRegistry.register�  sõ  € ô ˜&¤$Ô'ÜØ˜�xÐ<¼TÀ&»\×=RÑ=RÐ<SÐTóVð Và—‘˜LÓ)ˆØÐ¤j°¼Ô&>ÜØ˜�xð  Ü˜F“|×,Ñ,Ð-ð/ó0ð 0ð ×-Ñ-¨gÓ6ˆØ×7Ñ7¸×8KÑ8KÓ8MÓNˆØÒ- ˆØˆ=˜UÐ.Ø×)Ñ)¨%Ó0ˆEØ�Z‰Zñ 3	"Ø—Z‘Z ¨d�ZÓ3ˆFØ', }˜Ÿš¸$×:LÑ:LÈUÓ:S×XÑXÐY]Ó^ˆHà˜TÐ!ÒU¨$×*GÑ*GÈÈuÓ*UÐ&Uð #ð ˜TÐ!ò ? e°4Ð&7ò ?Ø Ð&ò?Ø+/°4·;±;Ð+>ð ñ ÙÜ—L‘Lð0Ø16¸ô>ð ÷3	"ð 3	"ñ *Ü)Ô*>×*EÑ*EÈEÐX\Ð*EÓ*]Ó^Ð^Ù˜H×,Ñ,°Ò7ÙÙ-ÜŸ™ð+ð " 4¨×)9Ñ)9ô;ô .Ô.B×.IÑ.IÐPUÐ\`Ð.IÓ.aÓbÐbä—K‘Kð1Ø26¸À×AQÑAQõSô —L‘Lð]ð ˜g x×'7Ñ'7ô	9ð
 ÷M3	"ð 3	"ôN %Ø 7°6À7ÐU]Ø)Ò/¨R¸(Ø'ÒH¨6¯:©:°mÀRÓ+HÐPUØ&;Ø)AôCˆF�4‰Lð ˆ}¡¨g¸T×=QÑ=QÑ.QØ08�×$Ñ$ WÑ-Ø×Ò Ñ!Õ÷g3	"÷ 3	"ñ 3	"ús   ÃBJ+Å3B?J+È;A'J+Ê+J4c          
      ó$  — | j                   5  | j                  «       }| j                  |«      }|�| j                  |«      nd}|�|�||k7  rt	        d|›d�«      ‚|€|}| j                  |«      }|j                  |«      }|€.|�"|� || j                  v rt	        d|›d|›d�«      ‚	 ddd«       y|j                  j                  d«      s…| j                  |j                  «      }t        |xr ||k(  «      }	|�V|	sT| j                  ||«      sBt        j                  d|||j                  |«       t	        d|›d	|›d
|j                  ›d�«      ‚||= |�|s| j                   j#                  |d«       | j%                  |j                  |«      sA| j&                  j#                  |j                  d«       | j)                  |j                  «       | xj*                  dz  c_        ddd«       t        j-                  d|«       y# 1 sw Y   Œ xY w)uf  Remove a tool; drops the toolset check/aliases if it was the last in its toolset.

        ``scope`` selects a profile overlay explicitly (multiplexed MCP tools live in the
        owning profile's overlay); plugin callers may not name another scope, non-plugin
        callers default to the process-global map. Gated by the same opt-in as
        ``register(override=True)``, else a plugin could deregister a tool it doesn't own
        and re-register over the empty slot (the override check only runs when an entry
        exists). ``mcp-*`` toolsets are exempt â€” discovery repaves its own tools per refresh.Nrp  z7 cannot deregister tools outside its own profile scope.zScoped plugin module z' cannot deregister process-global tool z%; register a scoped override instead.zmcp-zÇTool deregistration REJECTED: plugin %r attempted to remove tool %r (toolset %r) it does not own, without operator opt-in. Set plugins.entries.%s.allow_tool_override: true in config.yaml to allow it.z cannot deregister tool z
 (toolset z0) without operator opt-in (allow_tool_override).rY   zDeregistered tool: %s)r  r  r\  rt  rq  r   r"   r
  r—   rj  r^  r™   rl   rY  r   r   r  rË   r)  r  r$  r  r   )
r­   rb   rñ   Ú
caller_modr†  Úcaller_scoper#  r  rv  Úsame_plugins
             r   Ú
deregisterzToolRegistry.deregisterÝ  s;  € ð �Z‰Zñ -	"Ø×,Ñ,Ó.ˆJØ×;Ñ;¸JÓGˆLØBNÐBZ˜4×0Ñ0°Ô>Ð`dˆLØÐ'¨EÐ,=À%È<ÒBWÜ%Ø$ Z Nð 35ð 5ó6ð 6ð ˆ}Ø$�Ø—Z‘Z Ó&ˆFØ—J‘J˜tÓ$ˆEØˆ}ØÐ$¨Ð)AÀdÈdÏkÉkÑFYÜ)Ø/°
¨~ð > Ø $˜xÐ'LðNóOð Oð ÷#-	"ð -	"ð$ —=‘=×+Ñ+¨FÔ3Ø×-Ñ-¨e¯m©mÓ<�ô # 5Ò#B¨\¸UÑ-BÓC�à Ð,Ù'Ø ×9Ñ9¸,ÈÔUÜ—L‘Lðcð # D¨%¯-©-¸ô	Eô
 *Ø(¨¨Ð6NÈtÈhÐV`Ø Ÿ=™=Ð+Ð+[ð]ó^ð ^ð �t�ØÐ ©Ø×"Ñ"×&Ñ& u¨dÔ3Ø×(Ñ(¨¯©¸Ô>Ø×$Ñ$×(Ñ(¨¯©¸Ô=Ø×*Ñ*¨5¯=©=Ô9Ø×Ò Ñ!Õ÷[-	"ô\ 	�‰Ð,¨dÕ3÷]-	"ð -	"ús   �BHÂ2D5HÈHc                ó  ‡
— | j                   5  | j                  |d¬«      }|j                  |«      |ur
	 ddd«       y|€|j                  |d«       n|||<   |�|s| j                  j                  |d«       |j
                  h}|�|j                  |j
                  «       |D ]¡  Š
| j                  ‰
|«      }t        d„ |D «       d«      }|€.|€| j                  j                  ‰
d«       n|| j                  ‰
<   d„ | j                  j                  «       D «       }	|rŒ|t        ˆ
fd„|	D «       «      rŒ‘| j                  ‰
«       Œ£ | xj                  dz  c_        ddd«       t        j                  d	|«       y# 1 sw Y   Œ xY w)
aC  Restore a host-owned registration if it is still current (plugin ownership ledger).
        The identity check is deliberate: another plugin (or ``PluginManager`` in a
        multi-profile process) may have registered a newer entry under the same name, and
        unloading this entry must leave that newer one untouched.Tr  NFc              3   óN   K  — | ]  }|j                   sŒ|j                   –— Œ y ­wr=   )rš   ©r>   r  s     r   r@   z4ToolRegistry.restore_registration.<locals>.<genexpr>/  s   è ø€ Ò Y°EÈ%Ï.Ë. §¥Ñ Yùs   ‚%”%c              3   óJ   K  — | ]  }|j                  «       D ]  }|–— Œ Œ y ­wr=   )r(  )r>   Úmr�   s      r   r@   z4ToolRegistry.restore_registration.<locals>.<genexpr>5  s"   è ø€ ÒZ QÈqÏxÉxËzÒZÈ!œqÐZ˜qÑZùs   ‚!#c              3   ó<   •K  — | ]  }|j                   ‰k(  –— Œ y ­wr=   r1  r2  s     €r   r@   z4ToolRegistry.restore_registration.<locals>.<genexpr>6  s   øè ø€ Ò,WÀa¨Q¯Y©Y¸'Õ-AÑ,Wùs   ƒrY   zRestored tool registration: %s)r  r   r"   rË   r  r—   rº   r)  rÍ   r  r(  rB   r$  r  r   r   )r­   rb   rT  rU  rñ   r#  Úaffected_toolsetsÚ	survivingrš   Úin_overlaysr—   s             @r   Úrestore_registrationz!ToolRegistry.restore_registration  sz  ø€ ð �Z‰Zñ 	"Ø—Z‘Z ¨d�ZÓ3ˆFØ�z‰z˜$Ó wÑ.Ø÷	"ð 	"ð ÐØ—
‘
˜4 Õ&à'��t‘ØÐ ©Ø×"Ñ"×&Ñ& u¨dÔ3ð ")§¡Ð 1ÐØÐ#Ø!×%Ñ% h×&6Ñ&6Ô7Ø,ò 
8�Ø ×1Ñ1°'¸5ÓA�	ÜÑ Y¸YÔ YÐ[_Ó`�Ø�=ØÐ'Ø×,Ñ,×0Ñ0°¸$Õ?à8@˜×,Ñ,¨WÑ5ÙZ¨$×*<Ñ*<×*CÑ*CÓ*EÔZ�Ú ¬Ó,WÈ;Ô,WÕ)WØ×.Ñ.¨wÕ7ð
8ð ×Ò Ñ!Õ÷7	"ô8 	�‰Ð5°tÔ<Ø÷;	"ð 	"ús   Ž(E=¿C!E=Ä!E=Ä6(E=Å=FÚ
tool_namesÚquietc                 ó`  — g }i }| j                  «       D �ci c]  }|j                  |“Œ }}t        |«      D ]¿  }|j                  |«      }|sŒ|j                  r/t        |j                  |«      s|st        j                  d|«       ŒRi |j                  ¥d|j                  i¥}|j                  �2	 |j                  «       }	t        |	t        «      r|j                  |	«       |j                  d|dœ«       ŒÁ |S c c}w # t        $ r#}
d}	t        j                  d||
«       Y d}
~
Œed}
~
ww xY w)z¨OpenAI-format schemas for the requested tools whose ``check_fn`` passes (or is
        absent). Probes use the ~30 s TTL cache so ``hermes tools enable`` lands quickly.z"Tool %s unavailable (check failed)rb   NzCdynamic_schema_overrides for tool %s raised %s; using static schemaÚfunction)re  r›  )rý   rb   rP   r"   rš   r  r   r   r˜   r    rs   rg   r    r!   r+  rm   )r­   r˜  r™  r   Úcheck_resultsr  Úentries_by_namerb   Úschema_with_nameÚ	overridesrô   s              r   Úget_definitionszToolRegistry.get_definitions>  s,  € ð ˆØ.0ˆØ:>×:PÑ:PÓ:RÖS°˜5Ÿ:™: uÑ,ÐSˆÐSÜ˜:Ó&ò 	NˆDØ#×'Ñ'¨Ó-ˆEÙØØ�~Š~¤k°%·.±.À-Ô&PÙÜ—L‘LÐ!EÀtÔLØØC %§,¡,ÐC°¸¿
¹
ÑCÐð ×-Ñ-Ð9ð#Ø %× >Ñ >Ó @�Iô ˜i¬Ô.Ø$×+Ñ+¨IÔ6Ø�M‰M :Ð;KÑLÕMð+	Nð, ˆùò/ Tøô !ò #Ø $�IÜ—N‘NØ]Ø˜c÷#ñ #ûð#ús   —C<Â3DÄ	D-Ä
D(Ä(D-c                 ó<  — t        |t        «      rt        |«      S t        |t        «      r4|j	                  d«      du r!t        |j	                  d«      t
        «      r|S t        |«      j                  }t        j                  d| |«       t        d|› �d| |¬«      S )zÀResults must be a string or the multimodal envelope; anything else becomes a
        string error so logging/hooks/budgeting/persistence never receive values they
        cannot slice or size.Ú_multimodalTÚcontentz4Tool %s handler returned unsupported result type: %sz/Tool handler returned unsupported result type: Útool_result_contract)Ú
error_typeÚtoolÚresult_type)r    r#   r&   r!   r"   rN   re  r¡   r   r   Ú
tool_error)rb   r   r§  s      r   Ú_normalize_handler_resultz&ToolRegistry._normalize_handler_result^  s�   € ô
 �fœcÔ"Ü+¨FÓ3Ð3ä�vœtÔ$Ø—
‘
˜=Ó)¨TÑ1Ü˜6Ÿ:™: iÓ0´$Ô7ØˆMÜ˜6“l×+Ñ+ˆÜ�‰ÐKÈTÐS^Ô_ÜØ=¸k¸]ÐKØ-°DÀkôSð 	Sr   Úargsc          
      ó$  — | j                  ||¬«      }|st        d|› �«      S 	 t        |j                  |«      }|j                  r ddlm}  | |j                  |fi |¤Ž«      }n |j                  |fi |¤Ž}| j                  ||«      S # t        $ rz}t        j                  d|t        t        |«      «      «       dt        |«      j                  › d|› �}		 ddlm}
  |
|	«      }n# t        $ r |	}Y nw xY wt        |«      cY d	}~S d	}~ww xY w)
z˜Execute a tool handler by name: async handlers bridged via ``_run_async()``,
        results normalized, every exception returned as ``{"error": ...}``.r6  zUnknown tool: r   )Ú
_run_asynczTool %s dispatch error: %szTool execution failed: z: )Ú_sanitize_tool_errorN)r9  r¨  Ú_kwargs_accepted_byr™   rœ   Úmodel_toolsr¬  r©  rs   r   Ú	exceptionr   r#   re  r¡   r­  )r­   rb   rª  rñ   Úkwargsr  r¬  r   r�   Úrawr­  Ú	sanitizeds               r   ÚdispatchzToolRegistry.dispatchp  s  € ð —‘˜t¨5�Ó1ˆÙÜ ¨t¨fÐ5Ó6Ð6ð	)ô )¨¯©¸Ó?ˆFØ�~Š~Ý2Ù# M E§M¡M°$Ñ$A¸&Ñ$AÓB‘à&˜Ÿ™ tÑ6¨vÑ6�Ø×1Ñ1°$¸Ó?Ð?øÜò 
	)ä×ÑÐ9¸4ÔARÔSVÐWXÓSYÓAZÔ[à+¬D°«G×,<Ñ,<Ð+=¸RÀ¸sÐCˆCð Ý<Ù0°Ó5‘	øÜò  Ø’	ð úä˜iÓ(Õ(ûð
	)úsC   ¥A&B Â	DÂAD
ÃC)Ã(D
Ã)C7Ã4D
Ã6C7Ã7D
ÄDÄ
Dr1   c                 ó:   — t        | j                  |«      |d «      S r=   )r¾   r9  )r­   rb   r1   s      r   Ú_attrzToolRegistry._attr�  s   € Ü�t—~‘~ dÓ+¨T°4Ó8Ð8r   Údefaultc                 óF   — | j                  |d«      }|�|S |�|S ddlm} |S )zBReturn per-tool max result size, or *default* (or global default).rŸ   r   )ÚDEFAULT_RESULT_SIZE_CHARS)r¶  Útools.budget_configr¹  )r­   rb   r·  Úsizer¹  s        r   Úget_max_result_sizez ToolRegistry.get_max_result_size“  s2   € à�z‰z˜$Ð 7Ó8ˆØÐØˆKØÐØˆNÝAØ(Ð(r   c                 óB   — t        d„ | j                  «       D «       «      S )Nc              3   ó4   K  — | ]  }|j                   –— Œ y ­wr=   rC  r�  s     r   r@   z2ToolRegistry.get_all_tool_names.<locals>.<genexpr>ž  s   è ø€ ÒG U�e—j•jÑGùrD  )rP   rý   r  s    r   Úget_all_tool_nameszToolRegistry.get_all_tool_names�  s   € ÜÑG¨d×.DÑ.DÓ.FÔGÓGÐGr   c                 ó&   — | j                  |d«      S )zORaw schema dict, bypassing check_fn filtering (token estimates, introspection).r˜   ©r¶  ©r­   rb   s     r   Ú
get_schemazToolRegistry.get_schema   s   € à�z‰z˜$ Ó)Ð)r   c                 ó&   — | j                  |d«      S )Nr—   rÁ  rÂ  s     r   Úget_toolset_for_toolz!ToolRegistry.get_toolset_for_tool¤  s   € Ø�z‰z˜$ 	Ó*Ð*r   c                 ó.   — | j                  |d«      xs |S )z3Return the emoji for a tool, or *default* if unset.rž   rÁ  )r­   rb   r·  s      r   Ú	get_emojizToolRegistry.get_emoji§  s   € à�z‰z˜$ Ó(Ò3¨GÐ3r   c                 ór   — | j                  «       D �ci c]  }|j                  |j                  “Œ c}S c c}w r=   )rý   rb   r—   )r­   r  s     r   Úget_tool_to_toolset_mapz$ToolRegistry.get_tool_to_toolset_map«  s,   € Ø7;×7MÑ7MÓ7OÖP¨e�—
‘
˜EŸM™MÑ)ÒPÐPùÒPs   “4c                 óB   — | j                  || j                  «       «      S )zCTrue when a toolset has at least one exposable tool (never raises).)r5  rý   rE  s     r   Úis_toolset_availablez!ToolRegistry.is_toolset_available®  s   € à×0Ñ0°¸$×:PÑ:PÓ:RÓSÐSr   c                 óž   — | j                  «       }t        | j                  |«      «      D �ci c]  }|| j                  ||«      “Œ c}S c c}w r=   )rý   rP   r  r5  )r­   r  r—   s      r   Úcheck_toolset_requirementsz'ToolRegistry.check_toolset_requirements³  sR   € Ø×(Ñ(Ó*ˆô " $§-¡-°Ó"8Ó9ö;àð �T×6Ñ6°wÀÓHÑHò;ð 	;ùò ;s   ­A
c                 óø   — | j                  «       }i }| j                  |«      j                  «       D ]@  \  }}| j                  ||«      |D �cg c]  }|j                  ‘Œ c}dt        |«      dœ||<   ŒB |S c c}w )z'Return toolset metadata for UI display.rX   )Ú	availabler]   r�   Úrequirements)rý   r  rÊ   r5  rb   Ú_unique_env)r­   r  rû   r—   r4  r  s         r   Úget_available_toolsetsz#ToolRegistry.get_available_toolsets¹  s€   € à×(Ñ(Ó*ˆØ$&ˆØ $§¡¨gÓ 6× <Ñ <Ó >ò 	6ÑˆG�Wà!×>Ñ>¸wÈÓPØ29Ö:¨˜%Ÿ*›*Ò:Ø!Ü +¨GÓ 4ñ	!6ˆH�WÒð	6ð ˆùò ;s   ÁA7c           	      óþ   — | j                  «       \  }}i }| j                  |«      j                  «       D ]@  \  }}|t        |«      |j	                  |«      d|D �cg c]  }|j
                  ‘Œ c}dœ||<   ŒB |S c c}w )zABuild a TOOLSET_REQUIREMENTS-compatible dict for backward compat.N)rb   Úenv_varsrš   Ú	setup_urlr]   )r-  r  rÊ   rÑ  r"   rb   )r­   r  Útoolset_checksr   r—   r4  r  s          r   Úget_toolset_requirementsz%ToolRegistry.get_toolset_requirementsÅ  s…   € à"&×"6Ñ"6Ó"8Ñˆ�Ø"$ˆØ $§¡¨gÓ 6× <Ñ <Ó >ò 	<ÑˆG�WàÜ'¨Ó0Ø*×.Ñ.¨wÓ7Ø!Ø29Ö:¨˜%Ÿ*›*Ò:ñ<ˆF�7ŠOð	<ð ˆùò ;s   ÁA:c           	      óF  — g g }}| j                  «       }| j                  |«      }t        |«      D ]f  }| j                  ||«      r|j	                  |«       Œ'|j	                  |||   d   j
                  ||   D �cg c]  }|j                  ‘Œ c}dœ«       Œh ||fS c c}w )zDReturn (available_toolsets, unavailable_info) like the old function.r   )rb   rÔ  r]   )rý   r  rP   r5  rm   r›   rb   )r­   r™  rÏ  Úunavailabler  r  Útsr  s           r   Úcheck_tool_availabilityz$ToolRegistry.check_tool_availabilityÒ  s«   € à!# R�;ˆ	Ø×(Ñ(Ó*ˆØ—‘˜wÓ'ˆÜ˜“.ò 	DˆBØ×0Ñ0°°WÔ=Ø× Ñ  Õ$à×"Ñ"Ø¨F°2©J°q©M×,FÑ,FØ6<¸R±jÖA¨U˜eŸj›jÒAñ$Cõ Dð		Dð ˜+Ð%Ð%ùò Bs   Á<Br=   )	NNFrX   rX   NNFN)F)u   âš¡)Br¡   r¢   r£   r¤   r®   Ústaticmethodr#   r  r   r–   r   r  r   rl   r   r$  r&  r)  rk   r   r-  rý   r5  r9  r<  r>  r@  rF  rI  rK  rM  rª   rQ  rS  rW  rY  r^  r[  r\  rt  rw  rz  r  r!   rN   r¦   r§   r)   r�  r—  r	   r   r©  r´  r¶  r¼  r¿  rÃ  rÅ  rÇ  rÉ  rË  rÍ  rÒ  r×  rÛ  r¨   r   r   r  r  «  s+  „ ÙSò"ð  ð!˜sò !ó ð!ð ð˜$˜y™/ð ¨d°3¸¸Y¹Ð3GÑ.Hò ó ðð =Bò 1˜8 C™=ð 1°Tð 1ÀdÈ3ÐPYÈ>ÑFZó 1ðc¨Sð c°Tó cñ` 8¨C¡=ð `¸DÀÀiÀÑ<Pó `ðR¨ð R°H¸S±Mð RÀdÈ9Áoó Rð &*ñ#Ø˜c‘]ð#Ø.3°D¸±OÀTÈ#ÈxÈ-ÑEXÐ4XÑ.Yó#ð) 4¨	¡?ó )ðU°Cð UÀ$ÀyÁ/ð UÐVZó Uð >Bò 7˜cð 7¨X°c©]ð 7ÀhÈyÑFYó 7ð 48ò/Øð/Ø#+¨C¡=ð/Ø<DÀYÑ<Oó/ð?¨d°3©ió ?ð(  i¡ó (ð`°#ð `¸$¸s¹)ó `ð	"¨Cð 	"¸#ð 	"À$ó 	"ð/°°S¸#°X±ó /ð4¨cð 4°h¸s±mó 4ð OSò	Ø #ð	Ø.2ð	Ø>FÀs¹mð	à	ó	ð @DòOØ #ðOØ/7¸©}ðOà	Ð'Ñ	(óOð NRòØ #ðØ.CðàÐ0Ñ1ðà=EÀc¹]ðàVZóð/¨h°s©mð /Èsð /ÐW[ó /ðF¨ð F°X¸c±]ó Fð ðR (ð R¨sò Ró ðRð(¸Cð ÀHÈSÁMó ð9°ð 9¸À#¹ó 9ð@¸ð @ÀÈÁó @ð
R°(ð R¸xÈ¹}ó Rð
 ð˜Cò ó ðð PUØ\`ØDIØ#ñL"ØðL"Ø"%ðL"Ø/3ðL"Ø>FðL"àðL"à15ðL"àHLðL"ð ðL"ð '*ðL"ð HKÈUÁ{ÐUYÑGYðL"ð #+ð	L"ð >Bð	L"ð
 ˜‰}óL"ð\ ?Cò 74˜sð 74¨h°s©mð 74Àtó 74ðv  $ò$Øð$Ø"+ð$Ø7?À	Ñ7Jð$à˜‰}ð$à(,ó$ñP¨#¨c©(ð ¸4ð ÈDÐQUÉJó ð@ ðS¨ò Só ðSð$ @Dò)Øð)Ø#ð)Ø/7¸©}ð)ØRUÐX\ÑR\ó)ð@9˜#ð 9 Só 9ñ)¨ð )°c¸E±kÀDÑ6Hð )ÐTWÐZ_ÑT_ó )ðH D¨¡Ió Hð*˜sð * x°¡~ó *ð+¨ð +°¸#±ó +ñ4˜cð 4¨Cð 4¸Có 4ðQ¨¨c°3¨h©ó QðT¨Cð T°Dó Tð
;¨D°°d°©Oó ;ð
¨¨S°$¨Y©ó 
ð¨$¨s°D¨y©/ó ñ&¨Tô &r   r  r  c                 ój   ‡— g Š| D ]*  }‰j                  ˆfd„|j                  xs g D «       «       Œ, ‰S )zLUnion of ``requires_env`` across *entries*, first-seen order, no duplicates.c              3   ó,   •K  — | ]  }|‰vsŒ|–— Œ y ­wr=   r¨   )r>   rÅ   Úouts     €r   r@   z_unique_env.<locals>.<genexpr>å  s   øè ø€ ÒI˜¸AÀSºL”1ÑIùs   ƒ	�)Úextendr›   )r  r  rß  s     @r   rÑ  rÑ  á  s;   ø€ à€CØò JˆØ�
‰
ÓI˜u×1Ñ1Ò7°RÔIÕIðJà€Jr   c                 ó\   — t        j                  dt        t        | «      «      i|¥d¬«      S )u~   ``'{"error": "<message>", **extra}'`` â€” the error body is bounded so a raw
    exception can't bloat history across retries.r   Fr   )r   r$   r   r#   )ÚmessageÚextras     r   r¨  r¨  ñ  s*   € ô �:‰:�wÔ 1´#°g³,Ó ?ÐIÀ5ÐIÐX]Ô^Ð^r   c                 óD   — t        j                  | �| d¬«      S |d¬«      S )zDJSON-encode a dict positional arg *or* keyword arguments (not both).Fr   )r   r$   )r�   r±  s     r   Útool_resultrå  ÷  s"   € ä�:‰:˜dÐ.�dÈÔOÐO°FÈÔOÐOr   r™   r±  c                 óž  — 	 t        j                  | «      j                  }t        d„ |j                  «       D «       «      r|S t         j                  j                  t         j                  j                  h}|j                  «       D ��ci c]  \  }}||v sŒ||   j                  |v sŒ||“Œ! c}}S # t        t        f$ r |cY S w xY wc c}}w )z›*kwargs* narrowed to what *handler*'s signature declares; everything when it takes ``**kwargs`` or
    cannot be introspected (builtins, some C callables).c              3   óh   K  — | ]*  }|j                   t        j                  j                  u –— Œ, y ­wr=   )ÚkindÚinspectÚ	ParameterÚVAR_KEYWORD)r>   Úps     r   r@   z&_kwargs_accepted_by.<locals>.<genexpr>  s%   è ø€ Ò
P°qˆ1�6‰6”W×&Ñ&×2Ñ2Ô2Ñ
Pùs   ‚02)ré  Ú	signaturer�  Ú	TypeErrorr   rB   r(  rê  ÚPOSITIONAL_OR_KEYWORDÚKEYWORD_ONLYrÊ   rè  )r™   r±  r�  Úkeyword_kindsr×   rÅ   s         r   r®  r®  ü  s´   € ðÜ×&Ñ& wÓ/×:Ñ:ˆ
ô Ñ
P¸J×<MÑ<MÓ<OÔ
PÔPØˆÜ×&Ñ&×<Ñ<¼g×>OÑ>O×>\Ñ>\Ð]€MØ#Ÿ\™\›^×g‘T�Q˜¨q°JªÀ:ÈaÁ=×CUÑCUÐYfÒCfˆAˆq‰DÓgÐgøô ”zÐ"ò ØŠðüó
 hs#   ‚B2 Â
C	ÂC	Â)C	Â2CÃCr=   )r   N)Nr¤   r+   rc  rq   ré  r   Úloggingr|  r  rì   Údataclassesr   Úpathlibr   Útypingr   r   r   r   r	   r†   r   Ú	getLoggerr¡   r   r   r   r   r#   r   r&   ÚASTrl   r4   rK   rR   r‚   r‡   rN   ra   rp   r–   rª   r‚  rÈ   rÉ   rÌ   r°   rk   r§   r¥   r±   ro   r²   r³   ÚLockrî   rß   r´   rÝ   r¼   Úobjectr¿   rÒ   rã   ré   rø   rï   r  r  r  r  rÑ  r*   r¨  rå  r!   r®  r¨   r   r   ú<module>rú     s`  ðòó Û Û Û Û Û Û 
Û Û Ý !Ý ß 6Õ 6å ,à	ˆ×	Ñ	˜8Ó	$€ð Ð Ø 1Ð àÐ ðH˜Cð H Có Hð3 Sð 3¨Só 3ð"N S§W¡Wð N°ó Nð¨ð °$ó ð$¨ð °°d±ó ñ- h¨t¡nð -ÀÀSÁ	ó -ð`˜x¨™~ó ð
˜t C¨ I™ó 
ðM  c¨4 i¡ð M°Tó Mñ ˆe˜4Ô ÷8ð 8ó !ð8÷$%ñ %ð5ð ð Ð ð #'Ð ØÐ ØLN€��e˜H h¨s¡mÐ3Ñ4°e¸EÀ4¸KÑ6HÐHÑIÓ NØCEÐ �T˜% ¨(°3©-Ð 7Ñ8¸%Ð?Ñ@Ó EÙ;>»5Ð �S˜˜x¨°#©Ð6Ñ7Ñ8Ó @ÙBEÃ%Ð ˜C  h°¸±Ð&=Ñ >Ñ?Ó GØ%�y—~‘~Ó'Ð ØÐ Ù%(£UÐ �S˜‘]Ó *ð/Ð ð˜(ð  xó ð+�(ð +˜vó +ð	) ð 	)¨$ó 	)ð%˜h s™mó %ð>˜xð ¨Dó ð><˜ð < dó <ð~a˜Xð a¨#¨c©(ó að�Hð  D¨°4¨Ñ$8ð ¸Tó ó+ð
a 8ð 
a°¸±ó 
a÷s&ñ s&ðl˜˜i™ð ¨Tó ñ ‹>€ð_ Có _ñP¨ó Pð

h ð 
h°4ð 
h¸Dô 
hr   