
    iR                     z   d Z ddlZddlZddlZddlm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mZmZmZmZ ddlmZ ddlmZ ddlmZmZ dd	lmZ dd
lmZmZ ddl m!Z!m"Z"m#Z# ddl$m%Z%m&Z& ddl'm(Z( ddl)m*Z* ddl+m,Z,m-Z-  ej\                  e/      Z0dZ1e G d d             Z2 G d d      Z3 G d d      Z4y)z-Tool management for function calling and MCP.    N)	dataclass)Path)AnyDictListMappingSequence)Client)CallToolResult)StreamableHttpTransportStdioTransport)types)ToolingConfigConfigError)FunctionToolConfigMcpLocalConfigMcpRemoteConfig)MessageBlockMessageBlockType)ToolSpec)AttachmentStore)FUNCTION_CALLING_DIRFunctionManagerg      $@c                   &    e Zd ZU eed<   dZeed<   y)_FunctionManagerCacheEntrymanagerFauto_loadedN)__name__
__module____qualname__r   __annotations__r   bool     Q/Users/bowang/.openclaw/workspace/ChatDev/runtime/node/agent/tool/tool_manager.pyr   r       s    Kr$   r   c                   X   e Zd ZdZd5dZdefdZdeddfdZdddd	d
e	de
e	e	f   dz  dedz  dedee   f
dZdede	dee   fdZdee   dz  dee   fdZddde	de
e	ef   dede
e	ef   dz  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	 d6de	de
e	ef   dede
e	ef   dz  def
dZdedefdZ	 d6de	de
e	ef   dede
e	ef   dz  def
d Z	 d6de	de
e	ef   dede
e	ef   dz  def
d!Zde	d"ede
e	ef   dz  defd#Z de
e	ef   dz  de!dz  fd$Z"de	d%e#e$jJ                     dz  d&e!dz  dee&   fd'Z'de	d(e$jJ                  d)ed&e!dz  dee&   f
d*Z(dd+de	d,e	d-e	dz  d.e)d)ed&e!dz  d/e
e	ef   dz  dee&   fd0Z*de	d.e)d)ed-e	dz  de	f
d1Z+d-e	dz  de)fd2Z,dede	dd3fd4Z-y)7ToolManagerz&Manage function tools for agent nodes.returnNc                 D    t         | _        i | _        i | _        i | _        y N)r   _functions_dir_function_managers_mcp_tool_cache_mcp_stdio_clientsselfs    r%   __init__zToolManager.__init__)   s"    $8JL57DFr$   c                     | j                   j                  | j                        }|8t        t	        | j                              }|| j                   | j                  <   |j
                  S )Nr   )r,   getr+   r   r   r   )r0   entrys     r%   _get_function_managerz!ToolManager._get_function_manager/   sX    ''++D,?,?@=.tGZGZ7[\E;@D##D$7$78}}r$   	auto_loadc                     |sy | j                   j                  | j                  t        t	        | j                                    }|j
                  s"|j                  j                          d|_        y y )Nr3   T)r,   
setdefaultr+   r   r   r   r   load_functions)r0   r7   r5   s      r%   _ensure_functions_loadedz$ToolManager._ensure_functions_loaded6   sb    ''22&t?R?R/ST
   MM((* $E !r$      )headerstimeoutattempts
server_urlr=   r>   r?   c                  K   d}d }t        d|dz         D ]\  }	 t        t        ||xs d       |xs t              }|4 d {    |j	                          d {   cd d d       d {    c S  |r|g S 7 67  7 # 1 d {  7  sw Y   nxY w# t
        $ r5}	|	}||k(  r t        j                  |       d {  7   |dz  }Y d }	~	d }	~	ww xY ww)Ng      ?   r=   	transportr>      )ranger
   r   DEFAULT_MCP_HTTP_TIMEOUT
list_tools	Exceptionasynciosleep)
r0   r@   r=   r>   r?   delay
last_errorattemptclientexcs
             r%   _fetch_mcp_tools_httpz!ToolManager._fetch_mcp_tools_httpA   s      '+
Q1-G5j'/UYZ#?'? "6!'!2!2!44 "66 . 	 "4 "6666  
h&mmE***
s   C*BA;BBA=B B,A?-B1
C;B=B?BB	B
B	BC	C  C C
CCCCconfig
launch_keyc                 N   K   | j                  ||      }|j                         S wr*   )_get_stdio_clientrI   r0   rS   rT   rP   s       r%   _fetch_mcp_tools_stdioz"ToolManager._fetch_mcp_tools_stdio]   s'     ''
;  ""s   #%tool_configsc                    |sg S g }t               }t        |      D ]V  \  }}g }|j                  dk(  r4|j                  t              }|st        d      | j                  |      }n|j                  dk(  r4|j                  t              }|st        d      | j                  |      }nD|j                  dk(  r4|j                  t              }|st        d      | j                  |      }n	 |j                  }|D ]s  }	|	j                  }
|r| d|
 n|
}||v rt        d| d	      |j                  |       ||	_        ||	j                  d
<   |
|	j                  d<   |j!                  |	       u Y |S )zGReturn provider-agnostic tool specifications for the given config list.function&Function tooling configuration missing
mcp_remote MCP remote configuration missing	mcp_localMCP local configuration missing_zDuplicate tool name 'zG' detected. Please use a unique 'prefix' in your tooling configuration._config_indexoriginal_name)set	enumeratetype	as_configr   
ValueError_build_function_specsr   _build_mcp_remote_specsr   _build_mcp_local_specsprefixnamer   addmetadataappend)r0   rY   specs
seen_toolsidxtool_configcurrent_specsrS   rl   specrc   
final_names               r%   get_tool_specszToolManager.get_tool_specsa   s   I ""u
 ), 7C,.M:-$../AB$%MNN $ : :6 B!!\1$..?$%GHH $ < <V D!![0$..~>$%FGG $ ; ;F C  ''F% $		<Bxq8
+%/
| <V W  z* '	14o.1>o.T" &/ !8P r$   )tool_context	tool_name	argumentsrt   ry   c                   K   |j                   dk(  r6|j                  t              }|st        d      | j	                  ||||      S |j                   dk(  r>|j                  t
              }|st        d      | j                  ||||       d{   S |j                   dk(  r>|j                  t              }|st        d      | j                  ||||       d{   S t        d|j                          7 i7 w)	z0Execute a tool using the provided configuration.r[   r\   r]   r^   Nr_   r`   zUnsupported tool type: )	rf   rg   r   rh   _execute_function_toolr   _execute_mcp_remote_toolr   _execute_mcp_local_tool)r0   rz   r{   rt   ry   rS   s         r%   execute_toolzToolManager.execute_tool   s     z) **+=>F !IJJ..y)V\ZZ|+ **?;F !CDD66y)VUabbb{* **>:F !BCC55iFT`aaa2;3C3C2DEFF c bs%   BC>C:AC>C<C><C>c           
      4   | j                  |j                         g }|j                  D ]k  }|j                  d      }t	        |t
              sdi d}|j                  t        |j                  dd      |j                  d      xs d|ddi	             m |S )
N
parametersobjectrf   
propertiesrm    descriptionsourcer[   rm   r   r   ro   )r;   r7   toolsr4   
isinstancer   rp   r   )r0   rS   rq   toolr   s        r%   ri   z!ToolManager._build_function_specs   s    %%f&6&67 "LLD,/Jj'2&.bA
LL&"- $ 7 =2)&
3		 ! r$   c                    d|j                          }| j                  j                  |      }|Tt        j                  | j                  |j                  |j                  |j                              }|| j                  |<   g }|D ]W  }|j                  t        |j                  |j                  xs d|j                  xs di dd|j                  dd	             Y |S )
Nzremote:)r=   r>   r   r   r   mcpremoter   servermoder   )	cache_keyr-   r4   rK   runrR   r   r=   r>   rp   r   rm   r   inputSchema)r0   rS   r   r   rq   r   s         r%   rj   z#ToolManager._build_mcp_remote_specs   s    f..012	$$((3=KK**MM"NN"NN + E /4D  + "DLL $ 0 0 6B#//WHTV3W(-PXY	  r$   c                    |j                         }|st        d      d| }| j                  j                  |      }|4t	        j
                  | j                  ||            }|| j                  |<   g }|D ]M  }|j                  t        |j                  |j                  xs d|j                  xs di ddddd	
             O |S )N*MCP local configuration missing launch keyzstdio:r   r   r   r   stdiolocalr   r   )r   rh   r-   r4   rK   r   rX   rp   r   rm   r   r   )r0   rS   rT   r   r   rq   r   s          r%   rk   z"ToolManager._build_mcp_local_specs   s    %%'
IJJZL)	$$((3=KK ; ;FJ OPE.3D  + "DLL $ 0 0 6B#//WHTV3W(-'R	  r$   c                    | j                         }|j                  r|j                          |j                  |      }|t	        d| d| j
                         t        |xs i       }|| j                  |      r||d<    |di |S )NzTool z not found in _contextr#   )r6   r7   r:   get_functionrh   r+   dict_function_accepts_context)r0   rz   r{   rS   ry   mgrfunc	call_argss           r%   r}   z"ToolManager._execute_function_tool   s     ((* 	*<uYK~d>Q>Q=RSTTb)	$..t4$0Ij! i  r$   r   c                    	 t        j                  |      }|j                  j                         D ]|  }|j                  t         j                  j                  u r y|j                  dk(  s;|j                  t         j                  j                  t         j                  j                  fv s| y y# t        t        f$ r Y yw xY w)NFTr   )inspect	signaturerh   	TypeErrorr   valueskind	ParameterVAR_KEYWORDrm   POSITIONAL_OR_KEYWORDKEYWORD_ONLY)r0   r   r   params       r%   r   z%ToolManager._function_accepts_context  s    	))$/I ))002EzzW..:::zzZ'EJJ!!77!!..; -  3  I& 		s   B1 1CCc                 T  K   t        t        |j                  |j                  xs d       |j                  xs t
              }|4 d {    |j                  ||       d {   }d d d       d {    | j                  ||      S 7 A7 )7 # 1 d {  7  sw Y   +xY ww)NrC   rD   )r
   r   r   r=   r>   rH   	call_tool_normalize_mcp_result)r0   rz   r{   rS   ry   rP   results          r%   r~   z$ToolManager._execute_mcp_remote_tool  s      -fmmV^^E[W[\NN>&>
 6!++IyAAF 6)))V\JJ A 666sZ   A	B(BB(B%B&B*B(5B6B(BB(B%BB%!B(c                    K   |j                         }|st        d      | j                  ||      }|j                  ||      }| j	                  |||      S w)Nr   )r   rh   rV   r   r   )r0   rz   r{   rS   ry   rT   stdio_clientr   s           r%   r   z#ToolManager._execute_mcp_local_tool&  s^      %%'
IJJ--fjA''	9=)))V\JJs   AAr   c                 0   | j                  |      }| j                  ||j                  |      }|r|S |j                  |j                  S |j                  r@|j                  d   }t	        |t
        j                        r|j                  S t        |      S y )Nr   )	_extract_attachment_store_convert_mcp_content_to_blockscontentstructured_contentr   r   TextContenttextstr)r0   rz   r   ry   attachment_storeblocksr   s          r%   r   z!ToolManager._normalize_mcp_result4  s      99,G44YP`aM$$0,,,>>nnQ'G'5#4#45||#w<r$   c                     |sy |j                  d      }t        |t              r|S |)t        j	                  dt        |      j                         y )Nr   z@attachment_store in tool_context is not AttachmentStore (got %s))r4   r   r   loggerwarningrf   r   )r0   ry   	candidates      r%   r   z%ToolManager._extract_attachment_storeG  sP     $$%78	i1 NNRY(( r$   contentsr   c                     g }|s|S t        |      D ]-  \  }}| j                  ||||      }|s|j                  |       / |S r*   )re   _convert_single_mcp_blockextend)r0   rz   r   r   r   rs   r   	converteds           r%   r   z*ToolManager._convert_mcp_content_to_blocksT  sQ     &(M%h/LC66y'3P`aIi( 0 r$   r   block_indexc           
         t        |t        j                        r t        j                  |j
                        gS t        |t        j                        r8| j                  ||j                  |j                  t        j                  ||      S t        |t        j                        r8| j                  ||j                  |j                  t        j                  ||      S t        |t        j                        r
|j                  }t        |t        j                         rnt#        |j$                        |j                  d}t        t        j&                  |j
                  |j)                         D ci c]  \  }}|	|| c}}      gS t        |t        j*                        r\dt#        |j$                        i}	| j                  ||j,                  |j                  | j/                  |j                        |||	      S t        |t        j0                        rt#        |j$                        |j                  |j2                  d}t        t        j4                  |j2                  xs d|j$                   |j)                         D ci c]  \  }}|	|| c}}      gS t6        j9                  dt;        |      j<                         g S c c}}w c c}}w )N)uri	mime_typerf   r   dataresource_uriextra)r   r   r   zResource link: z$Unhandled MCP content block type: %s)r   r   r   r   
text_blockr   ImageContent_materialize_mcp_binary_blockr   mimeTyper   IMAGEAudioContentAUDIOEmbeddedResourceresourceTextResourceContentsr   r   TEXTitemsBlobResourceContentsblob_message_block_type_from_mimeResourceLinkr   DATAr   r   rf   r   )
r0   rz   r   r   r   r   data_payloadkvr   s
             r%   r   z%ToolManager._convert_single_mcp_blockc  s    gu001 ++GLL9::gu11255   &&   gu11255   &&   gu556''H(E$>$>?x||,!)!2!2 
 !-22%]]/;/A/A/CU/Ctq!q}ad/CU  (E$>$>?"C$5 99MM%%66x7H7HI$ :   gu1127;;'$--&22L ).. ,,O/'++0O+7+=+=+?Q+?41a1=!Q$+?Q  	=tG}?U?UV	= V4 Rs   4
K?K
KKr   payload_b64r   
block_typer   c                .   | j                  ||||      }	 t        j                  |      }	d||j                  d}|r|j                  |       |1d| d|xs d	 d
}t        t        j                  |i |d|d      gS |j                  |	||||      }|j                         gS # t        j                  t
        f$ rS}
t        j                  d|j                  ||
       t        j                  d|j                   d| d      gcY d }
~
S d }
~
ww xY w)Nz*Failed to decode MCP %s payload for %s: %sz[failed to decode z content from ]mcp_tool)r   rz   r   z[binary content omitted: z (zapplication/octet-streamz)]attachment_store_missing)reasonr   r   )r   r   display_namer   )_build_attachment_namebase64	b64decodebinasciiErrorrh   r   r   valuer   r   updater   r   register_bytesas_message_block)r0   rz   r   r   r   r   r   r   r   binaryrQ   ro   placeholderrecords                 r%   r   z)ToolManager._materialize_mcp_binary_block  sR    229j+W`a	%%k2F !"$**

 OOE"#+L>I<cIc;ddfg  )..$cHc0JYbc  "00% 1 
 '')**G 
+ 	NNGIYIY[dfij''()9)9(:.STU 	s   B( (DAD	DDc                     | d|j                    d|dz    j                         xs d}dj                  d |D              }t        j                  |xs d      xs d}| | S )Nra   rB   
attachmentr   c              3   L   K   | ]  }|j                         s|d v r|nd  yw)>   -ra   ra   N)isalnum).0chs     r%   	<genexpr>z5ToolManager._build_attachment_name.<locals>.<genexpr>  s(     [VZPR"**,"
2BBKVZs   "$)r   stripjoin	mimetypesguess_extension)r0   rz   r   r   r   base	safe_baseexts           r%   r   z"ToolManager._build_attachment_name  sq     Aj../qq0ABHHJZlGG[VZ[[	''	R8>BSE""r$   c                    |st         j                  S |j                  d      rt         j                  S |j                  d      rt         j                  S |j                  d      rt         j
                  S t         j                  S )Nzimage/zaudio/zvideo/)r   FILE
startswithr   r   VIDEO)r0   r   s     r%   r   z)ToolManager._message_block_type_from_mime  sk    #((()#))))#))))#)))$$$r$   _StdioClientWrapperc                 t    | j                   j                  |      }|t        |      }|| j                   |<   |S r*   )r.   r4   r
  rW   s       r%   rV   zToolManager._get_stdio_client  s<    ((,,Z8>(0F28D##J/r$   r(   Nr*   ).r   r   r    __doc__r1   r   r6   r"   r;   r   r   floatintr   r   rR   r   rX   r   r   rx   r   r   ri   r   rj   rk   r}   r   r~   r   FastMcpCallToolResultr   r   r   r	   r   ContentBlockr   r   r   r   r   r   r   rV   r#   r$   r%   r'   r'   &   s9   0G 	%$ 	%4 	% *. $ c3h$&	
   
c8#> #s #W[\_W` #04+>+E 0$x. 0p /3GG S>G #	G 38nt+G 
G:,> 4> "o $x. 2^ X 8 /3!! S>! #	!
 38nt+! 
!.c d ( /3KK S>K  	K
 38nt+K 
K( /3KK S>K 	K
 38nt+K 
K & 38nt+	
 
&d38nt6K P_bfPf  5--.5 *D0	
 
l	DD ##D 	D
 *D0D 
l	D^ (,1+1+ 1+ :	1+
 %1+ 1+ *D01+ CH~$1+ 
l	1+f
#
# %
# 	
#
 :
# 

#	%sTz 	%FV 	% C La r$   r'   c                       e Zd ZdeddfdZddZddZdee   fdZ	de
d	ee
ef   defd
Zde
dededefdZddZddZy)r
  rS   r(   Nc                 \   |j                   rt        j                  j                         ni }|j	                  |j
                         |xs d }t        |j                  t        |j                        ||j                  d      }t        |      | _        t        j                         | _        t!        j"                  | j$                  d      | _        | j&                  j)                          t        j*                  | j-                         | j                        }|j/                          y )NT)commandargsenvcwd
keep_alive)rE   )targetdaemon)inherit_envosenvironcopyr   r  r   r  listr  r  r
   _clientrK   new_event_loop_loop	threadingThread	_run_loop_threadstartrun_coroutine_threadsafe_initializer   )r0   rS   r  env_payloadrE   init_futures         r%   r1   z_StdioClientWrapper.__init__  s    #)#5#5bjjoo2

6::kT"NNfkk"


	 	2++-
 ''t~~dK66t7G7G7I4::Vr$   c                 v    t        j                  | j                         | j                  j                          y r*   )rK   set_event_loopr"  run_foreverr/   s    r%   r%  z_StdioClientWrapper._run_loop  s$    tzz*

 r$   c                    K   t        j                         | _        | j                  j	                          d {    y 7 wr*   )rK   Lock_lockr   
__aenter__r/   s    r%   r)  z_StdioClientWrapper._initialize  s)     \\^
ll%%'''s   7A?Ac                     t        j                  | j                  d      | j                        }|j	                         S )NrI   rK   r(  _callr"  r   r0   futures     r%   rI   z_StdioClientWrapper.list_tools  s-    11$**\2JDJJW}}r$   rm   r{   c                     t        j                  | j                  d||      | j                        }|j	                         S )Nr   r4  )r0   rm   r{   r7  s       r%   r   z_StdioClientWrapper.call_tool  s7    11JJ{D)4JJ
 }}r$   methodr  kwargsc                    K   | j                   4 d {    t        | j                  |      } ||i | d {   cd d d       d {    S 7 ;7 7 	# 1 d {  7  sw Y   y xY wwr*   )r1  getattrr   )r0   r9  r  r:  r   s        r%   r5  z_StdioClientWrapper._call!  sI     :::4<<0Dt.v.. ::. :::sS   A*AA*"AAAA*	A
A*AA*A'AA'#A*c                    t        j                  | j                         | j                        }|j	                          | j                  j                  | j                  j                         | j                  j                          y r*   )	rK   r(  	_shutdownr"  r   call_soon_threadsafestopr&  r   r6  s     r%   closez_StdioClientWrapper.close&  sR    11$..2BDJJO

''

8r$   c                    K   | j                   4 d {    | j                  j                  d d d        d {    d d d       d {    y 7 :7 7 	# 1 d {  7  sw Y   y xY wwr*   )r1  r   	__aexit__r/   s    r%   r>  z_StdioClientWrapper._shutdown,  sE     :::,,((tT::: ::: :::sS   A)AA)!AAAA)A	A)AA)A&AA&"A)r  )r   r   r    r   r1   r%  r)  r   r   rI   r   r   r   r5  rA  r>  r#   r$   r%   r
  r
    s|    ~ $ $!(DI c d38n  /# /c /S /S /
;r$   r
  )5r  rK   r   r   dataclassesr   r   loggingr  r  r#  pathlibr   typingr   r   r   r   r	   fastmcpr
   fastmcp.client.clientr   r  fastmcp.client.transportsr   r   r   r   entity.configsr   r   entity.configs.node.toolingr   r   r   entity.messagesr   r   entity.tool_specr   utils.attachmentsr   utils.function_managerr   r   	getLoggerr   r   rH   r   r'   r
  r#   r$   r%   <module>rR     s    3    !    	   5 5  I M  5 [ [ : % - H			8	$    
R Rj3; 3;r$   