
    "<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$d5dZ%d6dZ&d7d Z'd8d#Z(d5d$Z)d5d%Z*d9d)Z+	 d:d;d.Z,d<d0Z-d=d3Z.d4S )>    )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.
    schemacore_schema.CoreSchemareturnr   c                    |d         dk    r|                      |          S |d         dk    r|                     |          S t                                          |          S )zEOverride to prevent ref generation for enums and handle list schemas.typeenumlist)enum_schemalist_schemasupergenerate_innerselfr   	__class__s     /Users/kimhansen/Desktop/03 Workspace/ceo-agents/chl-effectiveness/mcp-servers/whoop/.venv/lib/python3.11/site-packages/fastmcp/server/elicitation.pyr(   z$ElicitationJsonSchema.generate_inner,   se     &>V## ##F+++&>V####F+++ww%%f---    core_schema.ListSchemac                z   |                     d          }|rA|                     d          dk    r(|                     |          }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   r0   r5   items_resultr+   s        r,   r&   z!ElicitationJsonSchema.list_schema9   s   zz.11  		L,,V44>>$$\22E% %.1    	 7711,??L <''\))l** l**$+\'-B#CL#)   ww""6***r-   core_schema.EnumSchemac                F    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     ww""6***r-   )r   r   r    r   )r   r.   r    r   )r   r9   r    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<   dS )r   z)Result when user accepts the elicitation.acceptzLiteral['accept']actionr   dataN)r;   r<   r=   r>   rB   __annotations__ r-   r,   r   r   i   s0         33 (F((((GGGGGr-   r   c                      e Zd ZU ded<   dS )r   r   valueN)r;   r<   r=   rD   rE   r-   r,   r   r   p   s         HHHHHr-   r   c                  2    e Zd ZU dZded<   ded<   ded<   dS )	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)r;   r<   r=   r>   rD   rE   r-   r,   r   r   u   s=           LLLLLr-   r   rJ   r   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   rJ   rL   )r   
isinstancedict_parse_dict_syntaxr$   _parse_list_syntaxr	   _parse_generic_list_is_scalar_type_parse_scalar_typer   rJ   s    r,   r   r      s     $B77
 
 
 	
 -&& 1!-000-&& 1!-000-  D(("=111}%% 1!-000 %m44#   r-   rK   c                    | t           t          t          t          hv p?t	          |           t
          u p)t          | t                    ot          | t                    S )z<Check if response_type is a scalar type that needs wrapping.)
rK   intfloatstrr	   r   rQ   r"   
issubclassr   rX   s    r,   rV   rV      sR     	$UC00 	Qm$$/	Q}d++O
=$0O0Or-   drI   c                x    | 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_selectrN   rG   r"   rO   requiredNTrP   )
ValueError_dict_to_enum_schemar   )r^   r%   s     r,   rS   rS      se     @>???&qu===K"K0 	
 

    r-   lst	list[Any]c                   t          |           dk    rft          | d         t                    rK| d         rCt          d | d         D                       r$t	          dddd| d         ididgd	d
d          S t          |           dk    rVt          | d         t
                    r;| d         r3t          | d         d          }t	          ddd|didgd	d
d          S | r_t          d | D                       rFt          t          |                    }t          |         }t	          t          |          |d          S t          d|            )z0Parse list patterns: [[...]], [{...}], or [...].   r   c              3  @   K   | ]}t          |t                    V  d S NrQ   r\   .0items     r,   	<genexpr>z%_parse_list_syntax.<locals>.<genexpr>   s,      99$
4%%999999r-   rN   rG   r3   r#   r4   rb   NTrP   r`   c              3  @   K   | ]}t          |t                    V  d S rk   rl   rm   s     r,   rp   z%_parse_list_syntax.<locals>.<genexpr>   s,      99T:dC((999999r-   Fz-Invalid list response_type format. Received: )lenrQ   r$   allr   rR   re   r   tupler   r   rd   )rf   r%   choice_literalwrappeds       r,   rT   rT      s    	CAs1vt$$ 	F 	 99#a&99999 	
  &FCPQFCS(T(TU$I 
 
 
 
 	
 3xx1}}CFD11}c!f}*3q6EEE &;(O(OP$I 
 
 
 
 	
  
s99S99999 
 s,'7)'22!
 
 
 	
 JSJJ
K
KKr-   c                Z    t           |          }t          t          |          |d          S )z.Parse list[X] type annotation -> multi-select.FrP   r   r   r   rJ   rv   s     r,   rU   rU      4    #M2G%g..   r-   c                Z    t           |          }t          t          |          |d          S )z:Parse scalar types (bool, int, float, str, Literal, Enum).FrP   rx   ry   s     r,   rW   rW      rz   r-   configcontentAcceptedElicitation[Any]c                $   | j         rIt          |t                    rd|vrt          d          t	          t
                   |d                   S | j        yt          | 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
    rG   z4Elicitation response missing required 'value' field.)rC   Nz6Elicitation expected an empty response, but received: )rL   rQ   rR   rd   r   r   rJ   r   validate_pythonr   rG   r\   )r|   r}   type_adaptervalidated_datas       r,   r   r     s    } ?'4(( 	UG7,B,BSTTT"3'WW-=>>>> '-f.BCC%55g>>n&;<< 	G&s+1EFFFF"3'^<<<<  
NWNN
 
 	
 tCH~.B7777r-   F	enum_dictdict[str, dict[str, str]]ra   c                    |rdnd}g }|                                  D ]3\  }}|                    d|          }|                    ||d           4||i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:
        {"oneOf": [{"const": "low", "title": "Low Priority"}, ...]} for single-select
        {"anyOf": [{"const": "low", "title": "Low Priority"}, ...]} for multi-select
    r2   r1   title)r6   r   )r5   r7   append)r   ra   pattern_keypatternrG   metadatar   s          r,   re   re   )  so     *6''wKG$??,, 9 9xWe,,778888!!r-   type[T]c                    t          |                               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)rJ   r   s     r,   r   r   >  sM     $M22>>. ?  F V$$F %V,,,Mr-   r   Nonec                   h d}|                      d          dk    r&t          d|                      d           d          |                      di           }|                                D ]g\  }}|                     d          }t          |t                    r,d|v r'd |D             }t          |          d	k    r|d
         }n|                     dd          rsd|v rxd|v r}d|v r|d         }|                    d          rS|dd         }|                      di                                |i           }d|v r|                     d          }	|	|v rt          d| d| d          d|v sd|v ro|                     dg           |                     dg           z   }
|
D ]=}d|v sd|v r|                     d          }||vrt          d| d| d| d          >~|dk    r|                     di           }|                     d          dk    rt          d| d          d|v rd|v sd|v rJ|                     dg           |                     dg           z   }
|
rt          d |
D                       rt          d| d           |dk    rt          d| d!          ||vrt          d| d"| d| d          idS )#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
    >   numberstringbooleanintegerr"   rN   z7Elicitation schema must be an object schema, got type 'zR'. Elicitation schemas are limited to flat objects with primitive properties only.rO   nullc                    g | ]
}|d k    |S )r   rE   )rn   ts     r,   
<listcomp>z4validate_elicitation_json_schema.<locals>.<listcomp>r  s    AAA1Q&[[Q[[[r-   ri   r   nullableFr6   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.r1   r2   z' has union type 'z&' which is not a primitive type. Only z$ are allowed in elicitation schemas.r3   r5   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 V  	dS )r6   NrE   )rn   ss     r,   rp   z3validate_elicitation_json_schema.<locals>.<genexpr>  s&      (M(M!A(M(M(M(M(M(Mr-   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 ')r7   	TypeErrorr5   rQ   r$   rr   
startswithrs   )r   ALLOWED_TYPESrO   	prop_nameprop_schema	prop_typeref_pathdef_nameref_defref_typeunion_schemasunion_schema
union_typer0   s                 r,   r   r   Q  s     ?>>M zz&X%%^fjjQWFXFX ^ ^ ^
 
 	

 L"--J","2"2"4"4 ^ ^	;OOF++	 i&& 	""AA	AAA	y>>Q&& )!I__Z// 	 k!! [   [  "6*H"":.. 	#ABB< **Wb1155hCCW$$";;v..},,mY m mPX m m m   k!!W%;%;'OOGR88;??7TV;W;WWM - 	 	l**f.D.D)--f55
]22#fY f fR\ f f2?f f f   3
  &??7B77L''833_ _ _ _   %% ,&&'\*A*A , 0 0" = =@P@PRA A ! ! S(M(M}(M(M(M%M%M  rY r r r     [Y [ [ [   M))^Y ^ ^I ^ ^*7^ ^ ^   *u^ ^r-   N)rJ   r   r    r   )rJ   r   r    rK   )r^   rI   r    r   )rf   rg   r    r   )r|   r   r}   r   r    r~   )F)r   r   ra   rK   r    rI   )rJ   r   r    rI   )r   rI   r    r   )/
__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__r;   loggerr   r   r   r   r   r   rV   rS   rT   rU   rW   r   re   r   r   rE   r-   r,   <module>r      s    " " " " " " ! ! ! ! ! !       4 4 4 4 4 4 4 4 4 4 4 4              D D D D D D D D % % % % % % % % % % % % 9 9 9 9 9 9 0 0 0 0 0 0 : : : : : :	 	 	 
H		GCA+ A+ A+ A+ A+. A+ A+ A+J    )WQZ        GAJ           & & & &R       *L *L *L *LZ      8 8 8 8F @E" " " " "*   &y y y y y yr-   