
    )`i^              
       &   d dl 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mZmZ d dlZd dl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mZmZ d dl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)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0  ede$e/          Z1 ede%e0          Z2 ede#e.          Z3 ede$e/          Z4 ede          Z5 ede#e.          Z6e7e8z  Z9 G d de          Z: G d dee4e2f                   Z; G d dee1e3e2e4e6f                   Z<dS )    N)Callable)AsyncExitStack)	timedelta)TracebackType)AnyGenericProtocolTypeVar)MemoryObjectReceiveStreamMemoryObjectSendStream)	BaseModel)Self)McpError)MessageMetadataServerMessageMetadataSessionMessage)ResponseRouter)CONNECTION_CLOSEDINVALID_PARAMSCancelledNotificationClientNotificationClientRequestClientResult	ErrorDataJSONRPCErrorJSONRPCMessageJSONRPCNotificationJSONRPCRequestJSONRPCResponseProgressNotificationRequestParamsServerNotificationServerRequestServerResultSendRequestTSendResultTSendNotificationTReceiveRequestTReceiveResultT)boundReceiveNotificationTc                   6    e Zd ZdZdededz  dedz  ddfdZdS )ProgressFnTz-Protocol for progress notification callbacks.progresstotalNmessagereturnc                 
   K   d S N )selfr.   r/   r0   s       f/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/mcp/shared/session.py__call__zProgressFnT.__call__2   s      s    )__name__
__module____qualname____doc__floatstrr7   r4   r8   r6   r-   r-   /   sV        77&+dl=@4Z	     r8   r-   c                       e Zd ZdZ	 ddedej        dz  deddded	ge	f         d
e
ddfdZddZdee         dz  dedz  dedz  ddfdZdeez  ddfdZddZedefd            Zedefd            ZdS )RequestRespondera  Handles responding to MCP requests and manages request lifecycle.

    This class MUST be used as a context manager to ensure proper cleanup and
    cancellation handling:

    Example:
        with request_responder as resp:
            await resp.respond(result)

    The context manager ensures:
    1. Proper cancellation scope setup and cleanup
    2. Request completion tracking
    3. Cleanup of in-flight requests
    N
request_idrequest_metarequestsessionzBaseSession[
            SendRequestT,
            SendNotificationT,
            SendResultT,
            ReceiveRequestT,
            ReceiveNotificationT
        ]on_complete.RequestResponder[ReceiveRequestT, SendResultT]message_metadatar1   c                     || _         || _        || _        || _        || _        d| _        t          j                    | _        || _	        d| _
        d S )NF)rA   rB   rC   rG   _session
_completedanyioCancelScope_cancel_scope_on_complete_entered)r5   rA   rB   rC   rD   rE   rG   s          r6   __init__zRequestResponder.__init__G   sT     %( 0".00'r8   c                 v    d| _         t          j                    | _        | j                                         | S )zBEnter the context manager, enabling request cancellation tracking.T)rO   rK   rL   rM   	__enter__r5   s    r6   rR   zRequestResponder.__enter__`   s4    ".00$$&&&r8   exc_typeexc_valexc_tbc                 .   	 | j         r|                     |            d| _        | j        st	          d          | j                            |||           dS # d| _        | j        st	          d          | j                            |||           w xY w)zFExit the context manager, performing cleanup and notifying completion.FNo active cancel scopeN)rJ   rN   rO   rM   RuntimeError__exit__r5   rT   rU   rV   s       r6   rZ   zRequestResponder.__exit__g   s    	C (!!$'''!DM% ="#;<<<'''6BBBBB "DM% ="#;<<<'''6BBBBs   A ;Bresponsec                    K   | j         st          d          | j        r
J d            | j        s0d| _        | j                            | j        |           d{V  dS dS )zSend a response for this request.

        Must be called within a context manager block.
        Raises:
            RuntimeError: If not used within a context manager
            AssertionError: If request was already responded to
        2RequestResponder must be used as a context managerzRequest already responded toTrA   r\   N)rO   rY   rJ   	cancelledrI   _send_responserA   )r5   r\   s     r6   respondzRequestResponder.respondw   s       } 	USTTT?BB$BBB"~ 	"DO-..?X /           	 	r8   c                   K   | j         st          d          | j        st          d          | j                                         d| _        | j                            | j        t          ddd                     d{V  dS )	z-Cancel this request and mark it as completed.r^   rX   Tr   zRequest cancelledNcoder0   datar_   )	rO   rY   rM   cancelrJ   rI   ra   rA   r   rS   s    r6   rg   zRequestResponder.cancel   s      } 	USTTT! 	97888!!###m**A/BNNN + 
 
 	
 	
 	
 	
 	
 	
 	
 	
 	
r8   c                 "    | j          o| j         S r3   )rJ   r`   rS   s    r6   	in_flightzRequestResponder.in_flight   s    ?"94>'99r8   c                     | j         j        S r3   )rM   cancel_calledrS   s    r6   r`   zRequestResponder.cancelled   s    !//r8   r3   )r1   rF   r1   N)r9   r:   r;   r<   	RequestIdr!   Metar(   r   r   r   rP   rR   typeBaseExceptionr   rZ   r&   r   rb   rg   propertyboolri   r`   r4   r8   r6   r@   r@   7   s        8 -1  $(4/ !	
 OPRUUV * 
   2   C}%,C %C $	C
 
C C C C kI&= $    &
 
 
 
 :4 : : : X: 04 0 0 0 X0 0 0r8   r@   c                      e Zd ZU dZeeeeez           f         e	d<   e
e	d<   eeeeef         f         e	d<   eeef         e	d<   ed         e	d<   	 d1d	eeez           d
ee         dee         dee         dedz  ddfdZdeddfdZdefdZdee         dz  dedz  dedz  dedz  fdZ	 	 	 d2dedee          dedz  de!dedz  de fdZ"	 d1de#dedz  ddfdZ$d ed!ee%z  ddfd"Z&d3d#Z'd$edefd%Z(d&eddfd'Z)d(eeef         ddfd)Z*deddfd*Z+	 	 d4d+e,e
z  d,e-d-e-dz  d&e,dz  ddf
d.Z.d/eeef         ez  ez  ddfd0Z/dS )5BaseSessiona  
    Implements an MCP "session" on top of read/write streams, including features
    like request/response linking, notifications, and progress.

    This class is an async context manager that automatically starts processing
    messages when entered.
    _response_streams_request_id
_in_flight_progress_callbacksr   _response_routersNread_streamwrite_streamreceive_request_typereceive_notification_typeread_timeout_secondsr1   c                     || _         || _        i | _        d| _        || _        || _        || _        i | _        i | _        g | _	        t                      | _        d S )Nr   )_read_stream_write_streamru   rv   _receive_request_type_receive_notification_type_session_read_timeout_secondsrw   rx   ry   r   _exit_stack)r5   rz   r{   r|   r}   r~   s         r6   rP   zBaseSession.__init__   sg     ()!#%9"*C'-A*#% !#)++r8   routerc                 :    | j                             |           dS )a  
        Register a response router to handle responses for non-standard requests.

        Response routers are checked in order before falling back to the default
        response stream mechanism. This is used by TaskResultHandler to route
        responses for queued task requests back to their resolvers.

        WARNING: This is an experimental API that may change without notice.

        Args:
            router: A ResponseRouter implementation
        N)ry   append)r5   r   s     r6   add_response_routerzBaseSession.add_response_router   s!     	%%f-----r8   c                    K   t          j                    | _        | j                                         d {V  | j                            | j                   | S r3   )rK   create_task_group_task_group
__aenter__
start_soon_receive_looprS   s    r6   r   zBaseSession.__aenter__   s]       244))+++++++++##D$6777r8   rT   rU   rV   c                    K   | j                                          d {V  | j        j                                         | j                            |||           d {V S r3   )r   acloser   cancel_scoperg   	__aexit__r[   s       r6   r   zBaseSession.__aexit__   sv       %%''''''''' 	%,,...%//'6JJJJJJJJJr8   rC   result_typerequest_read_timeout_secondsmetadataprogress_callbackc                   K   | j         }|dz   | _         t          j        t          t          z           d          \  }}|| j        |<   |                    ddd          }	|9d|	vri |	d<   d|	d         vri |	d         d<   ||	d         d         d<   || j        |<   	 t          dd	|d
|	}
| j	        
                    t          t          |
          |                     d{V  d}||                                }n | j        | j                                        }	 t          j        |          5  |                                 d{V }ddd           n# 1 swxY w Y   nL# t"          $ r? t%          t'          t(          j        j        d|j        j         d| d                    w xY wt3          |t                    rt%          |j                  |                    |j                  | j                            |d           | j                            |d           |                                 d{V  |                                 d{V  S # | j                            |d           | j                            |d           |                                 d{V  |                                 d{V  w xY w)a>  
        Sends a request and wait for a response. Raises an McpError if the
        response contains an error. If a request read timeout is provided, it
        will take precedence over the session read timeout.

        Do not use this method to emit notifications! Use send_notification()
        instead.
           Tjsonby_aliasmodeexclude_noneNparams_metaprogressToken2.0)jsonrpcidr0   r   z(Timed out while waiting for response to z	. Waited z	 seconds.re   r0   r4   )rv   rK   create_memory_object_streamr   r   ru   
model_dumprx   r   r   sendr   r   total_secondsr   
fail_afterreceiveTimeoutErrorr   r   httpxcodesREQUEST_TIMEOUT	__class__r9   
isinstanceerrormodel_validateresultpopr   )r5   rC   r   r   r   r   rA   response_streamresponse_stream_readerrequest_datajsonrpc_requesttimeoutresponse_or_errors                r6   send_requestzBaseSession.send_request   s       %
%>272STcfrTr2stu2v2v//-<z* ))4fSW)XX(|++)+X&l844424X&w/?IL"7+O<3DD$Z0(	2,    O $)).P_A`A`ks*t*t*tuuuuuuuuu G+76DDFF3?<JJLL%g.. O O.D.L.L.N.N(N(N(N(N(N(N%O O O O O O O O O O O O O O O 
 
 
"[82&092 2&2 2 2  	 	 	
 +\:: L06777"112C2JKK "&&z4888$((T:::!((*********(//1111111111 "&&z4888$((T:::!((*********(//1111111111sL   BI! !E( 5EE( E  E( #E $E( 'I! (A	F11AI! !A,Knotificationrelated_request_idc           	         K   t          d	ddi|                    ddd          }t          t          |          |rt	          |          nd          }| j                            |           d{V  dS )
zk
        Emits a notification, which is a one-way message that does not expect
        a response.
        r   r   Tr   r   )r   Nr   r4   )r   r   r   r   r   r   r   )r5   r   r   jsonrpc_notificationsession_messages        r6   send_notificationzBaseSession.send_notification<  s        3  
  
 
%%t&t%TT 
  
 )"#788Ugq*>PQQQQmq
 
 
  %%o66666666666r8   rA   r\   c           	        K   t          |t                    rQt          d||          }t          t	          |                    }| j                            |           d {V  d S t          d||                    ddd                    }t          t	          |                    }| j                            |           d {V  d S )Nr   r   r   r   r0   Tr   r   )r   r   r   )	r   r   r   r   r   r   r   r   r   )r5   rA   r\   jsonrpc_errorr   jsonrpc_responses         r6   ra   zBaseSession._send_responseQ  s      h	** 	;(:XVVVM,^M5R5RSSSO$))/:::::::::::.**DvTX*YY     
 -^DT5U5UVVVO$))/:::::::::::r8   c                    K    j         4 d {V   j        4 d {V  	  j         2 3 d {V }t          |t                    r                     |           d {V  8t          |j        j        t                    r	  j        	                    |j        j        
                    ddd                    }t          |j        j        j        |j        j        r|j        j        j        nd |  fd|j                  }| j        |j        <                        |           d {V  |j        s                     |           d {V  *# t          $ r}t)          j        d|            t)          j        d|j        j                    t/          d|j        j        j        t1          t2          d	d
                    }t5          t7          |                    } j                            |           d {V  Y d }~d }~ww xY wt          |j        j        t:                    r	  j        	                    |j        j        
                    ddd                    }t          |j        t>                    r@|j        j        j         }| j        v r% j        |         !                                 d {V  nt          |j        tD                    r|j        j        j#        }	|	 j$        v r{ j$        |	         }
	  |
|j        j        j%        |j        j        j&        |j        j        j                   d {V  n,# t          $ r}t)          j'        d|           Y d }~nd }~ww xY w (                    |           d {V                       |           d {V  # t          $ r/}t)          j        d| d|j        j                    Y d }~d }~ww xY w )                    |           d {V  6 nR# tT          j+        $ r t)          j        d           Y n-t          $ r!}t)          j,        d|            Y d }~nd }~ww xY w j-        .                                D ]q\  }}t1          t^          d          }	 |                    t/          d||                     d {V  |0                                 d {V  b# t          $ r Y nw xY w j-        1                                 n#  j-        .                                D ]q\  }}t1          t^          d          }	 |                    t/          d||                     d {V  |0                                 d {V  b# t          $ r Y nw xY w j-        1                                 w xY w	 d d d           d {V  n# 1 d {V swxY w Y   d d d           d {V  d S # 1 d {V swxY w Y   d S )NTr   r   c                 D    j                             | j        d           S r3   )rw   r   rA   )rr5   s    r6   <lambda>z+BaseSession._receive_loop.<locals>.<lambda>t  s    do6I6I!,X\6]6] r8   )rA   rB   rC   rD   rE   rG   zFailed to validate request: z Message that failed validation: r   zInvalid request parameters rd   r   r   z)Progress callback raised an exception: %sz!Failed to validate notification: z. Message was: zRead stream closed by clientz%Unhandled exception in receive loop: zConnection closedr   )2r   r   r   	Exception_handle_incomingr0   rootr   r   r   r   r@   r   r   metar   rw   rA   _received_requestrJ   loggingwarningdebugr   r   r   r   r   r   r   r   r   	requestIdrg   r    r   rx   r.   r/   r   _received_notification_handle_responserK   ClosedResourceError	exceptionru   itemsr   r   clear)r5   r0   validated_request	respondereerror_responser   r   cancelled_idprogress_tokencallbackr   streamr   s   `             r6   r   zBaseSession._receive_loop_  s	     h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/d/%)%6 M= M= M= M= M= M= M='!'955 L="33G<<<<<<<<<<#GO$8.II J="K040J0Y0Y ' 4 ? ?TZim ? n n1 1- )9+2?+?+B#4#9#@.*->-C-J-O-O%)(9(,,],],],]181A	) 	) 	)I ENDOI,@A"&"8"8"C"CCCCCCCC#,#7 G&*&;&;I&F&F F F F F F F F( K K K $O,N1,N,NOOO#M*cW_Ma*c*cddd-9(-#*?#7#:&/)7,H)+'" '" '". . .N /=^TbEcEc.d.d.dO"&"4"9"9/"J"JJJJJJJJJJJJJK" $GO$8:MNN %="+/+J+Y+Y ' 4 ? ?TZim ? n n, ,L  *,*;=RSS J/;/@/G/Q#/4?#B#B*./,*G*N*N*P*P$P$P$P$P$P$P$P $.l.?AU#V#V !.5A5F5M5[N (69Q'Q'Q373KN3[
).2:(0<0A0H0Q0<0A0H0N0<0A0H0P3. 3. -. -. -. -. -. -. -. -.
 09 ). ). ).,3M0[01-. -. -. -. -. -. -. -.).
 '+&A&A,&O&O O O O O O O O&*&;&;L&I&I I I I I I I I(   #O lA l lV]VeVj l l        #33G<<<<<<<<<<[ &7%6^ , > > > <===== O O O !"M!"M"MNNNNNNNNO #'"8">">"@"@  JB%+<FYZZZE$kk,uSX*Y*Y*YZZZZZZZZZ$mmoo--------$    &,,.... #'"8">">"@"@  JB%+<FYZZZE$kk,uSX*Y*Y*YZZZZZZZZZ$mmoo--------$    &,,.....Qh	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/ h	/sR  W#V?PP
APCEP
H	B+H	PH	#P6CN1A MN1
M6	M1	,N11M6	69N1/P1
O*	;$O%	P%O*	*!PT#Q/T1	Q:QTQT4V?ASV?
S&	#V?%S&	&V?5V)9AU?
>V)?
V	V)VV))V?-W#?
W			W#W		W##
W-0W-response_idc                     t          |t                    r8	 t          |          S # t          $ r t	          j        d|d           Y nw xY w|S )a   
        Normalize a response ID to match how request IDs are stored.

        Since the client always sends integer IDs, we normalize string IDs
        to integers when possible. This matches the TypeScript SDK approach:
        https://github.com/modelcontextprotocol/typescript-sdk/blob/a606fb17909ea454e83aab14c73f14ea45c04448/src/shared/protocol.ts#L861

        Args:
            response_id: The response ID from the incoming message.

        Returns:
            The normalized ID (int if possible, otherwise original value).
        zResponse ID z/ cannot be normalized to match pending requests)r   r>   int
ValueErrorr   r   )r5   r   s     r6   _normalize_request_idz!BaseSession._normalize_request_id  sr     k3'' 	oo;''' o o o m{ m m mnnnnnos   & "A
Ar0   c                 2  K   |j         j        }t          |t          t          z            sdS |                     |j                  }t          |t                    r)| j        D ] }|                    ||j	                  r dS !n,|j
        pi }| j        D ]}|                    ||          r dS | j                            |d          }|r|                    |           d{V  dS |                     t!          d|                      d{V  dS )z
        Handle an incoming response or error message.

        Checks response routers first (e.g., for task-related responses),
        then falls back to the normal response stream mechanism.
        Nz.Received response with an unknown request ID: )r0   r   r   r   r   r   r   ry   route_errorr   r   route_responseru   r   r   r   rY   )r5   r0   r   r   r   response_datar   s          r6   r   zBaseSession._handle_response  sg      # $, >?? 	F 0099 dL)) 
	0  %%k4:>> FF
 -1K,=2M0  ((mDD FF '++K>> 	r++d###########''5ofm5o5o(p(pqqqqqqqqqqqr8   r   c                 
   K   dS )z
        Can be overridden by subclasses to handle a request without needing to
        listen on the message stream.

        If the request is responded to within this method, it will not be
        forwarded on to the message stream.
        Nr4   )r5   r   s     r6   r   zBaseSession._received_request  
        r8   c                 
   K   dS )z
        Can be overridden by subclasses to handle a notification without needing
        to listen on the message stream.
        Nr4   )r5   r   s     r6   r   z"BaseSession._received_notification  r   r8   r   r.   r/   c                 
   K   dS )zh
        Sends a progress notification for a request that is currently being
        processed.
        Nr4   )r5   r   r.   r/   r0   s        r6   send_progress_notificationz&BaseSession.send_progress_notification  r   r8   reqc                 
   K   dS )zCA generic handler for incoming messages. Overwritten by subclasses.Nr4   )r5   r   s     r6   r   zBaseSession._handle_incoming!  s      
 	r8   r3   )NNNrl   )NN)0r9   r:   r;   r<   dictrm   r   r   r   __annotations__r   r@   r(   r&   r-   listr   r   r   ro   r+   r   rP   r   r   r   r   rp   r   rr   r   r%   r)   r   r   r'   r   r   ra   r   r   r   r   r   r>   r=   r   r   r4   r8   r6   rt   rt      s          I'=oP\>\']]^^^^Y 0+1M NNOOOOi45555,---- 26, ,.~	/IJ, -^<, #?3	,
 $((<#=, ($., 
, , , ,*.. .T . . . .$    K}%,K %K $	K
 
K K K K" :>$(04J2 J2J2 .)J2 '0$&6	J2
 "J2 '-J2 
J2 J2 J2 J2^ 047 7'7 &,7 
	7 7 7 7*;y ;KR[D[ ;`d ; ; ; ;i/ i/ i/ i/V y    *%rn %r %r %r %r %rN1A/S^B^1_ dh    9M RV     #"
 
c	
 
 t|	

 t
 

 
 
 
o{:;>RRU^^ 
     r8   rt   )=r   collections.abcr   
contextlibr   datetimer   typesr   typingr   r   r	   r
   rK   r   anyio.streams.memoryr   r   pydanticr   typing_extensionsr   mcp.shared.exceptionsr   mcp.shared.messager   r   r   mcp.shared.response_routerr   	mcp.typesr   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r+   r>   r   rm   r-   r@   rt   r4   r8   r6   <module>r     s    $ $ $ $ $ $ % % % % % %             2 2 2 2 2 2 2 2 2 2 2 2   R R R R R R R R       " " " " " " * * * * * * U U U U U U U U U U 5 5 5 5 5 5                                     ( w~}mDDgm\<@@G/1CEWXX '+]MJJ);;;w57IK]^^ #I	    (   h0 h0 h0 h0 h0w;< h0 h0 h0VD D D D D		D D D D Dr8   