+
    i)                         R t ^ RIt^ RIt^ RIHtHtHtHtHt ]P                  ! ]
4      t ! R R4      t ! R R4      t]! 4       tR# )aV  Central registry for all hermes-agent tools.

Each tool file calls ``registry.register()`` at module level to declare its
schema, handler, toolset membership, and availability check.  ``model_tools.py``
queries the registry instead of maintaining its own parallel data structures.

Import chain (circular-import safe):
    tools/registry.py  (no imports from model_tools or tool files)
           ^
    tools/*.py  (import from tools.registry at module level)
           ^
    model_tools.py  (imports tools.registry + all tool modules)
           ^
    run_agent.py, cli.py, batch_runner.py, etc.
N)CallableDictListOptionalSetc                   .   a  ] tR t^t o RtRtR tRtV tR# )	ToolEntryz&Metadata for a single registered tool.c
                r    Wn         W n        W0n        W@n        WPn        W`n        Wpn        Wn        Wn        R # N	nametoolsetschemahandlercheck_fnrequires_envis_asyncdescriptionemoji)
selfr   r   r   r   r   r   r   r   r   s
   &&&&&&&&&&+/home/ubuntu/hermes-agent/tools/registry.py__init__ToolEntry.__init__    s1    	 ( &
    )	r   r   r   r   r   r   r   r   r   Nr   )	__name__
__module____qualname____firstlineno____doc__	__slots__r   __static_attributes____classdictcell____classdict__s   @r   r   r      s     0I

 
r   r   c                   6  a  ] tR t^-t o RtR tR!V 3R lR lltV 3R lR ltR"V 3R lR	 lltV 3R
 lR lt	V 3R lR lt
V 3R lR ltV 3R lR ltR#V 3R lR lltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltR"V 3R lR lltR tV tR# )$ToolRegistryzISingleton registry that collects tool schemas + handlers from tool files.c                "    / V n         / V n        R # r
   _tools_toolset_checksr   s   &r   r   ToolRegistry.__init__0   s    ,.46r   Nc                P   < V ^8  d   QhRS[ RS[ RS[RS[RS[RS[RS[RS[ R	S[ /	# )
   r   r   r   r   r   r   r   r   r   )strdictr   listbool)formatr#   s   "r   __annotate__ToolRegistry.__annotate__8   se      5  5 5  5 	 5
  5  5  5  5  5  5r   c
                   V P                   P                  V4      p
V
'       d3   V
P                  V8w  d"   \        P	                  RWP                  V4       \        TTTTTT;'       g    . TT;'       g    VP                  RR4      V	R7	      V P                   V&   V'       d#   W P                  9  d   WPP                  V&   R# R# R# )zARegister a tool.  Called at module-import time by each tool file.zMTool name collision: '%s' (toolset '%s') is being overwritten by toolset '%s'r    r   N)r(   getr   loggerwarningr   r)   )r   r   r   r   r   r   r   r   r   r   existings   &&&&&&&&&& r   registerToolRegistry.register8   s     ;;??4(((G3NN.&&
 &%++#DDvzz-'D

D ';';;,4  ) <8r   c                $   < V ^8  d   QhRS[ RR/# )r-   r   returnNr.   )r2   r#   s   "r   r3   r4   Z   s     4 4s 4t 4r   c                  a V P                   P                  VR4      oSf   R# SP                  V P                  9   d   \        ;QJ d7    V3R lV P                   P                  4        4       F  '       g   K   RM,	  RM(! V3R lV P                   P                  4        4       4      '       g'   V P                  P                  SP                  R4       \        P                  RV4       R# )zRemove a tool from the registry.

Also cleans up the toolset check if no other tools remain in the
same toolset.  Used by MCP dynamic tool discovery to nuke-and-repave
when a server sends ``notifications/tools/list_changed``.
Nc              3   T   <"   T F  qP                   SP                   8H  x  K  	  R # 5ir
   r   ).0eentrys   & r   	<genexpr>*ToolRegistry.deregister.<locals>.<genexpr>e   s       =
0D1II&0Ds   %(TFzDeregistered tool: %s)r(   popr   r)   anyvaluesr8   debugr   r   rE   s   &&@r   
deregisterToolRegistry.deregisterZ   s     d+===D000 =
040B0B0D=
 =
040B0B0D=
 :
 :
   $$U]]D9,d3r   c                L   < V ^8  d   QhRS[ S[,          RS[RS[S[,          /# )r-   
tool_namesquietr>   )r   r.   r1   r   r/   )r2   r#   s   "r   r3   r4   o   s+      #c( 4 DQUJ r   c                Z   . p/ p\        V4       F  pV P                  P                  V4      pV'       g   K(  VP                  '       dp   VP                  V9  d'    \	        VP                  4       4      WFP                  &   WFP                  ,          '       g!   V'       g   \        P                  RV4       K  / VP                  CRVP                  /CpVP                  RRRV/4       K  	  V#   \
         d0    RYFP                  &   T'       g   \        P                  RT4        Li ; i)zReturn OpenAI-format tool schemas for the requested tool names.

Only tools whose ``check_fn()`` returns True (or have no check_fn)
are included.
FzTool %s check raised; skippingz"Tool %s unavailable (check failed)r   typefunction)sortedr(   r7   r   r1   	Exceptionr8   rK   r   r   append)r   rP   rQ   resultcheck_resultsr   rE   schema_with_names   &&&     r   get_definitionsToolRegistry.get_definitionso   s     .0:&DKKOOD)E~~~>>6Q8<U^^=M8Nnn5
 %^^44 %I4PC%,,C

CMM6:z;KLM% '&  % Q8=nn5$"LL)I4PQs   %C007D*)D*c                ,   < V ^8  d   QhRS[ RS[RS[ /# )r-   r   argsr>   )r.   r/   )r2   r#   s   "r   r3   r4      s'     \ \S \ \3 \r   c                   V P                   P                  V4      pV'       g   \        P                  ! RRV 2/4      #  VP                  '       d    ^ RIHp V! VP                  ! V3/ VB 4      # VP                  ! V3/ VB #   \         dR   p\        P                  RY4       \        P                  ! RR\        T4      P                   RT 2/4      u Rp?# Rp?ii ; i)zExecute a tool handler by name.

* Async handlers are bridged automatically via ``_run_async()``.
* All exceptions are caught and returned as ``{"error": "..."}``
  for consistent error format.
errorzUnknown tool: )
_run_asynczTool %s dispatch error: %szTool execution failed: z: N)r(   r7   jsondumpsr   model_toolsra   r   rV   r8   	exceptionrS   r   )r   r   r^   kwargsrE   ra   rD   s   &&&,   r   dispatchToolRegistry.dispatch   s     %::w.(?@AA	\~~~2!%--"?"?@@==000 	\94C::w*A$q'BRBRASSUVWUX(YZ[[	\s+    B B 1B C ACC C c                0   < V ^8  d   QhRS[ S[,          /# r-   r>   )r   r.   )r2   r#   s   "r   r3   r4      s     * *DI *r   c                H    \        V P                  P                  4       4      # )z0Return sorted list of all registered tool names.)rU   r(   keysr*   s   &r   get_all_tool_namesToolRegistry.get_all_tool_names   s    dkk&&())r   c                6   < V ^8  d   QhRS[ RS[S[,          /# r-   r   r>   )r.   r   r/   )r2   r#   s   "r   r3   r4      s     / /s /x~ /r   c                d    V P                   P                  V4      pV'       d   VP                  # R# )u   Return a tool's raw schema dict, bypassing check_fn filtering.

Useful for token estimation and introspection where availability
doesn't matter — only the schema content does.
N)r(   r7   r   rL   s   && r   
get_schemaToolRegistry.get_schema   s'     %$u||.$.r   c                6   < V ^8  d   QhRS[ RS[S[ ,          /# rp   )r.   r   )r2   r#   s   "r   r3   r4      s     0 0 0# 0r   c                d    V P                   P                  V4      pV'       d   VP                  # R# )z.Return the toolset a tool belongs to, or None.N)r(   r7   r   rL   s   && r   get_toolset_for_tool!ToolRegistry.get_toolset_for_tool   s%    % %u}}/4/r   c                ,   < V ^8  d   QhRS[ RS[ RS[ /# )r-   r   defaultr>   r?   )r2   r#   s   "r   r3   r4      s'     C Cc CC CC Cr   c                    V P                   P                  V4      pV'       d   VP                  '       d   VP                  # T# )z3Return the emoji for a tool, or *default* if unset.)r(   r7   r   )r   r   ry   rE   s   &&& r   	get_emojiToolRegistry.get_emoji   s-    %$B'Br   c                6   < V ^8  d   QhRS[ S[S[3,          /# rj   )r   r.   )r2   r#   s   "r   r3   r4      s     D Dc3h Dr   c                ~    V P                   P                  4        UUu/ uF  w  rWP                  bK  	  upp# u uppi )z?Return ``{tool_name: toolset_name}`` for every registered tool.)r(   itemsr   )r   r   rD   s   &  r   get_tool_to_toolset_map$ToolRegistry.get_tool_to_toolset_map   s1    /3{{/@/@/BC/BGDii/BCCCs   9c                &   < V ^8  d   QhRS[ RS[/# )r-   r   r>   )r.   r1   )r2   r#   s   "r   r3   r4      s      C D r   c                    V P                   P                  V4      pV'       g   R#  \        V! 4       4      #   \         d    \        P                  RT4        R# i ; i)zCheck if a toolset's requirements are met.

Returns False (rather than crashing) when the check function raises
an unexpected exception (e.g. network error, missing import, bad config).
Tz,Toolset %s check raised; marking unavailableF)r)   r7   r1   rV   r8   rK   )r   r   checks   && r   is_toolset_available!ToolRegistry.is_toolset_available   sR     $$((1	=  	LLGQ	s   7 !AAc                6   < V ^8  d   QhRS[ S[S[3,          /# rj   )r   r.   r1   )r2   r#   s   "r   r3   r4      s     N NDdO Nr   c                    \        R V P                  P                  4        4       4      p\        V4       Uu/ uF  q"V P	                  V4      bK  	  up# u upi )z7Return ``{toolset: available_bool}`` for every toolset.c              3   8   "   T F  qP                   x  K  	  R # 5ir
   rB   )rC   rD   s   & r   rF   :ToolRegistry.check_toolset_requirements.<locals>.<genexpr>   s     ?*>Qyy*>s   )setr(   rJ   rU   r   )r   toolsetstss   &  r   check_toolset_requirements'ToolRegistry.check_toolset_requirements   sL    ?$++*<*<*>??<B8<LM<LbD--b11<LMMMs   Ac                6   < V ^8  d   QhRS[ S[S[3,          /# rj   r   r.   r/   )r2   r#   s   "r   r3   r4      s      S$Y r   c           	        / pV P                   P                  4        F  pVP                  pW19  d   RV P                  V4      R. RRR. /W&   W,          R,          P	                  VP
                  4       VP                  '       g   Kl  VP                   F7  pWAV,          R,          9  g   K  W,          R,          P	                  V4       K9  	  K  	  V# )z'Return toolset metadata for UI display.	availabletoolsr   r6   requirements)r(   rJ   r   r   rW   r   r   )r   r   rE   r   envs   &    r   get_available_toolsets#ToolRegistry.get_available_toolsets   s    $&[['')EB!!:!:2!>R!2"B	  L!((4!!! --C2,~">> ^4;;C@ . * r   c                6   < V ^8  d   QhRS[ S[S[3,          /# rj   r   )r2   r#   s   "r   r3   r4      s      $sDy/ r   c                   / pV P                   P                  4        F  pVP                  pW19  d(   RVR. RV P                  P	                  V4      RRR. /W&   VP
                  W,          R,          9  d)   W,          R,          P                  VP
                  4       VP                   F7  pWAV,          R,          9  g   K  W,          R,          P                  V4       K9  	  K  	  V# )zABuild a TOOLSET_REQUIREMENTS-compatible dict for backward compat.r   env_varsr   	setup_urlNr   )r(   rJ   r   r)   r7   r   rW   r   )r   rX   rE   r   r   s   &    r   get_toolset_requirements%ToolRegistry.get_toolset_requirements   s    "$[['')EBB 4 4 8 8 <R
 zzG!44
7#**5::6))Rj44Jz*11#6 * * r   c                    < V ^8  d   QhRS[ /# )r-   rQ   )r1   )r2   r#   s   "r   r3   r4      s     & &T &r   c                   . p. p\        4       pV P                  P                  4        F  pVP                  pWd9   d   K  VP	                  V4       V P                  V4      '       d   VP                  V4       KR  TP                  RTRVP                  RV P                  P                  4        Uu. uF!  qwP                  V8X  g   K  VP                  NK#  	  up/4       K  	  W#3# u upi )zDReturn (available_toolsets, unavailable_info) like the old function.r   r   r   )	r   r(   rJ   r   addr   rW   r   r   )r   rQ   r   unavailableseenrE   r   rD   s   &&      r   check_tool_availability$ToolRegistry.check_tool_availability   s    	u[['')EBzHHRL((,,  $""B 2 2dkk.@.@.BV.BiiSUofaff.BV$  * %% Ws   1C'C'r'   )NNFr6   r6   )F)u   ⚡)r   r   r   r   r   r   r;   rM   r[   rg   rm   rr   rv   r{   r   r   r   r   r   r   r    r!   r"   s   @r   r%   r%   -   s     S7 5  5D4 4* B\ \.* */ /0 0
C C
D D N N
 & (& & &r   r%   )r   rb   loggingtypingr   r   r   r   r   	getLoggerr   r8   r   r%   registry r   r   <module>r      sH       6 6			8	$ *b& b&L >r   