
    i&                        d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	 ddlm
Z ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ  G d de      Zy)z2SamplingTool for use during LLM sampling requests.    )annotationsN)Callable)Any)TextContent)Tool)
ConfigDict)ParsedFunction)FunctionTool)
ToolResult)TransformedTool)FastMCPBaseModelc                      e Zd ZU dZded<   dZded<   ded<   d	ed
<   dZded<    ed      ZdddZ	ddZ
edddd	 	 	 	 	 	 	 	 	 dd       Zeddd	 	 	 	 	 	 	 dd       Zy)SamplingToola  A tool that can be used during LLM sampling.

    SamplingTools bundle a tool's schema (name, description, parameters) with
    an executor function, enabling servers to execute agentic workflows where
    the LLM can request tool calls during sampling.

    In most cases, pass functions directly to ctx.sample():

        def search(query: str) -> str:
            '''Search the web.'''
            return web_search(query)

        result = await context.sample(
            messages="Find info about Python",
            tools=[search],  # Plain functions work directly
        )

    Create a SamplingTool explicitly when you need custom name/description:

        tool = SamplingTool.from_function(search, name="web_search")
    strnameN
str | Nonedescriptionzdict[str, Any]
parametersCallable[..., Any]fnFbool
sequentialT)arbitrary_types_allowedc                |   K   |i } | j                   di |}t        j                  |      r
| d{   }|S 7 w)zExecute the tool with the given arguments.

        Args:
            arguments: Dictionary of arguments to pass to the tool function.

        Returns:
            The result of executing the tool function.
        N )r   inspectisawaitable)self	argumentsresults      u/Users/bowang/.openclaw/workspace/ChatDev/.venv/lib/python3.12/site-packages/fastmcp/server/sampling/sampling_tool.pyrunzSamplingTool.run3   sE      I%9%v&!\F "s   1<:<c                Z    t        | j                  | j                  | j                        S )zConvert to an mcp.types.Tool for SDK compatibility.

        This is used internally when passing tools to the MCP SDK's
        create_message() method.
        )r   r   inputSchema)SDKToolr   r   r   )r   s    r!   _to_sdk_toolzSamplingTool._to_sdk_toolD   s(     ((
 	
    )r   r   r   c                   t        j                  |d      }||j                  dk(  rt        d       | |xs |j                  |xs |j                  |j
                  |j                  |      S )a  Create a SamplingTool from a function.

        The function's signature is analyzed to generate a JSON schema for
        the tool's parameters. Type hints are used to determine parameter types.

        Args:
            fn: The function to create a tool from.
            name: Optional name override. Defaults to the function's name.
            description: Optional description override. Defaults to the function's docstring.
            sequential: If True, this tool requires sequential execution and prevents
                parallel execution of all tools in the batch. Set to True for tools
                with shared state, file writes, or other operations that cannot run
                concurrently. Defaults to False.

        Returns:
            A SamplingTool wrapping the function.

        Raises:
            ValueError: If the function is a lambda without a name override.
        T)validatez<lambda>z,You must provide a name for lambda functions)r   r   r   r   r   )r	   from_functionr   
ValueErrorr   input_schemar   )clsr   r   r   r   parseds         r!   r*   zSamplingTool.from_functionP   sl    :  --b4@<FKK:5KLL$#9v'9'9**yy!
 	
r'   )r   r   c                   t        t        t        f      s"t        dt	              j
                   d      dfd}|} | |xs j                  |xs j                  j                  |      S )ae  Create a SamplingTool from a FunctionTool or TransformedTool.

        Reuses existing server tools in sampling contexts. For TransformedTool,
        the tool's .run() method is used to ensure proper argument transformation,
        and the ToolResult is automatically unwrapped.

        Args:
            tool: A FunctionTool or TransformedTool to convert.
            name: Optional name override. Defaults to tool.name.
            description: Optional description override. Defaults to tool.description.

        Raises:
            TypeError: If the tool is not a FunctionTool or TransformedTool.
        z.Expected FunctionTool or TransformedTool, got z8. Only callable tools can be converted to SamplingTools.c                   K   j                  |        d {   }t        |t              r|j                  Nj                  r6j                  j                  d      r|j                  j                  d      S |j                  S |j                  rCt        |j                        dkD  r+|j                  d   }t        |t              r|j                  S |S 7 w)Nzx-fastmcp-wrap-resultr    r   )
r"   
isinstancer   structured_contentoutput_schemagetcontentlenr   text)kwargsr    first_contenttools      r!   wrapperz0SamplingTool.from_callable_tool.<locals>.wrapper   s     88F++F&*-,,8))d.@.@.D.D//  &88<<XFF  &888>>c&..&9A&=$*NN1$5M!-=,111M' ,s   CCC C)r   r   r   r   )r8   r   returnr   )	r1   r
   r   	TypeErrortype__name__r   r   r   )r-   r:   r   r   r;   r   s    `    r!   from_callable_toolzSamplingTool.from_callable_toolz   s    . $ ?@@dATAT@U VI I 	,  "#7t'7'7	
 	
r'   )N)r   zdict[str, Any] | Noner<   r   )r<   r%   )
r   r   r   r   r   r   r   r   r<   r   )r:   zFunctionTool | TransformedToolr   r   r   r   r<   r   )r?   
__module____qualname____doc____annotations__r   r   r   model_configr"   r&   classmethodr*   r@   r   r'   r!   r   r      s    , I"K"Jd;L"

 
  "& '
'
 	'

  '
 '
 
'
 '
R 
  "&<
,<
 	<

  <
 
<
 <
r'   r   )rC   
__future__r   r   collections.abcr   typingr   	mcp.typesr   r   r%   pydanticr   fastmcp.tools.function_parsingr	   fastmcp.tools.function_toolr
   fastmcp.tools.toolr   fastmcp.tools.tool_transformr   fastmcp.utilities.typesr   r   r   r'   r!   <module>rQ      s;    8 "  $  ! %  9 4 ) 8 4c
# c
r'   