o
    i#                     @   s  d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZm	Z	 d dl
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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m Z  e !e"Z#ej$dkrpg dng dZ%dZ&de'e(e(f fddZ)G dd deZ*eej+fde*de	fddZ,de(de(fddZ-dej+dfde(de.e( de'e(e(f dB de	dee(B dB f
dd Z/d%d!eeB d"e0ddfd#d$Z1dS )&    N)asynccontextmanager)Path)LiteralTextIO)Process)MemoryObjectReceiveStreamMemoryObjectSendStream)TextReceiveStream)	BaseModelField)terminate_posix_process_tree)FallbackProcesscreate_windows_processget_windows_executable_commandterminate_windows_process_tree)SessionMessagewin32)APPDATA	HOMEDRIVEHOMEPATHLOCALAPPDATAPATHPATHEXTPROCESSOR_ARCHITECTURESYSTEMDRIVE
SYSTEMROOTTEMPUSERNAMEUSERPROFILE)HOMELOGNAMEr   SHELLTERMUSER       @returnc                  C   s<   i } t D ]}tj|}|du rq|drq|| |< q| S )zo
    Returns a default environment object including only environment variables deemed
    safe to inherit.
    Nz())DEFAULT_INHERITED_ENV_VARSosenvironget
startswith)envkeyvalue r.   _/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/mcp/client/stdio/__init__.pyget_default_environment3   s   

r0   c                   @   s~   e Zd ZU eed< 	 eedZee ed< 	 dZe	eef dB ed< 	 dZ
eeB dB ed< 	 dZeed< 	 d	Zed
 ed< dS )StdioServerParameterscommand)default_factoryargsNr+   cwdzutf-8encodingstrict)r7   ignorereplaceencoding_error_handler)__name__
__module____qualname__str__annotations__r   listr4   r+   dictr5   r   r6   r:   r   r.   r.   r.   r/   r1   H   s   
 r1   servererrlogc                   s&  t d\}t d\}z#tj}t|jjdur&i t jnt |jdI dH  W n$ t	yV   |
 I dH  |
 I dH  
 I dH  
 I dH   w  fdd} fdd}t  4 I dH } 4 I dH  || || zq||fV  W  jrz
 j
 I dH  W n	 ty   Y nw zt t   I dH  W d   n1 sw   Y  W n ty   t I dH  Y n	 ty   Y nw |
 I dH  |
 I dH  
 I dH  
 I dH  np jrz
 j
 I dH  W n
 ty   Y nw zt t   I dH  W d   n	1 s&w   Y  W n ty=   t I dH  Y n
 tyF   Y nw |
 I dH  |
 I dH  
 I dH  
 I dH  w W d  I dH  n1 I dH suw   Y  W d  I dH  dS 1 I dH sw   Y  dS )z
    Client transport for stdio: this will connect to a server by spawning a
    process and communicating with it over stdin/stdout.
    r   N)r2   r4   r+   rC   r5   c                     s*   j sJ dzy4 I d H e d} t j jjd2 zJ3 d H W }| | d}| } |D ]6}ztj|}W n t	yX } zt
d |I d H  W Y d }~q/d }~ww t|}|I d H  q/q6 W d   I d H  W d S 1 I d H szw   Y  W d S  tjy   tj I d H  Y d S w )Nz Opened process is missing stdout r6   errors
z+Failed to parse JSONRPC message from server)stdoutr	   r6   r:   splitpoptypesJSONRPCMessagemodel_validate_json	Exceptionlogger	exceptionsendr   anyioClosedResourceErrorlowlevel
checkpoint)bufferchunklineslinemessageexcsession_message)processread_stream_writerrB   r.   r/   stdout_reader   s:   
2z#stdio_client.<locals>.stdout_readerc               	      s    j sJ dzE4 I d H 1 2 z 3 d H W } | jjddd} j |d jjjdI d H  q6 W d   I d H  W d S 1 I d H sFw   Y  W d S  tjy`   tj	
 I d H  Y d S w )NzOpened process is missing stdinT)by_aliasexclude_nonerG   rE   )stdinrZ   model_dump_jsonrQ   encoder6   r:   rR   rS   rT   rU   )r\   json)r]   rB   write_stream_readerr.   r/   stdin_writer   s"   2	z"stdio_client.<locals>.stdin_writer)rR   create_memory_object_stream_get_executable_commandr2   #_create_platform_compatible_processr4   r+   r0   r5   OSErroraclosecreate_task_group
start_soonrb   rN   
fail_afterPROCESS_TERMINATION_TIMEOUTwaitTimeoutError_terminate_process_treeProcessLookupError)rB   rC   read_streamwrite_streamr2   r_   rg   tgr.   )r]   r^   rB   rf   r/   stdio_clienti   s   


\rx   r2   c                 C   s   t jdkr	t| S | S )z
    Get the correct executable command normalized for the current platform.

    Args:
        command: Base command (e.g., 'uvx', 'npx')

    Returns:
        str: Platform-appropriate command
    r   )sysplatformr   )r2   r.   r.   r/   ri      s   

ri   r4   r+   r5   c                    sJ   t jdkrt| ||||I dH }|S tj| g||||ddI dH }|S )z
    Creates a subprocess in a platform-compatible way.

    Unix: Creates process in a new session/process group for killpg support
    Windows: Creates process in a Job Object for reliable child termination
    r   NT)r+   stderrr5   start_new_session)ry   rz   r   rR   open_process)r2   r4   r+   rC   r5   r]   r.   r.   r/   rj      s   

rj   r]   timeout_secondsc                    sB   t jdkrt| |I dH  dS t| tsJ t| |I dH  dS )af  
    Terminate a process and all its children using platform-specific methods.

    Unix: Uses os.killpg() for atomic process group termination
    Windows: Uses Job Objects via pywin32 for reliable child process cleanup

    Args:
        process: The process to terminate
        timeout_seconds: Timeout in seconds before force killing (default: 2.0)
    r   N)ry   rz   r   
isinstancer   r   )r]   r~   r.   r.   r/   rs     s
   
rs   )r$   )2loggingr'   ry   
contextlibr   pathlibr   typingr   r   rR   anyio.lowlevel	anyio.abcr   anyio.streams.memoryr   r   anyio.streams.textr	   pydanticr
   r   	mcp.typesrK   mcp.os.posix.utilitiesr   mcp.os.win32.utilitiesr   r   r   r   mcp.shared.messager   	getLoggerr;   rO   rz   r&   rp   rA   r>   r0   r1   r{   rx   ri   r@   rj   floatrs   r.   r.   r.   r/   <module>   sT    

!q

 