
    iE                       d dl mZ d dlmZ d dlmZ d dlmZmZm	Z	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 d d	lmZ d d
lmZ d dlmZ d dlmZ g dZ ee      Z ede      Z  G d de      Z! G d dee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Z(d#dZ)d#dZ*	 	 	 	 	 	 d'dZ+	 d(	 	 	 	 	 d)dZ,d*d Z-d+d!Z.y"),    )annotations)	dataclass)Enum)AnyGenericLiteral
get_origin)CancelledElicitationDeclinedElicitation)	BaseModel)GenerateJsonSchemaJsonSchemaValue)core_schema)TypeVar)compress_schema)
get_logger)get_cached_typeadapter)AcceptedElicitationr
   r   ElicitConfigScalarElicitationTypeget_elicitation_schemahandle_elicit_acceptparse_elicit_response_typeT)defaultc                  <     e Zd ZdZd fdZd fdZd fdZ xZS )ElicitationJsonSchemaa5  Custom JSON schema generator for MCP elicitation that always inlines enums.

    MCP elicitation requires inline enum schemas without $ref/$defs references.
    This generator ensures enums are always generated inline for compatibility.
    Optionally adds enumNames for better UI display when available.
    c                    |d   dk(  r| j                  |      S |d   dk(  r| j                  |      S t        |   |      S )zEOverride to prevent ref generation for enums and handle list schemas.typeenumlist)enum_schemalist_schemasupergenerate_innerselfschema	__class__s     /home/jay/workspace/.worktrees/task-2116-dev1/scripts/.codegraph-venv/lib/python3.12/site-packages/fastmcp/server/elicitation.pyr%   z$ElicitationJsonSchema.generate_inner,   sQ     &>V# ##F++&>V###F++w%f--    c                   |j                  d      }|r5|j                  d      dk(  r!| j                  |      }d|v rd|d   i}d|dS |r+t        |   |      }d|v sd|v sd|v rd|v rd|d   i}d|dS t        |   |      S )	zFGenerate schema for list types, detecting enum items for multi-select.items_schemar   r    oneOfanyOfarrayr   itemsconst)getr"   r$   r%   r#   )r'   r(   r-   r2   items_resultr)   s        r*   r#   z!ElicitationJsonSchema.list_schema9   s    zz.1 L,,V4>$$\2E% %.1   71,?L <'\)l* l*$+\'-B#CL#)  w"6**r+   c                "    t         |   |      S )zGenerate inline enum schema.

        Always generates enum pattern: {"enum": [value, ...]}
        Titled enums are handled separately via dict-based syntax in ctx.elicit().
        )r$   r"   r&   s     r*   r"   z!ElicitationJsonSchema.enum_schema^   s     w"6**r+   )r(   zcore_schema.CoreSchemareturnr   )r(   zcore_schema.ListSchemar7   r   )r(   zcore_schema.EnumSchemar7   r   )__name__
__module____qualname____doc__r%   r#   r"   __classcell__)r)   s   @r*   r   r   $   s    .#+J+ +r+   r   c                  *    e Zd ZU dZdZded<   ded<   y)r   z)Result when user accepts the elicitation.acceptzLiteral['accept']actionr   dataN)r8   r9   r:   r;   r?   __annotations__ r+   r*   r   r   i   s    3 (F(
Gr+   r   c                      e Zd ZU ded<   y)r   r   valueN)r8   r9   r:   rA   rB   r+   r*   r   r   p   s    Hr+   r   c                  0    e Zd ZU dZded<   ded<   ded<   y)	r   a  Configuration for an elicitation request.

    Attributes:
        schema: The JSON schema to send to the client
        response_type: The type to validate responses with (None for raw schemas)
        is_raw: True if schema was built directly (extract "value" from response)
    dict[str, Any]r(   ztype | Noneresponse_typeboolis_rawN)r8   r9   r:   r;   rA   rB   r+   r*   r   r   u   s     Lr+   r   c                &   | t        di ddd      S t        | t              rt        |       S t        | t              rt        |       S t        |       t        u rt        |       S t        |       rt        |       S t        t        |       | d      S )a6  Parse response_type into schema and handling configuration.

    Supports multiple syntaxes:
    - None: Empty object schema, expect empty response
    - dict: {"low": {"title": "..."}} -> single-select titled enum
    - list patterns:
        - [["a", "b"]] -> multi-select untitled
        - [{"low": {...}}] -> multi-select titled
        - ["a", "b"] -> single-select untitled
    - list[X] type annotation: multi-select with type
    - Scalar types (bool, int, float, str, Literal, Enum): single value
    - Other types (dataclass, BaseModel): use directly
    Nobject)r   
propertiesFr(   rG   rI   )r   
isinstancedict_parse_dict_syntaxr!   _parse_list_syntaxr	   _parse_generic_list_is_scalar_type_parse_scalar_typer   rG   s    r*   r   r      s     $B7
 	
 -&!-00-&!-00- D("=11}%!-00 %m4# r+   c                    | t         t        t        t        hv xs5 t	        |       t
        u xs" t        | t              xr t        | t              S )z<Check if response_type is a scalar type that needs wrapping.)
rH   intfloatstrr	   r   rN   r   
issubclassr   rU   s    r*   rS   rS      sI     	$UC00 	Qm$/	Q}d+O
=$0Or+   c                `    | st        d      t        | d      }t        dd|idgddd	      S )
zEParse dict syntax: {"low": {"title": "..."}} -> single-select titled.z#Dict response_type cannot be empty.Fmulti_selectrK   rD   r   rL   requiredNTrM   )
ValueError_dict_to_enum_schemar   )dr"   s     r*   rP   rP      sG    >??&qu=K"K0 	

  r+   c                   t        |       dk(  rJt        | d   t              r7| d   r2t        d | d   D              rt	        dddd| d   ididgd	d
d      S t        |       dk(  r@t        | d   t
              r-| d   r(t        | d   d      }t	        ddd|didgd	d
d      S | rDt        d | D              r2t        t        |          }t        |   }t	        t        |      |d      S t        d|        )z0Parse list patterns: [[...]], [{...}], or [...].   r   c              3  <   K   | ]  }t        |t                y wNrN   rY   .0items     r*   	<genexpr>z%_parse_list_syntax.<locals>.<genexpr>   s     9$
4%9   rK   rD   r0   r    r1   r^   NTrM   r\   c              3  <   K   | ]  }t        |t                y wrf   rg   rh   s     r*   rk   z%_parse_list_syntax.<locals>.<genexpr>   s     9T:dC(9rl   Fz-Invalid list response_type format. Received: )lenrN   r!   allr   rO   ra   r   tupler   r   r`   )lstr"   choice_literalwrappeds       r*   rQ   rQ      s(    	CAs1vt$F9#a&99 &FCPQFCS(TU$I
 
 	
 3x1}CFD1c!f*3q6E &;(OP$I
 
 	
 s9S99 s,'7)'2!
 	
 DSEJ
KKr+   c                B    t         |    }t        t        |      |d      S )z.Parse list[X] type annotation -> multi-select.FrM   r   r   r   rG   rs   s     r*   rR   rR      '    #M2G%g. r+   c                B    t         |    }t        t        |      |d      S )z:Parse scalar types (bool, int, float, str, Literal, Enum).FrM   ru   rv   s     r*   rT   rT      rw   r+   c                   | j                   r5t        |t              rd|vrt        d      t	        t
           |d         S | j                  ft        | j                        }|j                  |      }t        |t              rt	        t
           |j                        S t	        t
           |      S |rt        d|       t	        t        t        t
        f      i       S )a  Handle an accepted elicitation response.

    Args:
        config: The elicitation configuration from parse_elicit_response_type
        content: The response content from the client

    Returns:
        AcceptedElicitation with the extracted/validated data
    rD   z4Elicitation response missing required 'value' field.)r@   z6Elicitation expected an empty response, but received: )rI   rN   rO   r`   r   r   rG   r   validate_pythonr   rD   rY   )configcontenttype_adaptervalidated_datas       r*   r   r     s     }}'4(G7,BSTT"3'WW-=>> '-f.B.BC%55g>n&;<&s+1E1EFF"3'^<< DWIN
 	
 tCH~.B77r+   c                    |rdnd}g }| j                         D ]+  \  }}|j                  d|      }|j                  ||d       - ||i}|sd|d<   |S )a~  Convert dict enum to SEP-1330 compliant schema pattern.

    Args:
        enum_dict: {"low": {"title": "Low Priority"}, "medium": {"title": "Medium Priority"}}
        multi_select: If True, use anyOf pattern; if False, use oneOf pattern

    Returns:
        {"type": "string", "oneOf": [...]} for single-select
        {"anyOf": [...]} for multi-select (used as array items)
    r/   r.   title)r3   r   stringr   )r2   r4   append)	enum_dictr]   pattern_keypatternrD   metadatar   results           r*   ra   ra   )  sj     *'wKG$??, 9xWe,789 *73F!vMr+   c                p    t        |       j                  t              }t        |      }t	        |       |S )zkGet the schema for an elicitation response.

    Args:
        response_type: The type of the response
    )schema_generator)r   json_schemar   r    validate_elicitation_json_schema)rG   r(   s     r*   r   r   B  s<     $M2>>. ? F V$F %V,Mr+   c                   h d}| j                  d      dk7  rt        d| j                  d       d      | j                  di       }|j                         D ]  \  }}|j                  d      }t        |t              r-d|v r<|D cg c]
  }|dk7  s	| }}t        |      dk(  r|d	   }n|j                  d
d      rhd|v rmd|v rrd|v rj|d   }|j                  d      rB|dd }| j                  di       j                  |i       }	d|	v r|	j                  d      }
|
|v rt        d| d| d      d|v sd|v ra|j                  dg       |j                  dg       z   }|D ]5  }d|v sd|v r|j                  d      }||vs"t        d| d| d| d       I|dk(  r|j                  di       }|j                  d      dk(  rt        d| d      d|v rd|v sd|v r;|j                  dg       |j                  dg       z   }|rt        d |D              rt        d| d      |dk(  rt        d| d       ||vst        d| d!| d| d       yc c}w )"aa  Validate that a JSON schema follows MCP elicitation requirements.

    This ensures the schema is compatible with MCP elicitation requirements:
    - Must be an object schema
    - Must only contain primitive field types (string, number, integer, boolean)
    - Must be flat (no nested objects or arrays of objects)
    - Allows const fields (for Literal types) and enum fields (for Enum types)
    - Only primitive types and their nullable variants are allowed

    Args:
        schema: The JSON schema to validate

    Raises:
        TypeError: If the schema doesn't meet MCP elicitation requirements
    >   numberr   booleanintegerr   rK   z7Elicitation schema must be an object schema, got type 'zR'. Elicitation schemas are limited to flat objects with primitive properties only.rL   nullrd   r   nullableFr3   r    z$refz#/$defs/   Nz$defszElicitation schema field 'z' contains a reference 'z\' that could not be validated. Only references to enum types or primitive types are allowed.r.   r/   z' has union type 'z&' which is not a primitive type. Only z$ are allowed in elicitation schemas.r0   r2   z' is an array of objects, but arrays of objects are not allowed. Elicitation schemas must be flat objects with primitive properties only.c              3  $   K   | ]  }d |v  
 yw)r3   NrB   )ri   ss     r*   rk   z3validate_elicitation_json_schema.<locals>.<genexpr>  s     (M!A(Ms   z' is an array, but arrays are only allowed when items are enums (for multi-select). Only enum arrays are supported in elicitation schemas.z|' is an object, but nested objects are not allowed. Elicitation schemas must be flat objects with primitive properties only.z' has type ')r4   	TypeErrorr2   rN   r!   rn   
startswithro   )r(   ALLOWED_TYPESrL   	prop_nameprop_schema	prop_typetref_pathdef_nameref_defref_typeunion_schemasunion_schema
union_typer-   s                  r*   r   r   U  sa     ?M zz&X%EfjjQWFXEY Z^ ^
 	

 L"-J","2"2"4 ^	;OOF+	 i&"(1A1Q&[QA	Ay>Q& )!I__Z/ k! [  [ "6*H"":.#AB< **Wb155hCW$";;v.},,YK7OPXz Zm m  k!W%;'OOGR8;??7TV;WWM - 	l*f.D)--f5
]2#4YK?QR\Q] ^22?@df 	  &??7B7L'830 <_ _  % ,&'\*A , 0 0" =@P@PRA ! !S(M}(M%M ,YK 8r r   ,YK 8[ [  M),YK|I; O**78\^ w^ Bs   	
I%I%N)rG   r   r7   r   )rG   r   r7   rH   )rb   rF   r7   r   )rq   z	list[Any]r7   r   )r{   r   r|   r   r7   zAcceptedElicitation[Any])F)r   zdict[str, dict[str, str]]r]   rH   r7   rF   )rG   ztype[T]r7   rF   )r(   rF   r7   None)/
__future__r   dataclassesr   r    r   typingr   r   r   r	   mcp.server.elicitationr
   r   pydanticr   pydantic.json_schemar   r   pydantic_corer   typing_extensionsr   fastmcp.utilities.json_schemar   fastmcp.utilities.loggingr   fastmcp.utilities.typesr   __all__r8   loggerr   r   r   r   r   r   rS   rP   rQ   rR   rT   r   ra   r   r   rB   r+   r*   <module>r      s   " !  4 4  D % % 9 0 :	 
H	CA+. A+J)WQZ  GAJ     &R *LZ88#&88F @E(8<2&yr+   