
    #j7                       d Z ddlmZ ddl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 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  ee          Z ededef                   Zdd dZ d!dZ! G d de          Z"dS )"u4  FastMCPApp — a Provider that represents a composable MCP application.

FastMCPApp binds entry-point tools (model calls these) together with backend
tools (the UI calls these via CallTool).  Backend tools are tagged with
``meta["fastmcp"]["app"]`` so they can be found through the provider chain
even when transforms (namespace, visibility, etc.) have renamed or hidden
them — the server sets a context var that tells ``Provider.get_tool`` to
fall back to a direct lookup for app-visible tools.

Usage::

    from fastmcp import FastMCP, FastMCPApp

    app = FastMCPApp("Dashboard")

    @app.ui()
    def show_dashboard() -> Component:
        return Column(...)

    @app.tool()
    def save_contact(name: str, email: str) -> str:
        return name

    server = FastMCP("Platform")
    server.add_provider(app)
    )annotationsN)AsyncIteratorCallableSequence)asynccontextmanager)AnyLiteralTypeVaroverload)AnyFunctionIconToolAnnotations)	AuthCheck)Provider)LocalProvider)Tool)
get_loggerF.)boundapp_name
str | Nonereturnr   c                :     ddl mm d
 fddfd	}|S )u  Create a CallTool resolver that prefixes tool names with a hash.

    Structurally identical to the old ``___`` resolver — ``app_name`` is
    the FastMCPApp's name, known at serialization time from the tool's
    ``meta["fastmcp"]["app"]`` tag. The only change is the wire format:
    ``<hash>_<local_name>`` instead of ``<app_name>___<local_name>``.

    The dispatcher recognizes the hashed form and routes it via
    ``get_tool_by_hash`` which walks the provider tree recursively —
    same pattern as ``get_app_tool``.
    r   )hashed_backend_nameparse_hashed_backend_name
local_namestrr   c                >    r |           | S  |           S | S N )r   r   r   r   s    X/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/fastmcp/apps/app.py_prefixz_make_resolver.<locals>._prefixF   s=     	= )(44@!!&&x<<<    fnr   c                v   ddl m} t          | t                    r | |                     S d }	 ddlm}  ||           }n# t          $ r Y nw xY w|(t          |dd           }| | |                    S t          | dd           }| | |                    S t          d|           )Nr   )ResolvedToolname)get_fastmcp_metar(   __name__zCannot resolve tool reference: )	prefab_ui.appr&   
isinstancer   fastmcp.decoratorsr)   	Exceptiongetattr
ValueError)r$   r&   fmetar)   r(   fn_namer"   s         r!   _resolve_tool_refz)_make_resolver.<locals>._resolve_tool_refO   s   ......b# 	2<WWR[[1111	;;;;;;$$R((EE 	 	 	D	 &ufd;;D#|7777"j$//<WWW%5%56666A2AABBBs   A 
AA)r   r   r   r   )r$   r   r   r   )#fastmcp.server.providers.addressingr   r   )r   r3   r"   r   r   s   ` @@@r!   _make_resolverr5   5   s           
       C C C C C C2 r#   
name_or_fnstr | AnyFunction | Noner(   register Callable[[Any, str | None], Any]decorator_namer   c                    t          j        |           r | |          S t          | t                    r|t	          d          | n'| |n"t	          d| dt          |                      d	fd}|S )
zEShared dispatch logic for @app.tool() and @app.ui() calling patterns.NzECannot specify both a name as first argument and as keyword argument.zFirst argument to @z* must be a function, string, or None, got r$   r   r   c                     |           S r   r    )r$   r8   	tool_names    r!   	decoratorz&_dispatch_decorator.<locals>.decorator   s    xI&&&r#   )r$   r   r   r   )inspect	isroutiner,   r   	TypeErrortype)r6   r(   r8   r:   r>   r=   s     `  @r!   _dispatch_decoratorrC   k   s     $$ *x
D)))*c"" 
W   !+						&. & &
##& &
 
 	

' ' ' ' ' ' ' r#   c                      e Zd ZdZd> fdZd?dZeddd	ddd
d@d            Ze	 dAddd	ddd
dBd            Z	 dAddd	ddd
dCdZeddddddddddDd#            Ze	 dAddddddddddEd$            Z	 dAddddddddddFd%ZdGd)Z	dHd+Z
dAdId.ZdJd0ZdAdKd3ZdJd4ZdAdKd5ZdJd6ZdAdLd7ZedMd9            Z	 dAdNd=Z xZS )O
FastMCPAppaO  A Provider that represents an MCP application.

    Binds together entry-point tools (``@app.ui``), backend tools
    (``@app.tool``), and the Prefab renderer resource.  Backend tools
    are tagged with ``meta["fastmcp"]["app"]`` so ``Provider.get_tool``
    can find them by original name even when transforms have been applied.
    r(   r   r   Nonec                    t                                                       || _        t          d          | _        d S )Nerror)on_duplicate)super__init__r(   r   _local)selfr(   	__class__s     r!   rK   zFastMCPApp.__init__   s6    	#999r#   c                    d| j         dS )NzFastMCPApp()r'   rM   s    r!   __repr__zFastMCPApp.__repr__   s    +TY++++r#   NF)r(   descriptionmodelauthtimeoutr6   r   r   rS   rT   boolrU   "AuthCheck | list[AuthCheck] | NonerV   float | Nonec                   d S r   r    rM   r6   r(   rS   rT   rU   rV   s          r!   toolzFastMCPApp.tool   s	     Cr#   Callable[[F], F]c                   d S r   r    r[   s          r!   r\   zFastMCPApp.tool   s	     3r#   r7   r   c               V     |rddgndgd
 fd}t          |||d	          S )a  Register a backend tool that the UI calls via CallTool.

        Backend tools default to ``visibility=["app"]``.  Pass ``model=True``
        to also expose the tool to the model (``visibility=["app", "model"]``).

        Supports multiple calling patterns::

            @app.tool
            def save(name: str): ...

            @app.tool()
            def save(name: str): ...

            @app.tool("custom_name")
            def save(name: str): ...
        apprT   r$   r   r=   r   r   c                <   |pt          | dd           }|t          d|           ddlm}m} ddlm}  |          } ||          j         |j        |          dd}t          j	        | |
|		          }j
                            |           | S )
Nr*   zCannot determine tool name for r   	AppConfigapp_config_to_meta_dict	hash_tool)
visibilityr`   
_tool_hashuifastmcp)r(   rS   metarV   rU   )r/   r0   fastmcp.apps.configrc   rd   r4   rf   r(   r   from_functionrL   _add_component)r$   r=   resolved_namerc   rd   rf   
app_configrm   tool_objrU   rS   rM   rV   rg   s            r!   	_registerz"FastMCPApp.tool.<locals>._register   s    %FZ)F)FM$ !I2!I!IJJJNNNNNNNNEEEEEE"j999J--j999"+)DI}"E"E $ $D )"'  H K&&x000Ir#   r\   r$   r   r=   r   r   r   rC   )	rM   r6   r(   rS   rT   rU   rV   rt   rg   s	   `  ` `` @r!   r\   zFastMCPApp.tool   sj    6 !&2UGE7 		 	 	 	 	 	 	 	 	 	8 #:tYGGGr#   )r(   rS   titletagsiconsr   rU   rV   rw   rx   set[str] | Nonery   list[Icon] | Noner   ToolAnnotations | Nonec                   d S r   r    
rM   r6   r(   rS   rw   rx   ry   r   rU   rV   s
             r!   rk   zFastMCPApp.ui   s	     Cr#   c                   d S r   r    r~   s
             r!   rk   zFastMCPApp.ui
  s	     3r#   c          	     P    	 d 	fd}
t          |||
d          S )	a!  Register a UI entry-point tool that the model calls.

        Entry-point tools default to ``visibility=["model"]`` and auto-wire
        the Prefab renderer resource and CSP. They are tagged with the app
        name so structured content includes ``_meta.fastmcp.app``.

        Supports multiple calling patterns::

            @app.ui
            def dashboard() -> Component: ...

            @app.ui()
            def dashboard() -> Component: ...

            @app.ui("my_dashboard")
            def dashboard() -> Component: ...
        r$   r   r=   r   r   c                0   ddl m}m} ddlm} ddlm} |pt          | dd           pd} ||dg          } ||          j         |j        |          d	d
}t          j
        | |
|
  
        }	j                            |	           | S )Nr   rb   re   )PREFAB_RENDERER_URIr*   unknownrT   )resource_urirg   rh   rj   )	r(   rS   rw   rx   ry   r   rm   rV   rU   )rn   rc   rd   r4   rf   8fastmcp.server.providers.local_provider.decorators.toolsr   r/   r(   r   ro   rL   rp   )r$   r=   rc   rd   rf   r   resolvedrr   rm   rs   r   rU   rS   ry   rM   rx   rV   rw   s             r!   rt   z FastMCPApp.ui.<locals>._register8  s   NNNNNNNNEEEEEE      !NGB
D$A$ANYH"0#9  J .-j999"+)DIx"@"@ $ $D )''  H K&&x000Ir#   rk   ru   rv   )rM   r6   r(   rS   rw   rx   ry   r   rU   rV   rt   s   `  ``````` r!   rk   zFastMCPApp.ui  sb    >#	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	 #	J #:tYEEEr#   r\   Tool | Callable[..., Any]r   c                   t          |t                    st          j        |          }ddlm} |j        rt          |j                  ni }|                    di           }| j        |d<    || j        |j                  |d<   |                    di           }d|vrdg|d<   ||_        | j	        
                    |           |S )zoAdd a tool to this app programmatically.

        The tool is tagged with this app's name for routing.
        r   re   rl   r`   ri   rk   rg   )r,   r   _ensure_toolr4   rf   rm   dict
setdefaultr(   rL   rp   )rM   r\   rf   rm   fmrk   s         r!   add_toolzFastMCPApp.add_toolc  s     $%% 	+$T**DAAAAAA"&)3tDI__Y++I5	$9TY	::<__T2&&r!! %wB|	""4(((r#   Sequence[Tool]c                D   K   | j                                          d {V S r   )rL   _list_toolsrQ   s    r!   r   zFastMCPApp._list_tools  s,      [,,.........r#   versionTool | Nonec                H   K   | j                             ||           d {V S r   )rL   	_get_toolrM   r(   r   s      r!   r   zFastMCPApp._get_tool  s0      [**4999999999r#   Sequence[Any]c                D   K   | j                                          d {V S r   )rL   _list_resourcesrQ   s    r!   r   zFastMCPApp._list_resources  s,      [00222222222r#   uri
Any | Nonec                H   K   | j                             ||           d {V S r   )rL   _get_resourcerM   r   r   s      r!   r   zFastMCPApp._get_resource  s0      [..sG<<<<<<<<<r#   c                D   K   | j                                          d {V S r   )rL   _list_resource_templatesrQ   s    r!   r   z#FastMCPApp._list_resource_templates  s,      [99;;;;;;;;;r#   c                H   K   | j                             ||           d {V S r   )rL   _get_resource_templater   s      r!   r   z!FastMCPApp._get_resource_template  s0      [77WEEEEEEEEEr#   c                D   K   | j                                          d {V S r   )rL   _list_promptsrQ   s    r!   r   zFastMCPApp._list_prompts  s,      [..000000000r#   c                H   K   | j                             ||           d {V S r   )rL   _get_promptr   s      r!   r   zFastMCPApp._get_prompt  s0      [,,T7;;;;;;;;;r#   AsyncIterator[None]c                  K   | j                                         4 d {V  d W V  d d d           d {V  d S # 1 d {V swxY w Y   d S r   )rL   lifespanrQ   s    r!   r   zFastMCPApp.lifespan  s      ;'')) 	 	 	 	 	 	 	 	EEEE	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   ;
AA	transport9Literal['stdio', 'http', 'sse', 'streamable-http'] | Nonekwargsc                z    ddl m}  || j                  }|                    |             |j        dd|i| dS )z>Create a temporary FastMCP server and run this app standalone.r   )FastMCPr   Nr    )fastmcp.server.serverr   r(   add_providerrun)rM   r   r   r   servers        r!   r   zFastMCPApp.run  s^     	211111##D!!!
11Y1&11111r#   )r(   r   r   rF   )r   r   )r6   r   r(   r   rS   r   rT   rW   rU   rX   rV   rY   r   r   r   )r6   r   r(   r   rS   r   rT   rW   rU   rX   rV   rY   r   r]   )r6   r7   r(   r   rS   r   rT   rW   rU   rX   rV   rY   r   r   )r6   r   r(   r   rS   r   rw   r   rx   rz   ry   r{   r   r|   rU   rX   rV   rY   r   r   )r6   r   r(   r   rS   r   rw   r   rx   rz   ry   r{   r   r|   rU   rX   rV   rY   r   r]   )r6   r7   r(   r   rS   r   rw   r   rx   rz   ry   r{   r   r|   rU   rX   rV   rY   r   r   )r\   r   r   r   )r   r   )r(   r   r   r   r   r   )r   r   )r   r   r   r   r   r   )r(   r   r   r   r   r   )r   r   )r   r   r   r   r   rF   )r*   
__module____qualname____doc__rK   rR   r   r\   rk   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__)rN   s   @r!   rE   rE      s        : : : : : :
, , , , 
  "&37 $	 	 	 	 	 X	  "&	  "&37 $	 	 	 	 	 X	 04:H  "&37 $:H :H :H :H :H :H@ 
  "&  $#'.237 $     X  "&  "&  $#'.237 $     X  04DF  "&  $#'.237 $DF DF DF DF DF DFT   :/ / / /: : : : :3 3 3 3= = = = =< < < <F F F F F1 1 1 1< < < < <     PT
2 
2 
2 
2 
2 
2 
2 
2 
2r#   rE   r   )r   r   r   r   )
r6   r7   r(   r   r8   r9   r:   r   r   r   )#r   
__future__r   r?   collections.abcr   r   r   
contextlibr   typingr   r	   r
   r   	mcp.typesr   r   r   !fastmcp.server.auth.authorizationr   fastmcp.server.providers.baser   'fastmcp.server.providers.local_providerr   fastmcp.tools.baser   fastmcp.utilities.loggingr   r*   loggerr   r5   rC   rE   r    r#   r!   <module>r      s   6 # " " " " "  = = = = = = = = = = * * * * * * 2 2 2 2 2 2 2 2 2 2 2 2 8 8 8 8 8 8 8 8 8 8 7 7 7 7 7 7 2 2 2 2 2 2 A A A A A A # # # # # # 0 0 0 0 0 0	H		GCxS)***3 3 3 3 3l   F]2 ]2 ]2 ]2 ]2 ]2 ]2 ]2 ]2 ]2r#   