§
    ‘
¼ió*  ã                  óÈ   — d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z
mZmZmZmZ ddlmZmZmZmZmZmZ erddlmZmZ  G d	„ d
eee         eef         ¦  «        ZdS )z"Model retry middleware for agents.é    )ÚannotationsN)ÚTYPE_CHECKING)Ú	AIMessage)Ú	OnFailureÚRetryOnÚcalculate_delayÚshould_retry_exceptionÚvalidate_retry_params)ÚAgentMiddlewareÚ
AgentStateÚContextTÚModelRequestÚModelResponseÚ	ResponseT)Ú	AwaitableÚCallablec                  óh   ‡ — e Zd ZdZdefddddddœd'ˆ fd„Zed(d„¦   «         Zd)d„Zd*d$„Z	d+d&„Z
ˆ xZS ),ÚModelRetryMiddlewarea	  Middleware that automatically retries failed model calls with configurable backoff.

    Supports retrying on specific exceptions and exponential backoff.

    Examples:
        !!! example "Basic usage with default settings (2 retries, exponential backoff)"

            ```python
            from langchain.agents import create_agent
            from langchain.agents.middleware import ModelRetryMiddleware

            agent = create_agent(model, tools=[search_tool], middleware=[ModelRetryMiddleware()])
            ```

        !!! example "Retry specific exceptions only"

            ```python
            from anthropic import RateLimitError
            from openai import APITimeoutError

            retry = ModelRetryMiddleware(
                max_retries=4,
                retry_on=(APITimeoutError, RateLimitError),
                backoff_factor=1.5,
            )
            ```

        !!! example "Custom exception filtering"

            ```python
            from anthropic import APIStatusError


            def should_retry(exc: Exception) -> bool:
                # Only retry on 5xx errors
                if isinstance(exc, APIStatusError):
                    return 500 <= exc.status_code < 600
                return False


            retry = ModelRetryMiddleware(
                max_retries=3,
                retry_on=should_retry,
            )
            ```

        !!! example "Custom error handling"

            ```python
            def format_error(exc: Exception) -> str:
                return "Model temporarily unavailable. Please try again later."


            retry = ModelRetryMiddleware(
                max_retries=4,
                on_failure=format_error,
            )
            ```

        !!! example "Constant backoff (no exponential growth)"

            ```python
            retry = ModelRetryMiddleware(
                max_retries=5,
                backoff_factor=0.0,  # No exponential growth
                initial_delay=2.0,  # Always wait 2 seconds
            )
            ```

        !!! example "Raise exception on failure"

            ```python
            retry = ModelRetryMiddleware(
                max_retries=2,
                on_failure="error",  # Re-raise exception instead of returning message
            )
            ```
    é   Úcontinueg       @g      ð?g      N@T)Úmax_retriesÚretry_onÚ
on_failureÚbackoff_factorÚinitial_delayÚ	max_delayÚjitterr   Úintr   r   r   r   r   Úfloatr   r   r   ÚboolÚreturnÚNonec               óÜ   •— t          ¦   «                              ¦   «          t          ||||¦  «         || _        g | _        || _        || _        || _        || _        || _	        || _
        dS )uà  Initialize `ModelRetryMiddleware`.

        Args:
            max_retries: Maximum number of retry attempts after the initial call.

                Must be `>= 0`.
            retry_on: Either a tuple of exception types to retry on, or a callable
                that takes an exception and returns `True` if it should be retried.

                Default is to retry on all exceptions.
            on_failure: Behavior when all retries are exhausted.

                Options:

                - `'continue'`: Return an `AIMessage` with error details,
                    allowing the agent to continue with an error response.
                - `'error'`: Re-raise the exception, stopping agent execution.
                - **Custom callable:** Function that takes the exception and returns a
                    string for the `AIMessage` content, allowing custom error
                    formatting.
            backoff_factor: Multiplier for exponential backoff.

                Each retry waits `initial_delay * (backoff_factor ** retry_number)`
                seconds.

                Set to `0.0` for constant delay.
            initial_delay: Initial delay in seconds before first retry.
            max_delay: Maximum delay in seconds between retries.

                Caps exponential backoff growth.
            jitter: Whether to add random jitter (`Â±25%`) to delay to avoid thundering herd.

        Raises:
            ValueError: If `max_retries < 0` or delays are negative.
        N)ÚsuperÚ__init__r
   r   Útoolsr   r   r   r   r   r   )	Úselfr   r   r   r   r   r   r   Ú	__class__s	           €ú›C:\Users\Dell Inspiron 16\Desktop\tws\AgrotaPowerBi\back-agrota-powerbi\mcp-client-agrota\venv\Lib\site-packages\langchain/agents/middleware/model_retry.pyr%   zModelRetryMiddleware.__init__o   sq   ø€ õ\ 	‰Œ×ÒÑÔÐõ 	˜k¨=¸)À^ÑTÔTÐTà&ˆÔØˆŒ
Ø ˆŒØ$ˆŒØ,ˆÔØ*ˆÔØ"ˆŒØˆŒˆˆó    ÚexcÚ	ExceptionÚattempts_mader   c                ó˜   — t          | ¦  «        j        }t          | ¦  «        }|dk    rdnd}d|› d|› d|› d|› }t          |¬¦  «        S )	a  Format the failure message when retries are exhausted.

        Args:
            exc: The exception that caused the failure.
            attempts_made: Number of attempts actually made.

        Returns:
            `AIMessage` with formatted error message.
        é   ÚattemptÚattemptszModel call failed after ú z with z: ©Úcontent)ÚtypeÚ__name__Ústrr   )r+   r-   Úexc_typeÚexc_msgÚattempt_wordr4   s         r)   Ú_format_failure_messagez,ModelRetryMiddleware._format_failure_message«   sl   € õ ˜‘9”9Ô%ˆÝc‘(”(ˆØ$1°QÒ$6Ð$6yy¸Jˆà` }Ð`Ð`°|Ð`Ð`È8Ð`Ð`ÐW^Ð`Ð`ð 	õ  Ð)Ñ)Ô)Ð)r*   úModelResponse[ResponseT]c                óÞ   — | j         dk    r|‚t          | j         ¦  «        r&|                       |¦  «        }t          |¬¦  «        }n|                      ||¦  «        }t	          |g¬¦  «        S )a\  Handle failure when all retries are exhausted.

        Args:
            exc: The exception that caused the failure.
            attempts_made: Number of attempts actually made.

        Returns:
            `ModelResponse` with error details.

        Raises:
            Exception: If `on_failure` is `'error'`, re-raises the exception.
        Úerrorr3   )Úresult)r   Úcallabler   r;   r   )r'   r+   r-   r4   Úai_msgs        r)   Ú_handle_failurez$ModelRetryMiddleware._handle_failure¾   st   € ð Œ?˜gÒ%Ð%ØˆIåD”OÑ$Ô$ð 	FØ—o’o cÑ*Ô*ˆGÝ wÐ/Ñ/Ô/ˆFˆFà×1Ò1°#°}ÑEÔEˆFå V HÐ-Ñ-Ô-Ð-r*   ÚrequestúModelRequest[ContextT]Úhandlerú<Callable[[ModelRequest[ContextT]], ModelResponse[ResponseT]]ú$ModelResponse[ResponseT] | AIMessagec           	     óä  — t          | j        dz   ¦  «        D ]È}	  ||¦  «        c S # t          $ r¬}|dz   }t          || j        ¦  «        s|                      ||¦  «        cY d}~c S || j        k     rCt          || j        | j        | j	        | j
        ¬¦  «        }|dk    rt          j        |¦  «         n|                      ||¦  «        cY d}~c S Y d}~ŒÁd}~ww xY wd}t          |¦  «        ‚)a¬  Intercept model execution and retry on failure.

        Args:
            request: Model request with model, messages, state, and runtime.
            handler: Callable to execute the model (can be called multiple times).

        Returns:
            `ModelResponse` or `AIMessage` (the final result).

        Raises:
            RuntimeError: If the retry loop completes without returning. (This should not happen.)
        r/   N©r   r   r   r   r   ú2Unexpected: retry loop completed without returning)Úranger   r,   r	   r   rB   r   r   r   r   r   ÚtimeÚsleepÚRuntimeError©r'   rC   rE   r0   r+   r-   ÚdelayÚmsgs           r)   Úwrap_model_callz$ModelRetryMiddleware.wrap_model_callÖ   sP  € õ$ ˜TÔ-°Ñ1Ñ2Ô2ð 	Dð 	DˆGðDØw˜wÑ'Ô'Ð'Ð'Ð'øÝð Dð Dð DØ '¨!¡õ .¨c°4´=ÑAÔAð Dà×/Ò/°°]ÑCÔCÐCÐCÐCÐCÐCÐCÐCÐCð ˜TÔ-Ò-Ð-å+ØØ'+Ô':Ø&*Ô&8Ø"&¤.Ø#œ{ðñ ô Eð ˜q’yyÝœ
 5Ñ)Ô)Ð)øð  ×/Ò/°°]ÑCÔCÐCÐCÐCÐCÐCÐCÐCÐCøøøøøøøøøð/Døøøð4 CˆÝ˜3ÑÔÐs'   ›
(¨
C²/CÁ!CÁ)A#CÃCÃCúGCallable[[ModelRequest[ContextT]], Awaitable[ModelResponse[ResponseT]]]c           	   ƒ  ó   K  — t          | j        dz   ¦  «        D ]Ô}	  ||¦  «        ƒ d{V —†c S # t          $ r²}|dz   }t          || j        ¦  «        s|                      ||¦  «        cY d}~c S || j        k     rIt          || j        | j        | j	        | j
        ¬¦  «        }|dk    rt          j        |¦  «        ƒ d{V —† n|                      ||¦  «        cY d}~c S Y d}~ŒÍd}~ww xY wd}t          |¦  «        ‚)a½  Intercept and control async model execution with retry logic.

        Args:
            request: Model request with model, messages, state, and runtime.
            handler: Async callable to execute the model and returns `ModelResponse`.

        Returns:
            `ModelResponse` or `AIMessage` (the final result).

        Raises:
            RuntimeError: If the retry loop completes without returning. (This should not happen.)
        r/   NrI   r   rJ   )rK   r   r,   r	   r   rB   r   r   r   r   r   ÚasynciorM   rN   rO   s           r)   Úawrap_model_callz%ModelRetryMiddleware.awrap_model_call  sx  è è € õ$ ˜TÔ-°Ñ1Ñ2Ô2ð 	Dð 	DˆGðDØ$˜W WÑ-Ô-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ð-øÝð Dð Dð DØ '¨!¡õ .¨c°4´=ÑAÔAð Dà×/Ò/°°]ÑCÔCÐCÐCÐCÐCÐCÐCÐCÐCð ˜TÔ-Ò-Ð-å+ØØ'+Ô':Ø&*Ô&8Ø"&¤.Ø#œ{ðñ ô Eð ˜q’yyÝ%œm¨EÑ2Ô2Ð2Ð2Ð2Ð2Ð2Ð2Ð2øð  ×/Ò/°°]ÑCÔCÐCÐCÐCÐCÐCÐCÐCÐCøøøøøøøøøð/Døøøð4 CˆÝ˜3ÑÔÐs'   0°
C,º/C'Á)C,Á1A)C'ÃC,Ã'C,)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<   )rC   rD   rE   rF   r!   rG   )rC   rD   rE   rS   r!   rG   )r6   Ú
__module__Ú__qualname__Ú__doc__r,   r%   Ústaticmethodr;   rB   rR   rV   Ú__classcell__)r(   s   @r)   r   r      sË   ø€ € € € € ðMð Mðd Ø&˜LØ *Ø #Ø"ØØð:ð :ð :ð :ð :ð :ð :ð :ðx ð*ð *ð *ñ „\ð*ð$.ð .ð .ð .ð00 ð 0 ð 0 ð 0 ðd0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 ð 0 r*   r   )rY   Ú
__future__r   rU   rL   Útypingr   Úlangchain_core.messagesr   Ú"langchain.agents.middleware._retryr   r   r   r	   r
   Ú!langchain.agents.middleware.typesr   r   r   r   r   r   Úcollections.abcr   r   r   © r*   r)   ú<module>rc      sZ  ðØ (Ð (à "Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø  Ð  Ð  Ð  Ð  Ð  à -Ð -Ð -Ð -Ð -Ð -ðð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð 4Ø3Ð3Ð3Ð3Ð3Ð3Ð3Ð3ðY ð Y ð Y ð Y ð Y ˜?¨:°iÔ+@À(ÈIÐ+UÔVñ Y ô Y ð Y ð Y ð Y r*   