
    kKj                        d Z ddlmZ ddlZddlmZ ddlmZ ddl	Z	ddlm
Z
 ddlmZ ddlmZmZmZ d	gZ ej$                  e      Z G d
 d	e      Zy)zAResponse limiting middleware for controlling tool response sizes.    )annotationsN)Any)TextContent)
ToolResult   )CallNext
MiddlewareMiddlewareContextResponseLimitingMiddlewarec                  Z    e Zd ZdZdddd	 	 	 	 	 	 	 d	dZ	 d
	 	 	 	 	 ddZ	 	 	 	 	 	 ddZy)r   a#  Middleware that limits the response size of tool calls.

    Intercepts tool call responses and enforces size limits. If a response
    exceeds the limit, it extracts text content, truncates it, and returns
    a single TextContent block.

    Example:
        ```python
        from fastmcp import FastMCP
        from fastmcp.server.middleware.response_limiting import (
            ResponseLimitingMiddleware,
        )

        mcp = FastMCP("MyServer")

        # Limit all tool responses to 500KB
        mcp.add_middleware(ResponseLimitingMiddleware(max_size=500_000))

        # Limit only specific tools
        mcp.add_middleware(
            ResponseLimitingMiddleware(
                max_size=100_000,
                tools=["search", "fetch_data"],
            )
        )
        ```
    i@B z(

[Response truncated due to size limit]N)max_sizetruncation_suffixtoolsc               z    |dk  rt        d|       || _        || _        |t        |      | _        yd| _        y)a}  Initialize response limiting middleware.

        Args:
            max_size: Maximum response size in bytes. Defaults to 1MB (1,000,000).
            truncation_suffix: Suffix to append when truncating responses.
                Defaults to "\n\n[Response truncated due to size limit]".
            tools: List of tool names to apply limiting to. If None, applies to all.
        r   zmax_size must be positive, got N)
ValueErrorr   r   setr   )selfr   r   r   s       |/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/fastmcp/server/middleware/response_limiting.py__init__z#ResponseLimitingMiddleware.__init__2   sC     q=>xjIJJ !2#(#4SZ
$
    c                ~   t        | j                  j                  d            }d}| j                  |z
  |z
  }|dk  r| j                  }nR|j                  d      }t        |      |k  r|| j                  z   }n#|d| j	                  dd      | j                  z   }t        t        d|      g||	      S i 	      S )
z<Truncate text to fit within max_size and wrap in ToolResult.utf-82   r   Nignoreerrorstext)typer   )contentmeta)lenr   encoder   decoder   r   )r   r   r    suffix_bytesoverheadtarget_size	truncatedencodeds           r   _truncate_to_resultz.ResponseLimitingMiddleware._truncate_to_resultG   s     41188ABmml2X=!..I kk'*G7|{* 4#9#99	 L[)000J,,-   f9=>)
 	
/1
 	
r   c                p  K    ||       d{   }| j                   $|j                  j                  | j                   vr|S t        j                  |t
              }t        |      | j                  k  r|S t        j                  d|j                  j                  t        |      | j                         |j                  D cg c]  }t        |t              s|j                  ! }}|rdj                  |      n|j                  dd      }| j!                  ||j"                        S 7  c c}w w)	z-Intercept tool calls and limit response size.N)fallbackzDTool %r response exceeds size limit: %d bytes > %d bytes, truncatingz

r   replacer   )r    )r   messagenamepydantic_coreto_jsonstrr!   r   loggerwarningr   
isinstancer   r   joinr#   r)   r    )r   context	call_nextresult
serializedbtextsr   s           r   on_call_toolz'ResponseLimitingMiddleware.on_call_tooli   s	     !)) ::!goo&:&:$**&LM #**6C@
z?dmm+M 	ROO  
OMM		
 "(NA:a3MN  KK""79"= 	 ''6;;'??5 *& Os)   D6D.B6D6D1D1)AD61D6)r   intr   r1   r   zlist[str] | NonereturnNone)N)r   r1   r    zdict[str, Any] | Noner>   r   )r6   z+MiddlewareContext[mt.CallToolRequestParams]r7   z.CallNext[mt.CallToolRequestParams, ToolResult]r>   r   )__name__
__module____qualname____doc__r   r)   r<    r   r   r   r      s    > "!M"&? ? 	?
  ? 
?0 '+ 
 
 $ 
 
	 
D @< @ B @ 
	 @r   )rC   
__future__r   loggingtypingr   	mcp.typestypesmtr/   r   fastmcp.tools.baser   
middlewarer   r	   r
   __all__	getLoggerr@   r2   r   rD   r   r   <module>rO      sM    G "     ! ) ? ?'
(			8	$t@ t@r   