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   J/home/ubuntu/.local/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.)	model_fieldsitems
annotationtypesNoneType_is_primitive_field_is_string_sequence	TypeError_ELICITATION_PRIMITIVE_TYPES)r#   
field_name
field_infor)   r   r   r   _validate_elicitation_schema4   s   r2   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   allr9   r   r   r   r,   W   s   r,   sessionr   messager8   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.
    )rC   requestedSchemarE   Nr   )r   r   r!   Unexpected elicitation action: )
r2   model_json_schemaelicit_formr   contentmodel_validater   r   r    
ValueError)rB   rC   r#   rE   json_schemaresultvalidated_datar   r   r   elicit_with_validationi   s    


rR   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
    )rC   rS   rT   rE   Nr   r   r!   rI   )
elicit_urlr   r"   r   r    rN   )rB   rC   rS   rT   rE   rP   r   r   r   rV      s   


rV   )r#   r$   r%   r&   )r)   r3   r%   r4   r<   )
rB   r   rC   r8   r#   rD   rE   rF   r%   rG   )rB   r   rC   r8   rS   r8   rT   r8   rE   rF   r%   rU   )$r   
__future__r   r*   collections.abcr   typingr   r   r   r   r   r	   pydanticr
   mcp.server.sessionr   	mcp.typesr   r   r   r   r    ElicitationResultr"   rU   r8   intfloatr4   r/   r2   r-   r,   rR   rV   r   r   r   r   <module>   s.     


-