
    $j.                        d Z ddlmZ ddlZddlZddlZddlmZmZ ddlm	Z	m
Z
mZ ddlZddlmZ ddlmZmZ ddlmZ dd	lmZ  ej        e          Ze	rdd
lmZ dZd%dZd&dZd'dZd(d$ZdS ))aY  Background task elicitation support (SEP-1686).

This module provides elicitation capabilities for background tasks running
in Docket workers. Unlike regular MCP requests, background tasks don't have
an active request context, so elicitation requires special handling:

1. Set task status to "input_required" via Redis
2. Send notifications/tasks/status with elicitation metadata
3. Wait for client to send input via tasks/sendInput
4. Resume task execution with the provided input

This uses the public MCP SDK APIs where possible, with minimal use of
internal APIs for background task coordination.
    )annotationsN)datetimetimezone)TYPE_CHECKINGAnycast)ServerSession)get_task_contextget_task_session_idtask_redis_prefix)push_notification)FastMCPi  
task_scope
str | Nonetask_idstrreturntuple[str, str, str]c                H    t          |            d| d}| d| d| dfS )zFBuild (request, response, status) Redis keys for a task's elicitation.:z:elicitz:requestz	:responsez:statusr   )r   r   prefixs      h/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/fastmcp/server/tasks/elicitation.py_elicit_keysr   )   sH    !*--@@@@@F6 4 4 46H6H6HHH    sessionServerSession | Nonemessageschemadict[str, Any]fastmcpr   mcp.types.ElicitResultc                
  K   |j         }|t          d          t          t          j                              }t                      }|'|j        }t          |dd          pt                      }	nt          d          t          ||           \  }
}}|||d}|
                                4 d{V }|                    |                    |
          t          j        |          t                     d{V  |                    |                    |          dt                     d{V  ddd          d{V  n# 1 d{V swxY w Y   t!          j        t$          j                                                  }d| d	|||t          d
z  dd| d	|||||ddid}|	<t*                              d|            t.          j                            dd          S 	 t5          |	||           d{V  n# t6          $ r}t*                              d| |           	 |
                                4 d{V }|                    |                    |
          |                    |                     d{V  ddd          d{V  n# 1 d{V swxY w Y   n# t6          $ r Y nw xY wt.          j                            dd          cY d}~S d}~ww xY wt          }	 |
                                4 d{V }t;          t<          |                    |                    |          g|                     d{V }|r|\  }}t          j         |          }|                    |                    |
          |                    |                     d{V  t.          j                            |!                    dd          |!                    d                    cddd          d{V  S 	 ddd          d{V  n# 1 d{V swxY w Y   n3# t6          $ r&}t*                              d| |           Y d}~nd}~ww xY w	 |
                                4 d{V }|                    |                    |
          |                    |          |                    |                     d{V  ddd          d{V  n# 1 d{V swxY w Y   n3# t6          $ r&}t*          "                    d| |           Y d}~nd}~ww xY wt.          j                            dd          S )a  Send an elicitation request from a background task.

    This function handles the complexity of eliciting user input when running
    in a Docket worker context where there's no active MCP request.

    Args:
        task_id: The background task ID
        session: The MCP ServerSession for this task
        message: The message to display to the user
        schema: The JSON schema for the expected response
        fastmcp: The FastMCP server instance

    Returns:
        ElicitResult containing the user's response

    Raises:
        RuntimeError: If Docket is not available
        McpError: If the elicitation request fails
    Nz}Background task elicitation requires Docket. Ensure 'fastmcp[tasks]' is installed and the server has task-enabled components._fastmcp_state_prefixzCannot determine task scope for elicitation. This typically means elicit_for_task() was called outside a Docket worker context.)
request_idr   r   exwaitingznotifications/tasks/statusinput_requiredi  )taskIdstatusstatusMessage	createdAtlastUpdatedAtttlz$io.modelcontextprotocol/related-task)	requestIdr   requestedSchema)r*   r+   r,   r   elicitation)methodparams_metazLNo session_id available for task %s, cannot deliver elicitation notificationcancelactioncontentzSFailed to queue input_required notification for task %s, cancelling elicitation: %s)timeoutr8   acceptr9   z@BLPOP failed for task %s elicitation, falling back to cancel: %szIFailed to clean up elicitation keys for task %s (will expire via TTL): %s)#_docketRuntimeErrorr   uuiduuid4r
   r   getattrr   r   redissetkeyjsondumpsELICIT_TTL_SECONDSr   nowr   utc	isoformatloggerwarningmcptypesElicitResultr   	Exceptiondeleter   r   blpoploadsgetdebug)r   r   r   r   r!   docketr%   task_contextr   
session_idrequest_keyresponse_key
status_keyelicit_requestrA   	timestampnotification_dictemax_wait_secondsresult_keyresponse_dataresponsecleanup_errors                           r   elicit_for_taskre   /   s     4 _F~_
 
 	
 TZ\\""J#%%L!,
 G4d;;T?R?T?T 	
 a
 
 	
 -9W,M,M)Kz ! N ||~~ 
 
 
 
 
 
 
iiJJ{##J~&&!  
 
 	
 	
 	
 	
 	
 	
 	
 iiJJz""!  
 
 	
 	
 	
 	
 	
 	
 	

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
( X\**4466I.&$"&%,
 
 3!*!((!+&'-   
5 
5
 2 Z	
 	
 	
 y%%Xt%DDDE
,=vFFFFFFFFFF E E E 	a	
 	
 	
	||~~       llJJ{++JJz**                                  
  	 	 	D	y%%Xt%DDDDDDDD#E, *!
<<>> 	 	 	 	 	 	 	U  ZZ--.,          F  &,#m:m44 llJJ{++JJz**         y--#<<(;;$LL33 .  /	 	 	 	 	 	 	 	 	 	 	 	 	 		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	6  
 
 
N	
 	
 	
 	
 	
 	
 	
 	


<<>> 	 	 	 	 	 	 	U,,

;''

<((

:&&        	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	  
 
 
W	
 	
 	
 	
 	
 	
 	
 	

 9!!4!@@@s   5A?E
EE'G? ?
K"	K&J' AJJ'
J	J'"J	#J'&K'
J41K3J44#KK"K"-P( C)P0P( P( 
P  P( #P $P( (
Q2QQS1 6ASS1 
S))S1 ,S)-S1 1
T!;TT!r	   r2   Nonec                  K   	 |                      |d         |d                    d{V }t          |||j        |j        |           d{V  t                              d||j                   dS # t          $ rd}t                              d||           t          ||dd|           d{V }|s!t                              d	|           Y d}~dS Y d}~dS d}~ww xY w)
ah  Relay elicitation from a background task worker to the client.

    Called by the notification subscriber when it detects an input_required
    notification with elicitation metadata. Sends a standard elicitation/create
    request to the client session, then uses handle_task_input() to push the
    response to Redis so the blocked worker can resume.

    Args:
        session: MCP ServerSession
        task_scope: Authorization scope for Redis key construction
        task_id: Background task ID
        elicitation: Elicitation metadata (message, requestedSchema)
        fastmcp: FastMCP server instance
    r   r1   )r   r1   N)r   r   r8   r9   r!   z4Relayed elicitation response for task %s (action=%s)z+Failed to relay elicitation for task %s: %sr6   zGFailed to push cancel response for task %s (worker may block until TTL))elicithandle_task_inputr8   r9   rJ   rT   rO   rK   )r   r   r   r2   r!   r`   r^   successs           r   relay_elicitationrk      s     * ~~	*'(9: & 
 
 
 
 
 
 
 
  !=N
 
 
 	
 	
 	
 	
 	
 	
 	
 	BM	
 	
 	
 	
 	

    DgqQQQ)!
 
 
 
 
 
 
 
 
  	NN/        	 	 	 	 	 	s   A.A4 4
C">ACC"r8   r9   dict[str, Any] | Noneboolc                  K   |j         }|dS t          ||           \  }}}||d}	|                                4 d{V }
|
                    |                    |                     d{V }||                    d          dk    r	 ddd          d{V  dS |
                    |                    |          t          j        |	                     d{V  |
	                    |                    |          t                     d{V  |
                    |                    |          dt                     d{V  ddd          d{V  n# 1 d{V swxY w Y   dS )	a'  Handle input sent to a background task via tasks/sendInput.

    This is called when a client sends input in response to an elicitation
    request from a background task.

    Args:
        task_id: The background task ID
        task_scope: Authorization scope for Redis key construction
        action: The elicitation action ("accept", "decline", "cancel")
        content: The response content (for "accept" action)
        fastmcp: The FastMCP server instance

    Returns:
        True if the input was successfully stored, False otherwise
    NFr7   zutf-8r(   	respondedr&   T)r<   r   rA   rS   rC   decodelpushrD   rE   expirerF   rB   )r   r   r8   r9   r!   rU   _rY   rZ   rc   rA   r+   s               r   ri   ri   '  sp     , _F~u".z7"C"CA|Z  H
 ||~~ 
 
 
 
 
 
 
yyJ!7!788888888>V]]733y@@	
 
 
 
 
 
 
 
 
 
 
 
 
 
 kkJJ|$$Jx  
 
 	
 	
 	
 	
 	
 	
 	

 ll6::l335GHHHHHHHHH iiJJz""!  
 
 	
 	
 	
 	
 	
 	
 	
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
, 4s   AEB+E
E&)E&)r   r   r   r   r   r   )r   r   r   r   r   r   r   r    r!   r   r   r"   )r   r	   r   r   r   r   r2   r    r!   r   r   rf   )r   r   r   r   r8   r   r9   rl   r!   r   r   rm   ) __doc__
__future__r   rD   loggingr>   r   r   typingr   r   r   	mcp.typesrL   r	   fastmcp.server.tasks.contextr
   r   fastmcp.server.tasks.keysr   "fastmcp.server.tasks.notificationsr   	getLogger__name__rJ   fastmcp.server.serverr   rF   r   re   rk   ri    r   r   <module>r      sj    # " " " " "    ' ' ' ' ' ' ' ' + + + + + + + + + +           N N N N N N N N 7 7 7 7 7 7 @ @ @ @ @ @		8	$	$ .------  I I I I}A }A }A }A@5 5 5 5p7 7 7 7 7 7r   