
    Ki(                       d Z ddlmZ ddl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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 ddlmZ ddl m!Z!  e!e"      Z#erddl$m%Z%  ede&      Z'e G d dee'                Z(e G d d             Z)	 	 	 	 ddZ*ddZ+	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ,	 d	 	 	 	 	 	 	 ddZ-y)z8Sampling types and helper functions for FastMCP servers.    )annotationsN)	dataclass)TYPE_CHECKINGGeneric)ClientCapabilitiesCreateMessageResultCreateMessageResultWithTools	ModelHintModelPreferencesSamplingCapabilitySamplingMessageSamplingToolsCapabilityTextContent
ToolChoiceToolResultContentToolUseContent)CreateMessageRequestParams)Tool)TypeVar)	ToolError)SamplingTool)
get_logger)ContextResultT)defaultc                  0    e Zd ZU dZded<   ded<   ded<   y)	SamplingResulta  Result of a sampling operation.

    Attributes:
        text: The text representation of the result (raw text or JSON for structured).
        result: The typed result (str for text, parsed object for structured output).
        history: All messages exchanged during sampling.
    
str | Nonetextr   resultlist[SamplingMessage]historyN)__name__
__module____qualname____doc____annotations__     g/home/jay/workspace/scripts/.codegraph-venv/lib/python3.12/site-packages/fastmcp/server/sampling/run.pyr   r   '   s     O""r)   r   c                  \    e Zd ZU dZded<   ded<   ed
d       Zedd       Zedd       Zy	)
SampleStepzsResult of a single sampling call.

    Represents what the LLM returned in this step plus the message history.
    2CreateMessageResult | CreateMessageResultWithToolsresponser!   r"   c                j    t        | j                  t              r| j                  j                  dk(  S y)z-True if the LLM is requesting tool execution.toolUseF)
isinstancer.   r	   
stopReason)selfs    r*   is_tool_usezSampleStep.is_tool_use@   s+     dmm%AB==++y88r)   c                    | j                   j                  }t        |t              r&|D ]   }t        |t              s|j
                  c S  yt        |t              r|j
                  S y)z-Extract text from the response, if available.N)r.   contentr1   listr   r   )r3   r6   blocks      r*   r   zSampleStep.textG   s\     --''gt$  &e[1 ::%& -<<r)   c                    | j                   j                  }t        |t              r!|D cg c]  }t        |t              s| c}S t        |t              r|gS g S c c}w )z-Get the list of tool calls from the response.)r.   r6   r1   r7   r   )r3   r6   cs      r*   
tool_callszSampleStep.tool_callsT   sT     --''gt$&H!*Q*GAHH09	 Is   AAN)returnbool)r<   r   )r<   list[ToolUseContent])	r#   r$   r%   r&   r'   propertyr4   r   r;   r(   r)   r*   r,   r,   6   sP    
 A@""  
 
  r)   r,   c                <   | yt        | t              r| S t        | t              rt        t        |       g      S t        | t              rAt        d | D              st        d      t        | D cg c]  }t        |       c}      S t        d      c c}w )z5Convert model preferences to ModelPreferences object.N)name)hintsc              3  <   K   | ]  }t        |t                y w)N)r1   str).0hs     r*   	<genexpr>z+_parse_model_preferences.<locals>.<genexpr>j   s     A!:a%As   z7All elements of model_preferences list must be strings.zLmodel_preferences must be one of: ModelPreferences, str, list[str], or None.)r1   r   rD   r
   r7   all
ValueError)model_preferencesrF   s     r*   _parse_model_preferencesrK   _   s      	%'7	8  	%s	+y6G'H&IJJ	%t	,A/@AAVWWBS&TQya'8&TUUZ
 	
 'Us   3Bc                4   | j                   }| j                  }|j                  t        t	                           }|j                  t        t	        t                                 }|j                  dk(  r|j                  t        d      y|j                  dk(  r7|xr | xs |}|s)|j                  |r|r|st        d      t        d	      yy|j                  t        d
|j                  d      |st        d	      |r|st        d      y)aq  Determine whether to use fallback handler or client for sampling.

    Args:
        context: The MCP context.
        needs_tools: Whether the sampling request requires tool support.

    Returns:
        True if fallback handler should be used, False to use client.

    Raises:
        ValueError: If client lacks required capability and no fallback configured.
    )sampling)
capability)toolsalwaysz?sampling_handler_behavior is 'always' but no handler configuredTfallbackzeClient does not support sampling with tools. The client must advertise the sampling.tools capability.z Client does not support samplingz#Invalid sampling_handler_behavior: z(. Must be 'always', 'fallback', or None.F)	fastmcpsessioncheck_client_capabilityr   r   r   sampling_handler_behaviorsampling_handlerrI   )contextneeds_toolsrR   rS   has_samplinghas_tools_capabilityclient_sufficients          r*   determine_handler_moder\   v   sZ    ooGooG 22%/A/CD 3 L #::%'.E.GH
 ;  ((H4##+Q  		*	*j	8(V+o.UAU ''/<8L$S  !!CDD  
	*	*	61'2S2S1V W5 5
 	
 ;<<	1G
 	

 r)   c                 K   | j                   j                  t        d      | j                  t        d      | j                   j                  |t	        ||||t        |      ||      | j                        }t        j                  |      r
| d{   }t        |t              rt        dt        d|      dd	
      S |S 7 0w)zMake LLM call using the fallback handler.

    Note: This function expects the caller (sample_step) to have validated that
    sampling_handler is set via determine_handler_mode(). The checks below are
    safeguards against internal misuse.
    Nzsampling_handler is Nonezrequest_context is None)systemPromptmessagestemperature	maxTokensmodelPreferencesrO   
toolChoice	assistantr   typer   unknownendTurn)roler6   modelr2   )rR   rV   RuntimeErrorrequest_contextSamplingParamsrK   inspectisawaitabler1   rD   r   r   )	rW   r_   system_promptr`   
max_tokensrJ   	sdk_toolstool_choicer    s	            r*   call_sampling_handlerrt      s     " ''/566&455__--&# 56GH"	
 	F 6" &#"V&9 	
 	
 M s   BCC1Cc                  K   g }| D ]  }|j                  |j                        }|C|j                  t        d|j                  t        dd|j                   d      gd             c	 |j                  |j                         d{   }|j                  t        d|j                  t        dt        |            g	              |S 7 D# t        $ rk}t        j                  d
|j                   d       |j                  t        d|j                  t        dt        |            gd             Y d}~8d}~wt        $ r}t        j                  d
|j                   d       |rd|j                   d}nd|j                   d| }|j                  t        d|j                  t        d|      gd             Y d}~d}~ww xY ww)a  Execute tool calls and return results.

    Args:
        tool_calls: List of tool use requests from the LLM.
        tool_map: Mapping from tool name to SamplingTool.
        mask_error_details: If True, mask detailed error messages from tool execution.
            When masked, only generic error messages are returned to the LLM.
            Tools can explicitly raise ToolError to bypass masking when they want
            to provide specific error messages to the LLM.

    Returns:
        List of tool result content blocks.
    Ntool_resultr   zError: Unknown tool ''re   T)rf   	toolUseIdr6   isError)rf   rx   r6   zError calling sampling tool 'zError executing tool 'z': )getrA   appendr   idr   runinputrD   r   logger	exception	Exception)	r;   tool_mapmask_error_detailstool_resultstool_usetoolresult_valuee
error_texts	            r*   execute_toolsr      s    $ -/L 3||HMM*<!&&kk#!'#8q!I !
"%)XXhnn%==##%*"*++!,&s<?P!Q R'3j G  >  
  #@q!QR##%*"*++!,&s1v!F G $	     #@q!QR%#9(--!JJ#9(--A3!OJ##%*"*++!,&z!J K $	 sW   A(G+C	C
A C
GC	GA D?9G?GA<GGGG)rJ   )ModelPreferences | str | list[str] | Noner<   zModelPreferences | None)rW   r   rX   r=   r<   r=   )rW   r   r_   r!   rp   r   r`   zfloat | Nonerq   intrJ   r   rr   zlist[SDKTool] | Noners   zToolChoice | Noner<   r-   )F)r;   r>   r   zdict[str, SamplingTool]r   r=   r<   zlist[ToolResultContent]).r&   
__future__r   rn   dataclassesr   typingr   r   	mcp.typesr   r   r	   r
   r   r   r   r   r   r   r   r   r   rm   r   SDKTooltyping_extensionsr   fastmcp.exceptionsr   %fastmcp.server.sampling.sampling_toolr   fastmcp.utilities.loggingr   r#   r   fastmcp.server.contextr   rD   r   r   r,   rK   r\   rt   r   r(   r)   r*   <module>r      s>   > "  ! )    C % % ( > 0	H	.
)S
) #WW% # # % % %P
@

.8v00#0 	0
 0 0 A0 $0 #0 80l  %I$I%I I 	Ir)   