
    Rmj(                         d Z ddlZddlmZmZ ddlmZ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 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$ dZ%e G d d                      Z&dS )a	  
Experimental request context features.

This module provides the Experimental class which gives access to experimental
features within a request context, such as task-augmented request handling.

WARNING: These APIs are experimental and may change without notice.
    N)	AwaitableCallable)	dataclassfield)Anyoverload)
deprecated)ServerTaskContext)scoped_task_id)TaskSupport)ServerSession)McpError)MODEL_IMMEDIATE_RESPONSE_KEYis_terminal)
METHOD_NOT_FOUNDTASK_FORBIDDENTASK_REQUIREDClientCapabilitiesCreateTaskResult	ErrorDataResultTaskExecutionModeTaskMetadataToolaR  Passing an explicit task_id to run_task is deprecated. A task created with an explicit ID is not associated with the session that created it: any requestor that presents the ID can read its status and result or cancel it, and it never appears in tasks/list. Omit task_id to let the SDK generate an ID associated with the creating session.c                   L   e Zd ZU dZdZedz  ed<    edd          Ze	dz  ed<    edd          Z
edz  ed<    edd          Zedz  ed<   ed	efd
            Zed	efd            Zdddedz  ded	edz  fdZdddeded	edz  fdZdedz  d	efdZeddddeegee         f         dddedz  d	efd            Ze e e!          dddeegee         f         dededz  d	efd                        Zddddeegee         f         dedz  dedz  d	efdZdS )Experimentala  
    Experimental features context for task-augmented requests.

    Provides helpers for validating task execution compatibility and
    running tasks with automatic lifecycle management.

    WARNING: This API is experimental and may change without notice.
    Ntask_metadataF)defaultrepr_client_capabilities_session_task_supportreturnc                     | j         duS )z(Check if this request is task-augmented.N)r   selfs    o/home/thesage/.hermes/hermes-agent/venv/lib/python3.11/site-packages/mcp/server/experimental/request_context.pyis_taskzExperimental.is_task=   s     !--    c                 0    | j         dS | j         j        duS )z*Check if the client declared task support.NF)r    tasksr%   s    r'   client_supports_tasksz"Experimental.client_supports_tasksB   s#     $,5(.d::r)   Traise_errortool_task_moder.   c                    |pt           }d}|t          k    r| j        st          t          d          }n(|t           k    r| j        rt          t          d          }||rt          |          |S )a  
        Validate that the request is compatible with the tool's task execution mode.

        Per MCP spec:
        - "required": Clients MUST invoke as task. Server returns -32601 if not.
        - "forbidden" (or None): Clients MUST NOT invoke as task. Server returns -32601 if they do.
        - "optional": Either is acceptable.

        Args:
            tool_task_mode: The tool's execution.taskSupport value
                ("forbidden", "optional", "required", or None)
            raise_error: If True, raises McpError on validation failure. If False, returns ErrorData.

        Returns:
            None if valid, ErrorData if invalid and raise_error=False

        Raises:
            McpError: If invalid and raise_error=True
        Nz,This tool requires task-augmented invocation)codemessagez4This tool does not support task-augmented invocation)r   r   r(   r   r   r   )r&   r/   r.   modeerrors        r'   validate_task_modezExperimental.validate_task_modeI   s    4 /"&=   %F  EE ^###%N  E
 5//!r)   toolc                Z    |j         r|j         j        nd}|                     ||          S )a  
        Validate that the request is compatible with the given tool.

        Convenience wrapper around validate_task_mode that extracts the mode from a Tool.

        Args:
            tool: The Tool definition
            raise_error: If True, raises McpError on validation failure.

        Returns:
            None if valid, ErrorData if invalid and raise_error=False
        Nr-   )	executiontaskSupportr5   )r&   r6   r.   r3   s       r'   validate_for_toolzExperimental.validate_for_toolw   s3    $ .2^Et~))&&t&EEEr)   c                 @    |pt           }|t          k    r	| j        sdS dS )a  
        Check if this client can use a tool with the given task mode.

        Useful for filtering tool lists or providing warnings.
        Returns False if tool requires "required" but client doesn't support tasks.

        Args:
            tool_task_mode: The tool's execution.taskSupport value

        Returns:
            True if the client can use this tool, False otherwise
        FT)r   r   r,   )r&   r/   r3   s      r'   can_use_toolzExperimental.can_use_tool   s+     /=  )C 5tr)   )task_idmodel_immediate_responseworkr=   r>   c                
   K   d S N r&   r?   r=   r>   s       r'   run_taskzExperimental.run_task   s       3r)   )r>   c                
   K   d S rA   rB   rC   s       r'   rD   zExperimental.run_task   s       3r)   c                R  K   |!t          j        t          t          d           | j        t          d          | j        t          d          | j        t          d          | j        }|j        }|$| j        j	        }|j
        }|t          |          }|j                            | j        |           d{V }t          ||j        | j        |j        |j                  dfd	}	|                    |	           d}
|	t$          |i}
t'          dd
|i|
rd|
ini S )aV	  
        Create a task, spawn background work, and return CreateTaskResult immediately.

        This is the recommended way to handle task-augmented tool calls. It:
        1. Creates a task in the store
        2. Spawns the work function in a background task
        3. Returns CreateTaskResult immediately

        The work function receives a ServerTaskContext with:
        - elicit() for sending elicitation requests
        - create_message() for sampling requests
        - update_status() for progress updates
        - complete()/fail() for finishing the task

        When work() returns a Result, the task is auto-completed with that result.
        If work() raises an exception, the task is auto-failed.

        Generated task IDs embed the session's task scope so that the default
        task handlers only serve the task to the session that created it. An
        explicitly provided `task_id` is used verbatim and is not associated
        with the session, so any session can access it through the default
        handlers; passing one is deprecated for that reason.

        Args:
            work: Async function that does the actual work
            task_id: Deprecated. Optional task ID, used verbatim and not
                associated with the creating session. Omit it to let the SDK
                generate one.
            model_immediate_response: Optional string to include in _meta as
                io.modelcontextprotocol/model-immediate-response

        Returns:
            CreateTaskResult to return to the client

        Raises:
            RuntimeError: If task support is not enabled or task_metadata is missing

        Example:
            @server.call_tool()
            async def handle_tool(name: str, args: dict):
                ctx = server.request_context

                async def work(task: ServerTaskContext) -> CallToolResult:
                    result = await task.elicit(
                        message="Are you sure?",
                        requestedSchema={"type": "object", ...}
                    )
                    confirmed = result.content.get("confirm", False)
                    return CallToolResult(content=[TextContent(text="Done" if confirmed else "Cancelled")])

                return await ctx.experimental.run_task(work)

        WARNING: This API is experimental and may change without notice.
        N   )
stacklevelzHTask support not enabled. Call server.experimental.enable_tasks() first.zSession not available.zgRequest is not task-augmented (no task field in params). The client must send a task-augmented request.)taskstoresessionqueuehandlerr#   c                  Z  K   	             d {V } t          j        j                  s                    |            d {V  d S d S # t          $ rR}t          j        j                  s.                    t          |                     d {V  Y d }~d S Y d }~d S d }~ww xY wrA   )r   rI   statuscomplete	Exceptionfailstr)resultetask_ctxr?   s     r'   executez&Experimental.run_task.<locals>.execute  s     0#tH~~------"8=#788 4"++F333333333334 4 0 0 0"8=#788 0"--A///////////////0 0 0 0 0 00s   AA 
B*AB%%B*rI   _meta)r#   NrB   )warningswarnEXPLICIT_TASK_ID_DEPRECATIONDeprecationWarningr"   RuntimeErrorr!   r   
task_group_experimentaltask_session_scoper   rJ   create_taskr
   rL   rM   
start_soonr   r   )r&   r?   r=   r>   supportr^   featuressession_scoperI   rW   metarV   s    `         @r'   rD   zExperimental.run_task   s     z M68JWXYYYY%ijjj= 7888%A  
 $'
?}2H$7M((77]..t/A7KKKKKKKK$-M-O
 
 
	0 	0 	0 	0 	0 	0 	0 	g&&&&*#/02JKDMMTM-Lgt__"MMMr)   )"__name__
__module____qualname____doc__r   r   __annotations__r   r    r   r!   r   r"   r   propertyboolr(   r,   r   r   r5   r   r:   r<   r   r   r
   r   r   rS   r   rD   r	   r[   rB   r)   r'   r   r   -   s           *.M<$&---6;eDu6U6U6U,t3UUU%*U4e%D%D%DHmd"DDD(-d(G(G(GM;%GGG. . . . X. ;t ; ; ; X; !	, , ,)D0, 	,
 
T	, , , ,d !	F F FF 	F
 
T	F F F F*+<t+C     $ 
 /3  )*If,==> 	
 #&* 
   X Z,-- 04  )*If,==> 	
 #&* 
   .- X #/3lN lN lN)*If,==>lN t	lN
 #&*lN 
lN lN lN lN lN lNr)   r   )'rj   rY   collections.abcr   r   dataclassesr   r   typingr   r   typing_extensionsr	   $mcp.server.experimental.task_contextr
   "mcp.server.experimental.task_scoper   $mcp.server.experimental.task_supportr   mcp.server.sessionr   mcp.shared.exceptionsr   %mcp.shared.experimental.tasks.helpersr   r   	mcp.typesr   r   r   r   r   r   r   r   r   r   r[   r   rB   r)   r'   <module>ry      s     / / / / / / / / ( ( ( ( ( ( ( (                 ( ( ( ( ( ( B B B B B B = = = = = = < < < < < < , , , , , , * * * * * * [ [ [ [ [ [ [ [                       !  oN oN oN oN oN oN oN oN oN oNr)   