
    j
iQ                     d   d Z ddlmZmZ ddlmZmZmZmZ ddl	m
Z
 ddlmZmZmZmZmZmZ ddl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  ddl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z) dd	l!mZ* ddl+m,Z,m-Z- ddl.m/Z/m0Z0m1Z1 ddl2m3Z3m4Z4m5Z5 ddl6m7Z7m8Z8 	 ddl9m:Z: dZ;n# e<$ r dZ;Y nw xY weez  ez  Z=e;re>e=         e
z  e:z  Z?ne>e=         e
z  Z?dZ@ G d de          ZAde$de=fdZBde4deCe?eAdz  f         fdZDdee3gee4         f         de>e5         dz  dee3gee4         f         fdZEdede>e*         fd ZFdddddd!dedz  d"e*d#e7dz  d$e0dz  de>e5         dz  d%eGdz  d&eHdefd'ZIdddddd!dedz  d#e7dz  d$e0dz  de>e5         dz  d%eGdz  d&eHde>e         fd(ZJd"ede>eG         fd)ZKd"edefd*ZLdS )+zTools adapter for converting MCP tools to LangChain tools.

This module provides functionality to convert MCP tools into LangChain-compatible
tools, handle tool execution, and manage tool conversion between the two formats.
    )	AwaitableCallable)	AnnotatedAny	TypedDictget_args)ToolMessage)FileContentBlockImageContentBlockTextContentBlockcreate_file_blockcreate_image_blockcreate_text_block)BaseToolInjectedToolArgStructuredToolToolException)get_all_basemodel_annotations)ClientSession)Tool)ArgModelBaseFuncMetadata)AudioContentBlobResourceContentsContentBlockEmbeddedResourceImageContentResourceLinkTextContentTextResourceContents)	BaseModelcreate_model)CallbackContext	Callbacks_MCPCallbacks)MCPToolCallRequestMCPToolCallResultToolCallInterceptor)
Connectioncreate_session)CommandTFi  c                   .    e Zd ZU dZeeef         ed<   dS )MCPToolArtifactaf  Artifact returned from MCP tool calls.

    This TypedDict wraps the structured content from MCP tool calls,
    allowing for future extension if MCP adds more fields to tool results.

    Attributes:
        structured_content: The structured content returned by the MCP tool,
            corresponding to the structuredContent field in CallToolResult.
    structured_contentN)__name__
__module____qualname____doc__dictstrr   __annotations__     C:\Users\Dell Inspiron 16\Desktop\tws\AgrotaPowerBi\back-agrota-powerbi\mcp-client-agrota\venv\Lib\site-packages\langchain_mcp_adapters/tools.pyr-   r-   F   s2           S#X&&&&&r7   r-   contentreturnc                    t          | t                    rt          | j                  S t          | t                    rt          | j        | j                  S t          | t                    rd| j         }t          |          t          | t                    rf| j        pd}|r8|                    d          r#t          t          | j                  |          S t          t          | j                  |          S t          | t                    r| j        }t          |t"                    rt          |j                  S t          |t$                    rL|j        pd}|r+|                    d          rt          |j        |          S t          |j        |          S dt)          |          j         }t-          |          dt)          |           j         }t-          |          )	a|  Convert any MCP content block to a LangChain content block.

    Args:
        content: MCP content object (TextContent, ImageContent, AudioContent,
            ResourceLink, or EmbeddedResource).

    Returns:
        LangChain content block dict.

    Raises:
        NotImplementedError: If AudioContent is passed.
        ValueError: If an unknown content type is passed.
    )text)base64	mime_typeziAudioContent conversion to LangChain content blocks is not yet supported. Received audio with mime type: Nzimage/)urlr>   z Unknown embedded resource type: zUnknown MCP content type: )
isinstancer   r   r<   r   r   datamimeTyper   NotImplementedErrorr   
startswithr4   urir   r   resourcer    r   blobtyper/   
ValueError)r9   msgr>   rF   s       r8    _convert_mcp_content_to_lc_blockrK   T   s     ';'' 4 gl3333'<(( S!AQRRRR'<(( 'L9@9IL L 	 "#&&&'<(( L$,	 	Q--h77 	Q%#gk*:*:iPPPP S%5%5KKKK'+,, 
#h 455 	9$(-8888h 455 	P )1TI UY11(;; U))TTTT$HMYOOOOJh1HJJoo
?tG}}'=
?
?C
S//r7   call_tool_resultNc                 d   t          | t                    r| dfS t          rt          | t                    r| dfS d | j        D             }| j        rg }|D ]}t          |t                    r|                    |           -t          |t                    rB|	                    d          dk    r)|                    |	                    dd                     |rd
                    |          nt          |          }t          |          d}| j        t          | j                  }||fS )a  Convert MCP MCPToolCallResult to LangChain tool result format.

    Converts MCP content blocks to LangChain content blocks:
    - TextContent -> {"type": "text", "text": ...}
    - ImageContent -> {"type": "image", "base64": ..., "mime_type": ...}
    - ResourceLink (image/*) -> {"type": "image", "url": ..., "mime_type": ...}
    - ResourceLink (other) -> {"type": "file", "url": ..., "mime_type": ...}
    - EmbeddedResource (text) -> {"type": "text", "text": ...}
    - EmbeddedResource (blob) -> {"type": "image", ...} or {"type": "file", ...}
    - AudioContent -> raises NotImplementedError

    Args:
        call_tool_result: The result from calling an MCP tool. Can be either
            a CallToolResult (MCP format), a ToolMessage (LangChain format),
            or a Command (LangGraph format, if langgraph is installed).

    Returns:
        A tuple containing:
        - The content: either a string (single text), list of content blocks,
          ToolMessage, or Command
        - The artifact: MCPToolArtifact with structured_content if present,
          otherwise None

    Raises:
        ToolException: If the tool call resulted in an error.
        NotImplementedError: If AudioContent is encountered.
    Nc                 ,    g | ]}t          |          S r6   )rK   ).0r9   s     r8   
<listcomp>z-_convert_call_tool_result.<locals>.<listcomp>   s0     3 3 3 	)113 3 3r7   rH   r<    
)r.   )r@   r	   LANGGRAPH_PRESENTr+   r9   isErrorr4   appendr3   getjoinr   structuredContentr-   )rL   tool_contenterror_partsitem	error_msgartifacts         r8   _convert_call_tool_resultr^      sh   @ "K00 &%%  &Z(8'BB &%%3 3'/3 3 3L
  	'  	9 	9D$$$ 9""4((((D$'' 9DHHV,<,<,F,F""488FB#7#7888.9PDIIk***s<?P?P	I&&& (,H)5"/A
 
 
 !!r7   base_handlertool_interceptorsc                     | }|rWt          |          D ]G}|}||fdt          dt          dt          t          gt          t
                   f         dt
          fd}|}H|S )ag  Build composed handler chain with interceptors in onion pattern.

    Args:
        base_handler: Innermost handler executing the actual tool call.
        tool_interceptors: Optional list of interceptors to wrap the handler.

    Returns:
        Composed handler with all interceptors applied. First interceptor
        in list becomes outermost layer.
    req_interceptor_handlerr:   c                 *   K    || |           d {V S Nr6   )rb   rc   rd   s      r8   wrapped_handlerz1_build_interceptor_chain.<locals>.wrapped_handler   s,       *\#x888888888r7   )reversedr&   r(   r   r   r'   )r_   r`   handlerinterceptorcurrent_handlerrg   s         r8   _build_interceptor_chainrl      s     G &#$566 	& 	&K%O 5@ $9 9'919 #'()4E*FF9 #9 9 9 9 &GGNr7   sessionc                    K   d}g }d}	 |dz  }|t           k    rd}t          |          |                     |           d{V }|j        r|                    |j                   |j        sn|j        }n|S )a  List all available tools from an MCP session with pagination support.

    Args:
        session: The MCP client session.

    Returns:
        A list of all available MCP tools.

    Raises:
        RuntimeError: If maximum iterations exceeded while listing tools.
    Nr   T   z3Reached max of 1000 iterations while listing tools.)cursor)MAX_ITERATIONSRuntimeError
list_toolstoolsextend
nextCursor)rm   current_cursor	all_tools
iterationsrJ   list_tools_page_results         r8   _list_all_toolsr{      s       "&N!IJ;a
&&GCs###'.'9'9'9'P'P!P!P!P!P!P!P!' 	;39::: &0 	/:!;" r7   
connection	callbacksr`   server_nametool_name_prefixtoolr}   r~   r   r   c          
           d}t          |          	 ddt          t          dz  t                      f         dt          t
          t          f         dt          t          t          dz  f         f fd}t          dd          }	j        j                                        ni }
|	d|	ini }	i |
|	pd}j        }|rr d	j         }t          |j        pd
j        |d|          S )a  Convert an MCP tool to a LangChain tool.

    NOTE: this tool can be executed only in a context of an active MCP client session.

    Args:
        session: MCP client session
        tool: MCP tool to convert
        connection: Optional connection config to use to create a new session
                    if a `session` is not provided
        callbacks: Optional callbacks for handling notifications and events
        tool_interceptors: Optional list of interceptors for tool call processing
        server_name: Name of the server this tool belongs to
        tool_name_prefix: If `True` and `server_name` is provided, the tool name will be
            prefixed w/ server name (e.g., `"weather_search"` instead of `"search"`)

    Returns:
        a LangChain tool

    N8Either a session or a connection config must be providedruntime	argumentsr:   c                 @  K   *                     t          	j                            nt                      dt          dt
          f
fd}t          |          }t	          j        |	pdd|           } ||           d{V }t          |          S )	a  Execute tool call with interceptor chain and return formatted result.

        Args:
            runtime: LangGraph tool runtime if available, otherwise None.
            **arguments: Tool arguments as keyword args.

        Returns:
            A tuple of (content, artifact) where:
            - content: string, list of strings/content blocks, ToolMessage, or Command
            - artifact: MCPToolArtifact with structured_content if present, else None
        N)r   	tool_namecontextrequestr:   c                 \  K   | j         }| j        }}| j        }|<:t                    }d         dv r!                    di           }i |||d<   |}d}|d}t          |          t          |          4 d{V 	 }	|	                                 d{V  	 |	                    ||j	                   d{V }
n# t          $ r}|}Y d}~nd}~ww xY wddd          d{V  n# 1 d{V swxY w Y   ||n#                    ||j	                   d{V }
|
S )a  Execute the actual MCP tool call with optional session creation.

            Args:
                request: Tool call request with name, args, headers, and context.

            Returns:
                MCPToolCallResult from MCP SDK.

            Raises:
                ValueError: If neither session nor connection provided.
                RuntimeError: If tool call returns None.
            N	transport)ssehttpstreamable_httpzstreamable-httpheaders-Either session or connection must be providedmcp_callbacks)progress_callback)nameargsr   r3   rV   rI   r*   
initialize	call_toolr   	Exception)r   r   	tool_argseffective_connectionmodified_headersupdated_connectionexisting_headerscaptured_exceptionrJ   tool_sessionrL   er}   r   rm   s               r8   execute_toolzKconvert_mcp_tool_to_langchain_tool.<locals>.call_tool.<locals>.execute_toolI  s       II#-   '+
0F%)*%5%5"k* /   (2~~i'D'D$5*5*5&y1 ,>(!%'/IC$S//))(   / / / / / / / /!&11333333333/1=1G1G%%.;.M 2H 2 2 , , , , , ,((
 % / / /-.******// / / / / / / / / / / / / / / / / / / / / / / / / / /( &1,, 2 *1):):&3&E *; * * $ $ $ $ $ $  $#s<   C3$#CC3
CCC3CC33
C= C=unknown)r   r   r   r   r   )to_mcp_formatr#   r   r%   r&   r'   rl   r^   )r   r   r   ri   r   rL   r   r~   r}   r   rm   r   r`   s         @r8   r   z5convert_mcp_tool_to_langchain_tool.<locals>.call_tool1  s     & $ ##'K49UUU $     	H	$(: H	$?P H	$ H	$ H	$ H	$ H	$ H	$ H	$ H	$V +<9JKK$#0y
 
 
 ")!1!1111111()9:::r7   meta_meta_rQ   content_and_artifact)r   descriptionargs_schema	coroutineresponse_formatmetadatarf   )rI   r   objectr   r3   r4   r   tupleConvertedToolResultr-   getattrannotations
model_dumpr   r   r   inputSchema)rm   r   r}   r~   r`   r   r   rJ   r   r   baser   lc_tool_names   ``````       r8   "convert_mcp_tool_to_langchain_toolr     sy   : :-Hoo @Dm; m;6D=/*;*;;<m;#s(^m; 
"Od$::	;m; m; m; m; m; m; m; m; m; m; m;^ 4&&D,0,<,H4&&(((bD".GT??BD$$'4H 9L 4K 4%33	33$*$.   r7   c                   K    d}t          |          $                    t                              nt                      } d}t          |          t	          |          4 d{V 	 }|                                 d{V  t          |           d{V }	ddd          d{V  n# 1 d{V swxY w Y   nt                      d{V }	 fd|	D             S )a  Load all available MCP tools and convert them to LangChain [tools](https://docs.langchain.com/oss/python/langchain/tools).

    Args:
        session: The MCP client session. If `None`, connection must be provided.
        connection: Connection config to create a new session if session is `None`.
        callbacks: Optional `Callbacks` for handling notifications and events.
        tool_interceptors: Optional list of interceptors for tool call processing.
        server_name: Name of the server these tools belong to.
        tool_name_prefix: If `True` and `server_name` is provided, tool names will be
            prefixed w/ server name (e.g., `"weather_search"` instead of `"search"`).

    Returns:
        List of LangChain [tools](https://docs.langchain.com/oss/python/langchain/tools).
            Tool annotations are returned as part of the tool metadata object.

    Raises:
        ValueError: If neither session nor connection is provided.
    Nr   )r   r   r   r   c                 <    g | ]}t          |           S )r|   )r   )rO   r   r~   r}   r   rm   r`   r   s     r8   rP   z"load_mcp_tools.<locals>.<listcomp>  sO         	+!/#-	
 	
 	
  r7   )rI   r   r#   r%   r*   r   r{   )
rm   r}   r~   r`   r   r   rJ   r   r   rt   s
   ``````    r8   load_mcp_toolsr     s     6 :-Hoo   	K(P(P(PQQQ__  ACS//!!m
 
 
 	8 	8 	8 	8 	8 	8 	8 	8))+++++++++),77777777E		8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 &g........            s   ?0C
CCc                     dt           dt          fdfdt          | j                                                  D             S )zExtract field names with InjectedToolArg annotation from tool schema.

    Args:
        tool: LangChain tool to inspect.

    Returns:
        List of field names marked as injected arguments.
    type_r:   c                 ^    t          d t          |           dd         D                       S )z2Check if type annotation contains InjectedToolArg.c              3      K   | ]C}t          |t                    p)t          |t                    ot          |t                    V  Dd S rf   )r@   r   rH   
issubclass)rO   args     r8   	<genexpr>zD_get_injected_args.<locals>._is_injected_arg_type.<locals>.<genexpr>   sd       
 
  sO,, L3%%J*S/*J*J
 
 
 
 
 
r7   ro   N)anyr   )r   s    r8   _is_injected_arg_typez1_get_injected_args.<locals>._is_injected_arg_type  sA     
 
  qrr*
 
 
 
 
 	
r7   c                 0    g | ]\  }} |          |S r6   r6   )rO   field
field_infor   s      r8   rP   z&_get_injected_args.<locals>.<listcomp>  s>       E:  ,,  r7   )rH   boolr   r   items)r   r   s    @r8   _get_injected_argsr     sg    
T 
d 
 
 
 
   !>t?O!P!P!V!V!X!X   r7   c                 (    t           j        t                    sd}t          |           j                                        }d  j        j                                        D             }t           j	         dfi |dt          i}t          |          }dt          t          t          f         dt          f fd}t                     }t!          |          d	k    rd
}t#          |          t%          | j	         j        ||d          S )a  Convert LangChain tool to FastMCP tool.

    Args:
        tool: LangChain tool to convert.

    Returns:
        FastMCP tool equivalent.

    Raises:
        TypeError: If args_schema is not BaseModel subclass.
        NotImplementedError: If tool has injected arguments.
    ziTool args_schema must be a subclass of pydantic.BaseModel. Tools with dict args schema are not supported.c                 (    i | ]\  }}||j         |fS r6   )
annotation)rO   r   r   s      r8   
<dictcomp>zto_fastmcp.<locals>.<dictcomp>"  s6       E: 	
%z2  r7   	Arguments__base__)	arg_modelr   r:   c                  >   K                        |            d {V S rf   )ainvoke)r   r   s    r8   fnzto_fastmcp.<locals>.fn-  s+      \\),,,,,,,,,r7   r   z9LangChain tools with injected arguments are not supportedT)r   r   r   
parametersfn_metadatais_async)r   r   r!   	TypeErrortool_call_schemamodel_json_schemamodel_fieldsr   r"   r   r   r   r3   r4   r   r   lenrC   FastMCPToolr   )r   rJ   r   field_definitionsr   r   r   injected_argss   `       r8   
to_fastmcpr     s^    d&	22 = 	 nn&88::J !%!6!C!I!I!K!K   9 #4 ?K  I 333K-d38n - - - - - - - 't,,M
=AI!#&&&Y$   r7   )Mr2   collections.abcr   r   typingr   r   r   r   langchain_core.messagesr	   langchain_core.messages.contentr
   r   r   r   r   r   langchain_core.toolsr   r   r   r   langchain_core.tools.baser   mcpr   mcp.server.fastmcp.toolsr   r   *mcp.server.fastmcp.utilities.func_metadatar   r   	mcp.typesr   r   r   r   r   r   r   r    MCPToolpydanticr!   r"    langchain_mcp_adapters.callbacksr#   r$   r%   #langchain_mcp_adapters.interceptorsr&   r'   r(   langchain_mcp_adapters.sessionsr)   r*   langgraph.typesr+   rS   ImportErrorToolMessageContentBlocklistr   rq   r-   rK   r   r^   rl   r{   r4   r   r   r   r   r   r6   r7   r8   <module>r      si    0 / / / / / / / 6 6 6 6 6 6 6 6 6 6 6 6 / / / / / /                           D C C C C C       8 8 8 8 8 8 Q Q Q Q Q Q Q Q	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 & % % % % % , , , , , , , , V V V V V V V V V V         
 G F F F F F F F''''''    +->>AQQ   F67+EO67+E' ' ' ' 'i ' ' '000 0 0 0f?"'?"
$ 667?" ?" ?" ?"D./;L1MMN/047 !"I.?$@@A   D"= "T'] " " " "R %)"&:>""a a aT!a
a T!	a
 4a /047a ta a a a a aN %)"&:>""= = =T!= T!= 4	=
 /047= t= = 
(^= = = =@X $s)    2/X /+ / / / / / /s   B B%$B%