
    "<iP                       U 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	 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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 d dl&m'Z' d dl(m)Z) erd dl*m+Z+ d dl,m-Z- d dl.m/Z/ d dl0m1Z1  edd          Z2de3d<    edd          Z4de3d<    edd          Z5de3d<   g dZ6dNd&Z7 ed'(          dOd*            Z8e	dPd.            Z9e	dPd/            Z:dQd1Z; G d2 d3e          Z<dQd4Z= G d5 d6e          Z>dRd8Z? G d9 d:e          Z@dSd<ZA G d= d>e          ZB G d? d@e          Z G dA dBe          ZCdC ZDdD ZEdTdFZFdUdVdKZGdWdMZdS )X    )annotationsN)AsyncGeneratorCallable)AsyncExitStackasynccontextmanager)
ContextVar)	lru_cache)TYPE_CHECKINGAnycastget_type_hints)
Dependency_Dependsget_dependency_parameters)Progress)get_access_token)AuthenticatedUser)AccessToken)request_ctx)Request)_current_http_request)is_class_member_of_type)Docket)WorkerContextFastMCPdocket)defaultzContextVar[Docket | None]_current_docketworkerzContextVar[Worker | None]_current_workerserverz'ContextVar[weakref.ref[FastMCP] | None]_current_server)r   CurrentContextCurrentDocketCurrentFastMCPCurrentWorkerr   r   get_contextget_http_headersget_http_request
get_serverresolve_dependencieswithout_injected_parametersfnr   
kwarg_typetypereturn
str | Nonec                   t          j        |           rt          | d          r| j        } 	 t	          | d          }n!# t
          $ r t          | di           }Y nw xY wt          j        |           }|j        	                                D ]4\  }}|
                    ||j                  }t          ||          r|c S 5dS )a+  Find the name of the kwarg that is of type kwarg_type.

    This is the legacy dependency injection approach, used specifically for
    injecting the Context object when a function parameter is typed as Context.

    Includes union types that contain the kwarg_type, as well as Annotated types.
    __func__T)include_extras__annotations__N)inspectismethodhasattrr6   r   	Exceptiongetattr	signature
parametersitemsget
annotationr   )r0   r1   
type_hintssignameparamrB   s          /Users/kimhansen/Desktop/03 Workspace/ceo-agents/chl-effectiveness/mcp-servers/whoop/.venv/lib/python3.11/site-packages/fastmcp/server/dependencies.py_find_kwarg_by_typerH   ;   s      J 7 7 [8#Bt<<<

 8 8 8R!2B77


8 
B

C~++--  e^^D%*:;;
":z:: 	KKK	4s   ? AAi  )maxsizeCallable[..., Any]c                l    ddl m} t           |          }t                     }t	                      |r                    |           |r'                    |                                           s S t          j	                   }fd|j
                                        D             }t          j        |          }d fd}||_        fdt           d	i                                           D             |_        t           d
d          |_        t           dd          |_        |S )a  Create a wrapper function without injected parameters.

    Returns a wrapper that excludes Context and Docket dependency parameters,
    making it safe to use with Pydantic TypeAdapter for schema generation and
    validation. The wrapper internally handles all dependency resolution and
    Context injection when called.

    Args:
        fn: Original function with Context and/or dependencies

    Returns:
        Async wrapper function without injected parameters
    r   r   c                "    g | ]\  }}|v	|S  rM   ).0rE   rF   excludes      rG   
<listcomp>z/without_injected_parameters.<locals>.<listcomp>t   s.       $4w;N;N;N;N;N    user_kwargsr   r3   c                    K   t          |           4 d {V } di |}t          j        |          r| d {V }|cd d d           d {V  S # 1 d {V swxY w Y   d S )NrM   )r.   r9   isawaitable)rR   resolved_kwargsresultr0   s      rG   wrapperz,without_injected_parameters.<locals>.wrapperz   s     'K88 	 	 	 	 	 	 	OR**/**F"6** &%		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   &A
A Ac                0    i | ]\  }}|v	|d k    ||S )r3   rM   )rN   kvrO   s      rG   
<dictcomp>z/without_injected_parameters.<locals>.<dictcomp>   s:       AqGX 	
1 -rQ   r8   __name__rW   __doc__N)rR   r   r3   r   )fastmcp.server.contextr   rH   r   setaddupdatekeysr9   r>   r?   r@   	Signature__signature__r=   r8   r\   r]   )	r0   r   context_kwargdependency_paramsrD   user_paramsnew_sigrW   rO   s	   `       @rG   r/   r/   T   s    /..... (G44M1"55eeG #M""" 1(--//000 	 
B

C   !$!5!5!7!7  K ,,G      $G   B 1266<<>>  G
 r:y99Gb)T22GONrQ   	argumentsdict[str, Any]$AsyncGenerator[dict[str, Any], None]c           
    r  K   t          |           }|s|W V  dS t          j                            i           }	 t	                      4 d{V }t          j                            |          }	 i }|                                D ]z\  }}||v r||         ||<   	 |                    |           d{V ||<   5# t          $ r9}	t          | dt          |                     }
t          d| d|
           |	d}	~	ww xY wi ||}|W V  t          j                            |           n$# t          j                            |           w xY w	 ddd          d{V  n# 1 d{V swxY w Y   t          j                            |           dS # t          j                            |           w xY w)a  Resolve Docket dependencies for a FastMCP function.

    Sets up the minimal context needed for Docket's Depends() to work:
    - A cache for resolved dependencies
    - An AsyncExitStack for managing context manager lifetimes

    The Docket instance (for CurrentDocket dependency) is managed separately
    by the server's lifespan and made available via ContextVar.

    Note: This does NOT set up Docket's Execution context. If user code needs
    Docket-specific dependencies like TaskArgument(), TaskKey(), etc., those
    will fail with clear errors about missing context.

    Args:
        fn: The function to resolve dependencies for
        arguments: The arguments passed to the function

    Yields:
        Dictionary of resolved dependencies merged with provided arguments
    Nr\   zFailed to resolve dependency 'z' for )r   r   cacher_   r   stackr@   enter_async_contextr<   r=   reprRuntimeErrorreset)r0   ri   rf   cache_tokenrn   stack_tokenresolved	parameter
dependencyerrorfn_namefinal_argumentss               rG   _resolve_fastmcp_dependenciesr{      s     0 2"55  .$$R((K*!## 	2 	2 	2 	2 	2 	2 	2u".,,U33K2+-->-D-D-F-F % %)Iz I--.7	.B+ %494M4M&5 5 / / / / / /++ % % % %")"j$r(("C"C*WYWWgWW $%% #<Y";(";%%%%%$$[1111$$[111117	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2: 	[)))))[))))sk   F  E#0+D,B;:D,;
C>4C99C>>D, E#,!EE#F #
E--F 0E-1F !F6c               F  K   ddl m} t          |           fd|                                D             }t	          | |          4 d{V }t          | |          }|r||vrt                      ||<   |W V  ddd          d{V  dS # 1 d{V swxY w Y   dS )a  Resolve dependencies and inject Context for a FastMCP function.

    This function:
    1. Filters out any dependency parameter names from user arguments (security)
    2. Resolves Docket dependencies
    3. Injects Context if needed
    4. Merges everything together

    The filtering prevents external callers from overriding injected parameters by
    providing values for dependency parameter names. This is a security feature.

    Args:
        fn: The function to resolve dependencies for
        arguments: User arguments (may contain keys that match dependency names,
                  which will be filtered out)

    Yields:
        Dictionary of filtered user args + resolved dependencies + Context

    Example:
        ```python
        async with resolve_dependencies(my_tool, {"name": "Alice"}) as kwargs:
            result = my_tool(**kwargs)
            if inspect.isawaitable(result):
                result = await result
        ```
    r   r   c                $    i | ]\  }}|v	||S rM   rM   )rN   rY   rZ   rf   s      rG   r[   z(resolve_dependencies.<locals>.<dictcomp>   s*    RRR$!Qq@Q7Q7QA7Q7Q7QrQ   N)r1   )r^   r   r   r@   r{   rH   r*   )r0   ri   r   	user_argsrU   re   rf   s         @rG   r.   r.      sZ     > /.....
 2"55RRRR)//"3"3RRRI,R;;       +B7CCC 	;]/AA-8]]OM*                             s   .B
BBr   c                 \    ddl m}  |                                 }|t          d          |S )Nr   )_current_contextzNo active context found.)r^   r   rA   rq   )r   contexts     rG   r*   r*      s>    777777""$$G5666NrQ   c                      e Zd ZdZddZdS )_CurrentContextz-Internal dependency class for CurrentContext.r3   r   c                "   K   t                      S N)r*   selfs    rG   
__aenter__z_CurrentContext.__aenter__  s      }}rQ   Nr3   r   r\   
__module____qualname__r]   r   rM   rQ   rG   r   r     s.        77     rQ   r   c                 :    t          dt                                S )ai  Get the current FastMCP Context instance.

    This dependency provides access to the active FastMCP Context for the
    current MCP operation (tool/resource/prompt call).

    Returns:
        A dependency that resolves to the active Context instance

    Raises:
        RuntimeError: If no active context found (during resolution)

    Example:
        ```python
        from fastmcp.dependencies import CurrentContext

        @mcp.tool()
        async def log_progress(ctx: Context = CurrentContext()) -> str:
            ctx.report_progress(50, 100, "Halfway done")
            return "Working"
        ```
    r   )r   r   rM   rQ   rG   r&   r&     s    , 	?,,---rQ   c                      e Zd ZdZddZdS )_CurrentDocketz,Internal dependency class for CurrentDocket.r3   r   c                ^   K   t                                           }|t          d          |S )Nz[No Docket instance found. Docket is only available within a running FastMCP server context.)r!   rA   rq   )r   r   s     rG   r   z_CurrentDocket.__aenter__+  s:       $$&&>4  
 rQ   Nr3   r   r   rM   rQ   rG   r   r   (  s.        66	 	 	 	 	 	rQ   r   r   c                 :    t          dt                                S )am  Get the current Docket instance managed by FastMCP.

    This dependency provides access to the Docket instance that FastMCP
    automatically creates for background task scheduling.

    Returns:
        A dependency that resolves to the active Docket instance

    Raises:
        RuntimeError: If not within a FastMCP server context

    Example:
        ```python
        from fastmcp.dependencies import CurrentDocket

        @mcp.tool()
        async def schedule_task(docket: Docket = CurrentDocket()) -> str:
            await docket.add(some_function)(arg1, arg2)
            return "Scheduled"
        ```
    r   )r   r   rM   rQ   rG   r'   r'   7  s    , .**+++rQ   c                      e Zd ZdZddZdS )_CurrentWorkerz,Internal dependency class for CurrentWorker.r3   r   c                ^   K   t                                           }|t          d          |S )Nz[No Worker instance found. Worker is only available within a running FastMCP server context.)r#   rA   rq   )r   r"   s     rG   r   z_CurrentWorker.__aenter__S  s:       $$&&>4  
 rQ   Nr3   r   r   rM   rQ   rG   r   r   P  s.        66     rQ   r   r   c                 :    t          dt                                S )aO  Get the current Docket Worker instance managed by FastMCP.

    This dependency provides access to the Worker instance that FastMCP
    automatically creates for background task processing.

    Returns:
        A dependency that resolves to the active Worker instance

    Raises:
        RuntimeError: If not within a FastMCP server context

    Example:
        ```python
        from fastmcp.dependencies import CurrentWorker

        @mcp.tool()
        async def check_worker_status(worker: Worker = CurrentWorker()) -> str:
            return f"Worker: {worker.name}"
        ```
    r   )r   r   rM   rQ   rG   r)   r)   ^  s    * .**+++rQ   c                       e Zd ZdZd fdZddZedd            Zedd
            Zedd            Z	ddZ
dddZddZ xZS )InMemoryProgressa	  In-memory progress tracker for immediate tool execution.

    Provides the same interface as Progress but stores state in memory
    instead of Redis. Useful for testing and immediate execution where
    progress doesn't need to be observable across processes.
    r3   Nonec                r    t                                                       d | _        d| _        d | _        d S )N   )super__init___current_total_message)r   	__class__s    rG   r   zInMemoryProgress.__init__~  s2    $($(rQ   DocketProgressc                
   K   | S r   rM   r   s    rG   r   zInMemoryProgress.__aenter__  s      rQ   
int | Nonec                    | j         S r   )r   r   s    rG   currentzInMemoryProgress.current  
    }rQ   intc                    | j         S r   )r   r   s    rG   totalzInMemoryProgress.total  s
    {rQ   r4   c                    | j         S r   r   r   s    rG   messagezInMemoryProgress.message  r   rQ   r   c                B   K   |dk     rt          d          || _        dS )z1Set the total/target value for progress tracking.r   zTotal must be at least 1N)
ValueErrorr   )r   r   s     rG   	set_totalzInMemoryProgress.set_total  s)      1997888rQ   r   amountc                t   K   |dk     rt          d          | j        	|| _        dS | xj        |z  c_        dS )z0Atomically increment the current progress value.r   zAmount must be at least 1N)r   r   )r   r   s     rG   	incrementzInMemoryProgress.increment  sE      A::8999= "DMMMMMV#MMMMrQ   r   c                   K   || _         dS )z#Update the progress status message.Nr   )r   r   s     rG   set_messagezInMemoryProgress.set_message  s      rQ   )r3   r   r3   r   )r3   r   )r3   r   )r3   r4   )r   r   r3   r   )r   )r   r   r3   r   )r   r4   r3   r   )r\   r   r   r]   r   r   propertyr   r   r   r   r   r   __classcell__r   s   @rG   r   r   v  s         ) ) ) ) ) )       X    X    X   $ $ $ $ $               rQ   r   c                  $     e Zd ZdZd fdZ xZS )r   a  FastMCP Progress dependency that works in both server and worker contexts.

    Extends Docket's Progress to handle two execution modes:
    - In Docket worker: Uses the execution's progress (standard Docket behavior)
    - In FastMCP server: Uses in-memory progress (not observable remotely)

    This allows tools to use Progress() regardless of whether they're called
    immediately or as background tasks.
    r3   r   c                   K   	 t                                                       d {V S # t          $ r< t                                          }|t          d          d t                      cY S w xY w)Nz6Progress dependency requires a FastMCP server context.)r   r   LookupErrorr!   rA   rq   r   )r   r   r   s     rG   r   zProgress.__aenter__  s      	&++--------- 		& 		& 		&$((**F~"L 
 $%%%%%		&s   %+ AA10A1r   )r\   r   r   r]   r   r   r   s   @rG   r   r     sG         & & & & & & & & & &rQ   r   c                      e Zd ZdZd ZdS )_CurrentFastMCPz-Internal dependency class for CurrentFastMCP.c                   K   t                                           }|t          d           |            }|t          d          |S )N%No FastMCP server instance in context.FastMCP server instance is no longer availabler%   rA   rq   )r   
server_refr$   s      rG   r   z_CurrentFastMCP.__aenter__  sP      $((**
FGGG>OPPPrQ   Nr   rM   rQ   rG   r   r     s)        77    rQ   r   c                 F    ddl m}  t          | t                                S )a  Get the current FastMCP server instance.

    This dependency provides access to the active FastMCP server.

    Returns:
        A dependency that resolves to the active FastMCP server

    Raises:
        RuntimeError: If no server in context (during resolution)

    Example:
        ```python
        from fastmcp.dependencies import CurrentFastMCP

        @mcp.tool()
        async def introspect(server: FastMCP = CurrentFastMCP()) -> str:
            return f"Server: {server.name}"
        ```
    r   r   )fastmcp.server.serverr   r   r   r   s    rG   r(   r(     s,    ( .-----**+++rQ   c                     t                                           } | t          d           |             }|t          d          |S )zGet the current FastMCP server instance directly.

    Returns:
        The active FastMCP server

    Raises:
        RuntimeError: If no server in context
    Nr   r   r   )r   r$   s     rG   r-   r-     sN     !$$&&JBCCCZ\\F~KLLLMrQ   r   c                     d } t          j        t                    5  t          j                    j        } d d d            n# 1 swxY w Y   | t          j                    } | t          d          | S )NzNo active HTTP request found.)
contextlibsuppressr   r   rA   requestr   rq   )r   s    rG   r,   r,     s    G		[	)	) , ,/##+, , , , , , , , , , , , , , ,
 '+--:;;;Ns   AAAFinclude_allbooldict[str, str]c                X   | rt                      }n,h d}t          d |D                       st          d          i }	 t                      }|j                                        D ]/\  }}|                                }||vrt          |          ||<   0|S # t          $ r i cY S w xY w)al  
    Extract headers from the current HTTP request if available.

    Never raises an exception, even if there is no active HTTP request (in which case
    an empty dict is returned).

    By default, strips problematic headers like `content-length` that cause issues if forwarded to downstream clients.
    If `include_all` is True, all headers are returned.
    >   
keep-alivecontent-lengthmcp-session-idproxy-connectiontransfer-encodingproxy-authenticateproxy-authorizationtehostacceptexpectupgrade
connectionc              3  F   K   | ]}|                                 |k    V  d S r   )lower)rN   hs     rG   	<genexpr>z#get_http_headers.<locals>.<genexpr>*  s.      ;;a17799>;;;;;;rQ   z"Excluded headers must be lowercase)	r_   allr   r,   headersr@   r   strrq   )r   exclude_headersr   r   rE   value
lower_names          rG   r+   r+     s      C%%
 
 
$ ;;?;;;;; 	CABBBG"$$"?0022 	1 	1KD%J00&)%jj
#   			s   AB B)(B)AccessToken | Nonec            
     ^   d} 	 t                      }|j                            d          }t          |t                    r|j        } n# t          $ r Y nw xY w| t                      } | t          | t                    r| S 	 | 	                                }t          |d         |d         |d         |                    d          |                    d          |                    d          	          S # t          $ r+}t          d
t          |           j         d          |d}~ww xY w)a  
    Get the FastMCP access token from the current context.

    This function first tries to get the token from the current HTTP request's scope,
    which is more reliable for long-lived connections where the SDK's auth_context_var
    may become stale after token refresh. Falls back to the SDK's context var if no
    request is available.

    Returns:
        The access token if an authenticated user is available, None otherwise.
    Nusertoken	client_idscopes
expires_atresource_ownerclaims)r   r   r   r   r   r   z3Expected fastmcp.server.auth.auth.AccessToken, got z7. Ensure the SDK is using the correct AccessToken type.)r,   scoperA   
isinstancer   access_tokenrq   _sdk_get_access_tokenr   
model_dumpr<   	TypeErrorr2   r\   )r   r   r   access_token_as_dictes        rG   r   r   9  so    ,0L
"$$}  ((d-.. 	-,L   
 ,..z,DD+6688&w/*;7'1+//==/334DEE'++H55
 
 
 	
    D$|BTBTB] D D D
 
 	s+   AA	 	
AAA3C7 7
D,&D''D,)r0   r   r1   r2   r3   r4   )r0   rJ   r3   rJ   )r0   rJ   ri   rj   r3   rk   r   r   r   )r3   r   )F)r   r   r3   r   )r3   r   )H
__future__r   r   r9   weakrefcollections.abcr   r   r   r   contextvarsr   	functoolsr	   typingr
   r   r   r   docket.dependenciesr   r   r   r   r   'mcp.server.auth.middleware.auth_contextr   r   &mcp.server.auth.middleware.bearer_authr   mcp.server.auth.providerr   _SDKAccessTokenmcp.server.lowlevel.serverr   starlette.requestsr   fastmcp.server.authfastmcp.server.httpr   fastmcp.utilities.typesr   r   r   docket.workerr   r^   r   r   r   r!   r8   r#   r%   __all__rH   r/   r{   r.   r*   r   r&   r   r'   r   r)   r   r   r(   r-   r,   r+   rM   rQ   rG   <module>r
     s   " " " " " " "       4 4 4 4 4 4 4 4 : : : : : : : : " " " " " "       ; ; ; ; ; ; ; ; ; ; ; ; O O O O O O O O O O : : : : : :      E D D D D D      3 2 2 2 2 2 & & & & & & + + + + + + 5 5 5 5 5 5 ; ; ; ; ; ; .$$$$$$......------ .8Z$-O-O-O O O O O-7Z$-O-O-O O O O O;E:d< < <      "   2 46 6 6 6r =* =* =* =*@ , , , ,^       j   . . . .2    Z   , , , ,2    Z   , , , ,0.  .  .  .  . ~ .  .  . b& & & & &~ & & &6
 
 
 
 
j 
 
 
, , ,2  &    + + + + +\4 4 4 4 4 4rQ   