
    h6                     p    d dl mZmZ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 d dlmZmZ  G d d      Zy)	    )AnyDictIterableListOptionalTupleUnion)verbose_logger
aresponses)!BaseResponsesAPIStreamingIterator)ResponsesAPIResponse	ToolParamc                   r   e Zd ZdZedeee      defd       Z	edeee      de
ee   ee   f   fd       Zededee   fd       Zedee   dee   fd	       Zed
eeeeef      ee   f   defd       Zededee   fd       Zede
ee   ee   ee   f   fd       Zededeeef   fd       Zededefd       Zedee   dedeeeef      fd       Ze	 d!dedeeeef      dedee   fd       Zedee   dedeee      dededeeef   fd       Zededee   deeeef      defd        Zy)"LiteLLM_Proxy_MCP_Handlerz
    Helper class with static methods for MCP integration with Responses API.

    This handles when a user passes mcp server_url="litellm_proxy" in their tools.
    toolsreturnc                     | rC| D ]>  }t        |t              s|j                  d      dk(  s)|j                  d      dk(  s> y y)z\
        Returns True if the user passed a MCP tool with server_url="litellm_proxy"
        typemcp
server_urllitellm_proxyTF)
isinstancedictget)r   tools     k/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/responses/mcp/litellm_proxy_mcp_handler.py_should_use_litellm_mcp_gatewayz9LiteLLM_Proxy_MCP_Handler._should_use_litellm_mcp_gateway   sE    
 tT*HHV$-HH\*o=	 
     c                     g }g }| rb| D ]]  }t        |t              r:|j                  d      dk(  r&|j                  d      dk(  r|j                  |       M|j                  |       _ ||fS )z
        Parse tools and separate MCP tools with litellm_proxy from other tools.
        
        Returns:
            Tuple of (mcp_tools_with_litellm_proxy, other_tools)
        r   r   r   r   )r   r   r   append)r   mcp_tools_with_litellm_proxyother_toolsr   s       r   _parse_mcp_toolsz*LiteLLM_Proxy_MCP_Handler._parse_mcp_tools   sq     9;$!#tT*HHV$-HH\*o=077=&&t,  ,[88r   user_api_key_authc                 N   K   ddl m} |j                  |        d{   S 7 w)z0Get available tools from the MCP server manager.r   global_mcp_server_manager)r%   N)9litellm.proxy._experimental.mcp_server.mcp_server_managerr(   
list_tools)r%   r(   s     r   _get_mcp_tools_from_managerz5LiteLLM_Proxy_MCP_Handler._get_mcp_tools_from_manager3   s(     	
 /99L]9^^^^s   %#%	mcp_toolsc                 V    ddl m} g }| D ]  } ||      }|j                  |        |S )z0Transform MCP tools to OpenAI-compatible format.r   )/transform_mcp_tool_to_openai_responses_api_tool)%litellm.experimental_mcp_client.toolsr.   r!   )r,   r.   openai_toolsmcp_toolopenai_tools        r   _transform_mcp_tools_to_openaiz8LiteLLM_Proxy_MCP_Handler._transform_mcp_tools_to_openai<   s8    	
 !HI(SK, " r   r"   c                     | D ];  }t        |t              r|j                  d      dk(  s( yt        |dd      dk(  s; y y)zCheck if we should auto-execute tool calls.

        Only auto-execute tools if user passed a MCP tool with require_approval set to "never".
        
        
        require_approvalneverTNFr   r   r   getattr)r"   r   s     r   _should_auto_execute_toolsz4LiteLLM_Proxy_MCP_Handler._should_auto_execute_toolsJ   sG     1D$%88./7:148GC 1 r   responsec                     g }| j                   D ]f  }t        |t              r&|j                  d      dk(  r|j	                  |       9t        |d      sFt        |d      dk(  sV|j	                  |       h |S )z,Extract tool calls from the response output.r   function_call)outputr   r   r   r!   hasattrr8   )r:   
tool_callsoutput_items      r   !_extract_tool_calls_from_responsez;LiteLLM_Proxy_MCP_Handler._extract_tool_calls_from_response\   so     !#
#??K;-'?:!!+.f-'+v2NRa2a!!+. + r   c                 &   t        | t              rG| j                  d      }| j                  d      }| j                  d      xs | j                  d      }n6t        | dd      }t        | dd      }t        | dd      xs t        | dd      }|||fS )z;Extract tool name, arguments, and call_id from a tool call.name	argumentscall_ididNr7   )	tool_call	tool_nametool_argumentstool_call_ids       r   _extract_tool_call_detailsz4LiteLLM_Proxy_MCP_Handler._extract_tool_call_detailsk   s     i&!f-I&]];7N$==3Jy}}T7JL	648I$YTBN"9i>`')UY[_B`L.,66r   rI   c                     ddl }t        | t              r	 |j                  |       S | xs i S # |j                  $ r i cY S w xY w)z<Parse tool arguments, handling both string and dict formats.r   N)jsonr   strloadsJSONDecodeError)rI   rM   s     r   _parse_tool_argumentsz/LiteLLM_Proxy_MCP_Handler._parse_tool_argumentsy   sN     	nc*zz.11 "'R' '' 	s   - A Aresultc                 J   | rt        | d      r| j                  sy	 ddlm}m}m} g }g }| j                  D ]  }t        ||      r%|j                  t        |j                               4t        ||      r|j                  d       Rt        ||      r|j                  d       pt        |      j                  }|j                  |        |rdj                  |      nd}|r*d	d
j                  |       d}	| d|	 j                         }|xs dS # t        $ r Y yw xY w)z:Parse MCP tool call result and extract meaningful content.contentzTool executed successfullyr   )EmbeddedResourceImageContentTextContentImagerU     z[Generated z, ])r>   rT   	mcp.typesrU   rV   rW   ImportErrorr   r!   rN   textr   __name__joinstrip)
rR   rU   rV   rW   
text_partsother_content_typescontent_itemcontent_typeresult_text
other_infos
             r   _parse_mcp_resultz+LiteLLM_Proxy_MCP_Handler._parse_mcp_result   s    WVY7v~~/	0MM
 
 "NNL,4!!#l&7&7"89L,7#**73L*:;#**+=>  $L1::#**<8 +  /9chhz*b &tyy1D'E&FaHJ(M:,7==?K:::=  	0/	0s   
D 	D"!D"r?   c           	        K   ddl m} g }d}| D ]  }	 t        j                  |      \  }}}|st	        j
                  d|        8t        j                  |      }|j                  |||       d{   }	t        j                  |	      }
|j                  ||
d        |S 7 1# t        $ rB}t	        j                  d|        |j                  |dt        |       d       Y d}~d}~ww xY ww)	z&Execute tool calls and return results.r   r'   NzTool call missing name: )rC   rD   r%   )rJ   rR   zError executing MCP tool call: zError executing tool: )r)   r(   r   rK   r
   warningrQ   	call_toolrh   r!   	Exception	exceptionrN   )r?   r%   r(   tool_resultsrJ   rG   rH   rI   parsed_argumentsrR   rf   es               r   _execute_tool_callsz-LiteLLM_Proxy_MCP_Handler._execute_tool_calls   s    	
 &*#I:S:n:nox:y7	>< "**-Ei[+QR#<#R#RSa#b 8BB".&7  C    8II&Q##$0)% % $< )  ((+J1#)NO##$0 6s1vh?%  sL   C53B'C5,B'3B%4-B'!C5%B''	C208C-(C5-C22C5Nrn   original_inputc                 T   g }|rYt        |t              r|j                  dd|d       n3t        |t              r|j	                  |       n|j                  |       g }g }| j
                  D ]  }t        |t              s|j                  d      dk(  rc|j                  d      xs |j                  d      }|j                  d      }|j                  d	      }	|sq|st|j                  d|||	d
       |j                  d      dk(  s|j                  dg       }
t        |
t              r|j	                  |
       |j                  |
        |s|r-|j                  dd|d       |D ]  }|j                  |        |D ]  }|j                  d|d   |d   d        |S )z:Create follow-up input with tool results in proper format.messageuser)r   rolerT   r   r<   rE   rF   rC   rD   )r   rE   rC   rD   rT   	assistantfunction_call_outputrJ   rR   )r   rE   r=   )r   rN   r!   listextendr=   r   r   )r:   rn   rr   follow_up_inputassistant_message_contentfunction_callsr@   rE   rC   rD   rT   r<   tool_results                r   _create_follow_up_inputz1LiteLLM_Proxy_MCP_Handler._create_follow_up_input   s    &( .#.&&%"-( 
 ND1&&~6&&~6 02!/1#??K+t,??6*o=)ooi8QKOOD<QG&??62D + <I 4&--$3'.$()2	/  !__V,	9)ooi<G!'40188A188A+ +0 %""!#4$  "0&&}5 "0 (K"".&~6%h/$  ( r   r{   model	all_toolsresponse_idcall_paramsc                 >   K   t        d| |||d| d{   S 7 w)z3Make follow-up response API call with tool results.)inputr   r   previous_response_idN r   )r{   r   r   r   r   s        r   _make_follow_up_callz.LiteLLM_Proxy_MCP_Handler._make_follow_up_call"  s:        
!!,	

 
 
 	
 
s   mcp_tools_fetchedc                    ddl }ddl}ddlm}m}  |dd|j                         j                  dd  dd |d	|j                  |d
t              g       g      } |dd|j                         j                  dd  dd |d	|j                  |d
t              g       g      }| j                  j                  |j                                | j                  j                  |j                                | S )zHAdd custom output elements to the final response for MCP tool execution.r   N)GenericResponseOutputItem
OutputTextr   
mcp_tools_   	completedsystemoutput_text   )indentdefault)r   r^   annotations)r   rF   statusrv   rT   tool_execution_resultstool_results_)rM   uuidlitellm.types.responses.mainr   r   uuid4hexdumpsrN   r=   r!   
model_dump)	r:   r   rn   rM   r   r   r   mcp_tools_outputtool_results_outputs	            r   $_add_mcp_output_elements_to_responsez>LiteLLM_Proxy_MCP_Handler._add_mcp_output_elements_to_response3  s     	V 5$DJJL,,Ra012&$5aM "
 8)tzz|//345&LCH "
 	/::<=2==?@r   )N)r_   
__module____qualname____doc__staticmethodr   r   r   boolr   r   r   r   r$   r+   r3   r	   r   rN   r9   r   rA   rK   rQ   rh   rq   r   r   r   r   r   r   r   r   r   	   s    
x8K/L 
QU 
 
 9))< = 9%YY]^aYbHbBc 9 9* _S _T#Y _ _ $s) S	   &+Dc3h,@$y/,Q&R	 " 4H TRUY   7x}hsmU]^aUb7b1c 7 7 
(c 
(d38n 
( 
( &;# &;# &; &;P )I)) 
d38n	) )V  #D&D4S>*D D 
c	D DL 
c

 DI&
 	

 
 
#%FF	G
 
  .&.9. 4S>*. 
	. .r   r   N)typingr   r   r   r   r   r   r	   litellm._loggingr
   litellm.responses.mainr   $litellm.responses.streaming_iteratorr   litellm.types.llms.openair   r   r   r   r   r   <module>r      s&    D D D + - R EY Yr   