o
    i                     @  s   d Z ddlmZ ddl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 ddlmZ ddlmZ e	d	ed
ZG dd deee ZG dd deZG dd deZee eB eB ZG dd deZeeB eB ZeeeefZd/ddZd0ddZ d0ddZ!	d1d2d(d)Z"	d1d3d-d.Z#dS )4z&Elicitation utilities for MCP servers.    )annotationsN)Sequence)GenericLiteralTypeVarUnionget_args
get_origin)	BaseModel)ServerSession)	RequestIdElicitSchemaModelT)boundc                   @  s&   e Zd ZU dZdZded< ded< dS )AcceptedElicitationz)Result when user accepts the elicitation.acceptLiteral['accept']actionr   dataN__name__
__module____qualname____doc__r   __annotations__ r   r   M/home/app/Keep/.python/lib/python3.10/site-packages/mcp/server/elicitation.pyr      s   
 r   c                   @     e Zd ZU dZdZded< dS )DeclinedElicitationz*Result when user declines the elicitation.declinezLiteral['decline']r   Nr   r   r   r   r   r         
 r   c                   @  r   )CancelledElicitationz)Result when user cancels the elicitation.cancelzLiteral['cancel']r   Nr   r   r   r   r   r       r   r    c                   @  r   )AcceptedUrlElicitationz0Result when user accepts a URL mode elicitation.r   r   r   Nr   r   r   r   r   r"   '   r   r"   schematype[BaseModel]returnNonec                 C  sZ   | j  D ]%\}}|j}|du s|tju rqt|rqt|r qtd| dt ddS )zCValidate that a Pydantic model only contains primitive field types.NzElicitation schema field 'z' must be a primitive type zw, a sequence of strings (list[str], etc.), or Optional of these types. Nested models and complex types are not allowed.)	Zmodel_fieldsitems
annotationtypesNoneType_is_primitive_field_is_string_sequence	TypeError_ELICITATION_PRIMITIVE_TYPES)r#   
field_nameZ
field_infor(   r   r   r   _validate_elicitation_schema4   s   r0   r(   typeboolc                 C  sX   t | }|r*zt|trt| }t|dko|d tu W S W dS  ty)   Y dS w dS )zMCheck if annotation is a sequence of strings (list[str], Sequence[str], etc).   r   F)r	   
issubclassr   r   lenstrr-   r(   originargsr   r   r   r,   G   s   
r,   c                 C  sD   | t v rdS t| }|tu s|tju r t| }tdd |D S dS )zDCheck if a field is a primitive type allowed in elicitation schemas.Tc                 s  s*    | ]}|t ju p|tv pt|V  qd S N)r)   r*   r.   r,   ).0argr   r   r   	<genexpr>b   s    
z&_is_primitive_field.<locals>.<genexpr>F)r.   r	   r   r)   	UnionTyper   allr7   r   r   r   r+   W   s   r+   sessionr   messager6   type[ElicitSchemaModelT]related_request_idRequestId | None%ElicitationResult[ElicitSchemaModelT]c                   s   t | | }| j|||dI dH }|jdkr)|jdur)||j}t|dS |jdkr1t S |jdkr9t S t	d|j )a)  Elicit information from the client/user with schema validation (form mode).

    This method can be used to interactively ask for additional information from the
    client within a tool's execution. The client might display the message to the
    user and collect a response according to the provided schema. Or in case a
    client is an agent, it might decide how to handle the elicitation -- either by asking
    the user or automatically generating a response.

    For sensitive data like credentials or OAuth flows, use elicit_url() instead.
    )rA   ZrequestedSchemarC   Nr   )r   r   r!   Unexpected elicitation action: )
r0   Zmodel_json_schemaZelicit_formr   contentZmodel_validater   r   r    
ValueError)r@   rA   r#   rC   Zjson_schemaresultZvalidated_datar   r   r   elicit_with_validationi   s    


rJ   urlelicitation_idUrlElicitationResultc                   sZ   | j ||||dI dH }|jdkrt S |jdkrt S |jdkr%t S td|j )a[  Elicit information from the user via out-of-band URL navigation (URL mode).

    This method directs the user to an external URL where sensitive interactions can
    occur without passing data through the MCP client. Use this for:
    - Collecting sensitive credentials (API keys, passwords)
    - OAuth authorization flows with third-party services
    - Payment and subscription flows
    - Any interaction where data should not pass through the LLM context

    The response indicates whether the user consented to navigate to the URL.
    The actual interaction happens out-of-band. When the elicitation completes,
    the server should send an ElicitCompleteNotification to notify the client.

    Args:
        session: The server session
        message: Human-readable explanation of why the interaction is needed
        url: The URL the user should navigate to
        elicitation_id: Unique identifier for tracking this elicitation
        related_request_id: Optional ID of the request that triggered this elicitation

    Returns:
        UrlElicitationResult indicating accept, decline, or cancel
    )rA   rK   rL   rC   Nr   r   r!   rF   )
elicit_urlr   r"   r   r    rH   )r@   rA   rK   rL   rC   rI   r   r   r   rN      s   


rN   )r#   r$   r%   r&   )r(   r1   r%   r2   r:   )
r@   r   rA   r6   r#   rB   rC   rD   r%   rE   )r@   r   rA   r6   rK   r6   rL   r6   rC   rD   r%   rM   )$r   
__future__r   r)   collections.abcr   typingr   r   r   r   r   r	   Zpydanticr
   Zmcp.server.sessionr   Z	mcp.typesr   r   r   r   r    ZElicitationResultr"   rM   r6   intfloatr2   r.   r0   r,   r+   rJ   rN   r   r   r   r   <module>   s.     


-