
    $j	              
          d 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	m
Z
 ddlZddlmZ  e	d          Zdedefd	Zded
ef         dededefdZe
dee         ded         deeez           fd            Ze
d
ddee         ded         dee         fd            Zdddee         dedee         eeez           z  fdZdS )zAsync utilities for FastMCP.    N)	AwaitableCallable)AnyLiteralTypeVaroverload)run_syncTfnreturnc                     t          | t          j                  r!| j        } t          | t          j                  !t	          j        |           S )a  Check if a callable is a coroutine function, unwrapping functools.partial.

    ``inspect.iscoroutinefunction`` returns ``False`` for
    ``functools.partial`` objects wrapping an async function on Python < 3.12.
    This helper unwraps any layers of ``partial`` before checking.
    )
isinstance	functoolspartialfuncinspectiscoroutinefunction)r   s    e/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/fastmcp/utilities/async_utils.pyis_coroutine_functionr      sH     R*
+
+ W R*
+
+ &r***    .argskwargsc                 V   K   t          t          j        | g|R i |           d{V S )zCall a sync function in a threadpool to avoid blocking the event loop.

    Uses anyio.to_thread.run_sync which properly propagates contextvars,
    making this safe for functions that depend on context (like dependency injection).
    N)run_sync_in_threadpoolr   r   )r   r   r   s      r   call_sync_fn_in_threadpoolr      sC       (	(9"(Nt(N(N(Nv(N(NOOOOOOOOOr   
awaitablesreturn_exceptionsTc                 
   K   d S N r   r   s     r   gatherr"   %   s       "cr   )r   Fc                 
   K   d S r   r    r!   s     r   r"   r"   ,   s       cr   c                 L   K   dgt          |          z  dt          dt          t                   ddf fd}t	          j                    4 d{V }t          |          D ]\  }}|                    |||           	 ddd          d{V  n# 1 d{V swxY w Y   S )a  Run awaitables concurrently and return results in order.

    Uses anyio TaskGroup for structured concurrency.

    Args:
        *awaitables: Awaitables to run concurrently
        return_exceptions: If True, exceptions are returned in results.
                          If False, first exception cancels all and raises.

    Returns:
        List of results in the same order as input awaitables.
    Niawr   c                 f   K   	 | d {V | <   d S # t           $ r}r|| <   n Y d }~d S d }~ww xY wr   )BaseException)r%   r&   eresultsr   s      r   run_atzgather.<locals>.run_atE   si      	!GAJJJ 	 	 	  

 




	s    
0	+0)lenintr   r
   anyiocreate_task_group	enumerate
start_soon)r   r   r+   tgr%   r&   r*   s   `     @r   r"   r"   3   sU       )-vJ'?G 1 $        &(( ) ) ) ) ) ) )Bz** 	) 	)EArMM&!R((((	)) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) Ns   -B
B B)__doc__r   r   collections.abcr   r   typingr   r   r   r   r.   anyio.to_threadr	   r   r
   boolr   r   listr(   r"   r    r   r   <module>r9      s   " "      / / / / / / / / 2 2 2 2 2 2 2 2 2 2 2 2  > > > > > >GCLL	+c 	+d 	+ 	+ 	+ 	+PcP#&P25PP P P P 
"1"t}" 
!m
" " " 
" 
 ),  1u~ 
!W   
 $  1 
!WtA%&&     r   