§
    ¦ìNg’  ã                   óÈ   — d Z ddlZddlmZmZmZmZmZ ddlm	Z	 ddl
mZ  ej        e¦  «        Z	 ddlmZ n# e$ r dZY nw xY w G d„ de¦  «        Z G d	„ d
e	¦  «        ZdS )z0Ratelimiting Handler to limit requests or tokensé    N)ÚAnyÚDictÚListÚLiteralÚOptional)ÚBaseCallbackHandler)Ú	LLMResult)Ú	Ratelimitc            
       ó^   ‡ — e Zd ZdZ	 	 d	deded         dee         dee         fˆ fd„Z	ˆ xZ
S )
ÚUpstashRatelimitErrorzi
    Upstash Ratelimit Error

    Raised when the rate limit is reached in `UpstashRatelimitHandler`
    NÚmessageÚtype)ÚtokenÚrequestÚlimitÚresetc                 ót   •— t          ¦   «                              |¦  «         || _        || _        || _        dS )a¢  
        Args:
            message (str): error message
            type (str): The kind of the limit which was reached. One of
                "token" or "request"
            limit (Optional[int]): The limit which was reached. Passed when type
                is request
            reset (Optional[int]): unix timestamp in milliseconds when the limits
                are reset. Passed when type is request
        N)ÚsuperÚ__init__r   r   r   )Úselfr   r   r   r   Ú	__class__s        €út/var/www/html/ai-engine/env/lib/python3.11/site-packages/langchain_community/callbacks/upstash_ratelimit_callback.pyr   zUpstashRatelimitError.__init__   s6   ø€ õ$ 	‰Œ×Ò˜Ñ!Ô!Ð!ØˆŒ	ØˆŒ
ØˆŒ
ˆ
ˆ
ó    )NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ústrr   r   ÚintÚfloatr   Ú__classcell__)r   s   @r   r   r      sˆ   ø€ € € € € ðð ð  $Ø!%ðð àðð Ð(Ô)ðð ˜Œ}ð	ð
 ˜Œðð ð ð ð ð ð ð ð ð r   r   c            	       ó  — e Zd ZU dZdZeed<   dZeed<   ddddœded	e	e
         d
e	e
         defd„Zdeeef         deeef         dedefd„Zdeeef         dee         deddfd„Zdededdfd„Zdde	e         dd fd„ZdS )ÚUpstashRatelimitHandleraÈ  
    Callback to handle rate limiting based on the number of requests
    or the number of tokens in the input.

    It uses Upstash Ratelimit to track the ratelimit which utilizes
    Upstash Redis to track the state.

    Should not be passed to the chain when initialising the chain.
    This is because the handler has a state which should be fresh
    every time invoke is called. Instead, initialise and pass a handler
    every time you invoke.
    TÚraise_errorFÚ_checkedN)Útoken_ratelimitÚrequest_ratelimitÚinclude_output_tokensÚ
identifierr&   r'   r(   c                ó~   — t          ||g¦  «        st          d¦  «        ‚|| _        || _        || _        || _        dS )a@  
        Creates UpstashRatelimitHandler. Must be passed an identifier to
        ratelimit like a user id or an ip address.

        Additionally, it must be passed at least one of token_ratelimit
        or request_ratelimit parameters.

        Args:
            identifier Union[int, str]: the identifier
            token_ratelimit Optional[Ratelimit]: Ratelimit to limit the
                number of tokens. Only works with OpenAI models since only
                these models provide the number of tokens as information
                in their output.
            request_ratelimit Optional[Ratelimit]: Ratelimit to limit the
                number of requests
            include_output_tokens bool: Whether to count output tokens when
                rate limiting based on number of tokens. Only used when
                `token_ratelimit` is passed. False by default.

        Example:
            .. code-block:: python

                from upstash_redis import Redis
                from upstash_ratelimit import Ratelimit, FixedWindow

                redis = Redis.from_env()
                ratelimit = Ratelimit(
                    redis=redis,
                    # fixed window to allow 10 requests every 10 seconds:
                    limiter=FixedWindow(max_requests=10, window=10),
                )

                user_id = "foo"
                handler = UpstashRatelimitHandler(
                    identifier=user_id,
                    request_ratelimit=ratelimit
                )

                # Initialize a simple runnable to test
                chain = RunnableLambda(str)

                # pass handler as callback:
                output = chain.invoke(
                    "input",
                    config={
                        "callbacks": [handler]
                    }
                )

        zhYou must pass at least one of input_token_ratelimit or request_ratelimit parameters for handler to work.N)ÚanyÚ
ValueErrorr)   r&   r'   r(   )r   r)   r&   r'   r(   s        r   r   z UpstashRatelimitHandler.__init__@   sZ   € õt OÐ%6Ð7Ñ8Ô8ð 	ÝðEñô ð ð
 %ˆŒØ.ˆÔØ!2ˆÔØ%:ˆÔ"Ð"Ð"r   Ú
serializedÚinputsÚkwargsÚreturnc                 ó¼   — | j         rR| j        sM| j                              | j        ¦  «        }|j        st          dd|j        |j        ¦  «        ‚d| _        dS dS dS )a\  
        Run when chain starts running.

        on_chain_start runs multiple times during a chain execution. To make
        sure that it's only called once, we keep a bool state `_checked`. If
        not `self._checked`, we call limit with `request_ratelimit` and raise
        `UpstashRatelimitError` if the identifier is rate limited.
        zRequest limit reached!r   TN)r'   r%   r   r)   Úallowedr   r   )r   r-   r.   r/   Úresponses        r   Úon_chain_startz&UpstashRatelimitHandler.on_chain_start…   s{   € ð Ô!ð 	!¨$¬-ð 	!ØÔ-×3Ò3°D´OÑDÔDˆHØÔ#ð Ý+Ø,¨i¸¼ÈÌñô ð ð !ˆDŒMˆMˆMð	!ð 	!ð 	!ð 	!r   Úpromptsc                 ó‚   — | j         r5| j                              | j        ¦  «        }|dk    rt          dd¦  «        ‚dS dS )z-
        Run when LLM starts running
        r   zToken limit reached!r   N)r&   Úget_remainingr)   r   )r   r-   r5   r/   Ú	remainings        r   Úon_llm_startz$UpstashRatelimitHandler.on_llm_start˜   sS   € ð Ôð 	MØÔ,×:Ò:¸4¼?ÑKÔKˆIØ˜AŠ~ˆ~Ý+Ð,BÀGÑLÔLÐLð	Mð 	Màˆ~r   r3   c                 óè   — | j         rj	 |j        pi }|d         }| j        r|d         n|d         }n# t          $ r t	          d¦  «        ‚w xY w| j                              | j        |¬¦  «         dS dS )z¬
        Run when LLM ends running

        If the `include_output_tokens` is set to True, number of tokens
        in LLM completion are counted for rate limiting
        Útoken_usageÚtotal_tokensÚprompt_tokenszþLLM response doesn't include `token_usage: {total_tokens: int, prompt_tokens: int}`  field. To use UpstashRatelimitHandler with token_ratelimit, either use a model which returns token_usage (like  OpenAI models) or rate limit only with request_ratelimit.)ÚrateN)r&   Ú
llm_outputr(   ÚKeyErrorr,   r   r)   )r   r3   r/   r?   r;   Útoken_counts         r   Ú
on_llm_endz"UpstashRatelimitHandler.on_llm_end£   s¹   € ð Ôð 	JðØ%Ô0Ð6°B
Ø(¨Ô7ð Ô1ð6K Ô/Ð/à$ _Ô5ð øõ
 ð ð ð Ý ðQñô ð ðøøøð Ô ×&Ò& t¤¸[Ð&ÑIÔIÐIÐIÐIð+	Jð 	Js	   ‰(2 ²Ac                 óT   — t          |p| j        | j        | j        | j        ¬¦  «        S )zÐ
        Creates a new UpstashRatelimitHandler object with the same
        ratelimit configurations but with a new identifier if it's
        provided.

        Also resets the state of the handler.
        )r)   r&   r'   r(   )r#   r)   r&   r'   r(   )r   r)   s     r   r   zUpstashRatelimitHandler.resetÁ   s7   € õ 'Ø!Ð4 T¤_Ø Ô0Ø"Ô4Ø"&Ô"<ð	
ñ 
ô 
ð 	
r   )N)r   r   r   r   r$   ÚboolÚ__annotations__r%   r   r   r
   r   r   r   r4   r   r9   r	   rB   r   © r   r   r#   r#   /   sŽ  € € € € € € ðð ð €KÐÐÑØ€HˆdÐÐÑð 04Ø15Ø&+ðC;ð C;ð C;àðC;ð " )Ô,ð	C;ð
 $ IÔ.ðC;ð  $ðC;ð C;ð C;ð C;ðJ!Ø˜s C˜xœ.ð!Ø26°s¸C°x´.ð!ØLOð!à	ð!ð !ð !ð !ð&	MØ˜s C˜xœ.ð	MØ37¸´9ð	MØHKð	Mà	ð	Mð 	Mð 	Mð 	MðJ 9ð J¸ð JÀð Jð Jð Jð Jð<
ð 
 ¨¤ð 
Ð9Rð 
ð 
ð 
ð 
ð 
ð 
r   r#   )r   ÚloggingÚtypingr   r   r   r   r   Úlangchain_core.callbacksr   Úlangchain_core.outputsr	   Ú	getLoggerr   ÚloggerÚupstash_ratelimitr
   ÚImportErrorÚ	Exceptionr   r#   rF   r   r   ú<module>rP      s  ðØ 6Ð 6à €€€Ø 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5à 8Ð 8Ð 8Ð 8Ð 8Ð 8Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,à	ˆÔ	˜8Ñ	$Ô	$€ðØ+Ð+Ð+Ð+Ð+Ð+Ð+øØð ð ð Ø€I€I€Iðøøøðð ð ð ð ˜Iñ ô ð ð>_
ð _
ð _
ð _
ð _
Ð1ñ _
ô _
ð _
ð _
ð _
s   ²9 ¹AÁA