§
    œŠtj¬8  ã                  ór  — U d Z ddlmZ ddlZddlmZmZ ddlmZ ddl	m
Z
mZmZmZmZmZ ddlmZ erddlmZmZ dd	lmZ dd
lmZmZmZ  ej        e¦  «        Zd3d„Zd4d„Zd5d„Z d6d„Z!d7d„Z"d8d„Z#d9d"„Z$d:d%„Z%d;d'„Z&d<d)„Z' e(h d*£¦  «        Z)d+e*d,<   d=d0„Z+ G d1„ d2e
ee         eef         ¦  «        Z,dS )>u8  Model fallback middleware for agents.

When a caching middleware such as `AnthropicPromptCachingMiddleware` wraps this
middleware from the outside, it applies Anthropic `cache_control` markers to the
request *before* the fallback loop runs. Those markers are provider-specific and
cause API errors on non-Anthropic fallback models, so this middleware strips them
from fallback attempts â€” but only when the fallback model itself cannot accept
Anthropic cache markers. When the fallback is another Anthropic model the markers
are valid and preserve prompt caching, so they are left intact.

The knowledge of the `cache_control` marker is duplicated here (rather than owned
solely by the Anthropic partner package) because an outer caching middleware
never re-runs during fallback and therefore cannot clean up after itself.
é    )ÚannotationsN)ÚTYPE_CHECKINGÚAny)ÚBaseTool)ÚAgentMiddlewareÚ
AgentStateÚContextTÚModelRequestÚModelResponseÚ	ResponseT)Úinit_chat_model)Ú	AwaitableÚCallable)ÚBaseChatModel)Ú	AIMessageÚ
AnyMessageÚSystemMessageÚcontentú str | list[str | dict[str, Any]]Úreturnc                óú   — t          | t          ¦  «        s| S g }d}| D ]X}t          |t          ¦  «        s|                     |¦  «         Œ-t	          |¦  «        \  }}|p|}|                     |¦  «         ŒY|r|n| S )z;Remove Anthropic cache markers from message content blocks.F)Ú
isinstanceÚlistÚdictÚappendÚ)_without_cache_control_from_content_block)r   Úsanitized_contentÚchangedÚblockÚsanitized_blockÚblock_changeds         úh/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/langchain/agents/middleware/model_fallback.pyÚ_sanitize_content_blocksr#   *   s£   € õ �g�tÑ$Ô$ð Øˆà46ÐØ€Gàð 2ð 2ˆÝ˜%¥Ñ&Ô&ð 	Ø×$Ò$ UÑ+Ô+Ð+Øå)RÐSXÑ)YÔ)YÑ&ˆ˜ØÐ*˜]ˆØ× Ò  Ñ1Ô1Ð1Ð1à 'Ð4ÐÐ¨WÐ4ó    Úsystem_messageúSystemMessage | Nonec                óx   — | €dS t          | j        ¦  «        }|| j        u r| S |                      d|i¬¦  «        S )z5Remove Anthropic cache markers from a system message.Nr   ©Úupdate©r#   r   Ú
model_copy)r%   r   s     r"   Ú_sanitize_system_messager,   @   sQ   € ð ÐØˆtå0°Ô1GÑHÔHÐØ˜NÔ2Ð2Ð2ØÐà×$Ò$¨YÐ8IÐ,JÐ$ÑKÔKÐKr$   Úmessagesúlist[AnyMessage]c                óv   — g }d}| D ]-}t          |¦  «        \  }}|p|}|                     |¦  «         Œ.|r|n| S )z5Remove Anthropic cache markers from request messages.F)Ú_sanitize_messager   )r-   Úsanitized_messagesr   ÚmessageÚsanitized_messageÚmessage_changeds         r"   Ú_sanitize_messagesr5   N   sb   € à+-ÐØ€Gàð 5ð 5ˆÝ->¸wÑ-GÔ-GÑ*Ð˜?ØÐ,˜_ˆØ×!Ò!Ð"3Ñ4Ô4Ð4Ð4à!(Ð6ÐÐ¨hÐ6r$   Útoolsúlist[BaseTool | dict[str, Any]]c                óÆ   — g }d}| D ]U}t          |t          ¦  «        rt          |¦  «        \  }}nt          |¦  «        \  }}|p|}|                     |¦  «         ŒV|r|n| S )z2Remove Anthropic cache markers from tool payloads.F)r   r   Ú_sanitize_base_toolÚ_sanitize_dict_toolr   )r6   Úsanitized_toolsr   ÚtoolÚsanitized_toolÚtool_changeds         r"   Ú_sanitize_toolsr?   [   s†   € ð 8:€OØ€Gàð /ð /ˆå�d�HÑ%Ô%ð 	EÝ+>¸tÑ+DÔ+DÑ(ˆN˜L˜Lå+>¸tÑ+DÔ+DÑ(ˆN˜LàÐ)˜\ˆØ×Ò˜~Ñ.Ô.Ð.Ð.à%Ð0ˆ?ˆ?¨5Ð0r$   ÚrequestúModelRequest[ContextT]c                ó€  — i }t          | j        ¦  «        \  }}|r||d<   t          | j        ¦  «        }|| j        ur||d<   t	          | j        ¦  «        }|| j        ur||d<   t          | j        ¦  «        }|| j        ur||d<   |s| S t           	                    dt          |¦  «        ¦  «          | j        di |¤ŽS )zLSanitize provider-specific Anthropic cache markers before fallback attempts.Úmodel_settingsr%   r-   r6   zHStripped Anthropic cache_control markers from %s before fallback attempt© )Ú_without_cache_controlrC   r,   r%   r5   r-   r?   r6   ÚloggerÚdebugÚsortedÚoverride)r@   Ú	overridesrC   Úmodel_settings_changedr%   r-   r6   s          r"   Ú_sanitize_request_for_fallbackrL   o   sõ   € à "€Iå-CÀGÔDZÑ-[Ô-[Ñ*€NÐ*Øð 5Ø&4ˆ	Ð"Ñ#å-¨gÔ.DÑEÔE€NØ˜WÔ3Ð3Ð3Ø&4ˆ	Ð"Ñ#å! 'Ô"2Ñ3Ô3€HØ�wÔ'Ð'Ð'Ø (ˆ	�*Ñå˜GœMÑ*Ô*€EØ�G”MÐ!Ð!Ø"ˆ	�'Ñàð Øˆõ ‡L‚LØRÝˆyÑÔñô ð ð
 ˆ7ÔÐ(Ð(˜iÐ(Ð(Ð(r$   r2   r   útuple[AnyMessage, bool]c                óx   — t          | j        ¦  «        }|| j        u r| dfS |                      d|i¬¦  «        dfS )z½Remove Anthropic cache markers from a single message.

    Returns:
        The sanitized message (the original instance when unchanged) and whether
            any marker was removed.
    Fr   r(   Tr*   )r2   r   s     r"   r0   r0   �   sM   € õ 1°´ÑAÔAÐØ˜GœOÐ+Ð+Ø˜ˆ~Ðà×Ò iÐ1BÐ%CÐÑDÔDÀdÐJÐJr$   r<   r   útuple[BaseTool, bool]c                óŠ   — | j         s| dfS t          | j         ¦  «        \  }}|s| dfS |                      d|pdi¬¦  «        dfS )zõRemove Anthropic cache markers from a `BaseTool` payload.

    Returns:
        The sanitized tool (the original instance when unchanged) and whether any
            marker was removed.

            Emptied `extras` collapse back to `None`.
    FÚextrasNr(   T)rQ   rE   r+   )r<   Úsanitized_extrasr   s      r"   r9   r9   ž   sc   € ð Œ;ð Ø�Uˆ{Ðå 6°t´{Ñ CÔ CÑÐ�gØð Ø�Uˆ{Ðà�?Š? 8Ð-=Ð-EÀÐ"Fˆ?ÑGÔGÈÐMÐMr$   údict[str, Any]útuple[dict[str, Any], bool]c                óÊ   — t          | ¦  «        \  }}|                     d¦  «        }t          |t          ¦  «        s||fS t          |¦  «        \  }}|s||fS i |¥d|pdi¥dfS )zúRemove Anthropic cache markers from a dict-style tool payload.

    Returns:
        The sanitized tool (the original instance when unchanged) and whether any
            marker was removed.

            Emptied `extras` collapse back to `None`.
    rQ   NT©rE   Úgetr   r   )r<   r=   r   rQ   rR   Úextras_changeds         r"   r:   r:   ±   sŒ   € õ 5°TÑ:Ô:Ñ€N�Gà×Ò Ñ)Ô)€FÝ�f�dÑ#Ô#ð 'Ø˜wÐ&Ð&å'=¸fÑ'EÔ'EÑ$Ð�nØð 'Ø˜wÐ&Ð&àAˆnÐA˜hÐ(8Ð(@¸DÐAÐAÀ4ÐGÐGr$   Úpayloadc                óR   — d| vr| dfS d„ |                       ¦   «         D ¦   «         dfS )zFReturn payload without `cache_control`, plus whether anything changed.Úcache_controlFc                ó&   — i | ]\  }}|d k    ¯||“ŒS )r[   rD   )Ú.0ÚkeyÚvalues      r"   ú
<dictcomp>z*_without_cache_control.<locals>.<dictcomp>Í   s(   € ÐPÐPÐP™
˜˜U¸ÀÒ9OÐ9OˆˆeÐ9OÐ9OÐ9Or$   T)Úitems)rY   s    r"   rE   rE   Ç   s@   € à˜gÐ%Ð%Ø˜ˆ~Ðð 	QÐP g§m¢m¡o¤oÐPÑPÔPØðð r$   r   c                óì   — t          | ¦  «        \  }}dD ]\}|                     |¦  «        }t          |t          ¦  «        sŒ-t          |¦  «        \  }}|sŒB|| u rt          | ¦  «        }|||<   d}Œ]||fS )a'  Return content block without Anthropic cache markers.

    Strips `cache_control` from the block itself and from its nested `extras` and
    `metadata` payloads.

    Returns:
        The sanitized block (the original instance when unchanged) and whether any
            marker was removed.
    )rQ   ÚmetadataTrV   )r   r    r   Ú
nested_keyÚnested_payloadÚsanitized_payloadÚnested_changeds          r"   r   r   Ò   s�   € õ  6°eÑ<Ô<Ñ€O�Wà,ð ð ˆ
Ø(×,Ò,¨ZÑ8Ô8ˆÝ˜.­$Ñ/Ô/ð 	Øå,BÀ>Ñ,RÔ,RÑ)Ð˜>Øð 	Øà˜eÐ#Ð#Ý" 5™kœkˆOØ&7ˆ˜
Ñ#Øˆˆà˜GÐ#Ð#r$   >   úanthropic-chatúanthropic-bedrock-chatúanthropic-chat-vertexaizfrozenset[str]Ú_ANTHROPIC_LLM_TYPESÚmodelr   Úboolc                ó`   — t          | dd¦  «        }t          |t          ¦  «        o|t          v S )ar  Return whether `model` accepts Anthropic `cache_control` markers.

    Checked via `_llm_type` so the decision is provider-based rather than
    model-name-based: any Anthropic-compatible model (including future model IDs
    we have not seen) keeps its cache markers on fallback, while OpenAI, Gemini,
    and other non-Anthropic providers get a sanitized request.
    Ú	_llm_typeN)Úgetattrr   Ústrrk   )rl   Úllm_types     r"   Ú!_supports_anthropic_cache_controlrs   
  s0   € õ �u˜k¨4Ñ0Ô0€HÝ�h¥Ñ$Ô$ÐI¨Õ5IÐ)IÐIr$   c                  ó4   ‡ — e Zd ZdZdˆ fd„Zdd„Zdd„Zˆ xZS )ÚModelFallbackMiddlewarea<  Automatic fallback to alternative models on errors.

    Retries failed model calls with alternative models in sequence until
    success or all models exhausted. Primary model specified in `create_agent`.

    Example:
        ```python
        from langchain.agents.middleware import ModelFallbackMiddleware
        from langchain.agents import create_agent

        fallback = ModelFallbackMiddleware(
            "openai:gpt-5.5",  # Try first on error
            "anthropic:claude-sonnet-4-5-20250929",  # Then this
        )

        agent = create_agent(
            model="openai:gpt-5.5",  # Primary model
            middleware=[fallback],
        )

        # If primary fails: tries gpt-5.5, then claude-sonnet-4-5-20250929
        result = await agent.invoke({"messages": [HumanMessage("Hello")]})
        ```
    Úfirst_modelústr | BaseChatModelÚadditional_modelsr   ÚNonec                ó  •— t          ¦   «                              ¦   «          |g|¢R }g | _        |D ]Y}t          |t          ¦  «        r(| j                             t          |¦  «        ¦  «         Œ?| j                             |¦  «         ŒZdS )zÅInitialize model fallback middleware.

        Args:
            first_model: First fallback model (string name or instance).
            *additional_models: Additional fallbacks in order.
        N)ÚsuperÚ__init__Úmodelsr   rq   r   r   )Úselfrv   rx   Ú
all_modelsrl   Ú	__class__s        €r"   r|   z ModelFallbackMiddleware.__init__0  sš   ø€ õ 	‰Œ×ÒÑÔÐð "Ð6Ð$5Ð6Ð6ˆ
Ø+-ˆŒØð 	*ð 	*ˆEÝ˜%¥Ñ%Ô%ð *Ø”×"Ò"¥?°5Ñ#9Ô#9Ñ:Ô:Ð:Ð:à”×"Ò" 5Ñ)Ô)Ð)Ð)ð		*ð 	*r$   r@   rA   Úhandlerú<Callable[[ModelRequest[ContextT]], ModelResponse[ResponseT]]ú$ModelResponse[ResponseT] | AIMessagec                ó  — 	  ||¦  «        S # t           $ r}|}Y d}~nd}~ww xY w| j        D ]\}t          |¦  «        r|nt          |¦  «        }	  ||                     |¬¦  «        ¦  «        c S # t           $ r}|}Y d}~ŒUd}~ww xY w|‚)a<  Try fallback models in sequence on errors.

        Args:
            request: Initial model request.
            handler: Callback to execute the model.

        Returns:
            AIMessage from successful model call.

        Raises:
            Exception: If all models fail, re-raises last exception.
        N©rl   ©Ú	Exceptionr}   rs   rL   rI   ©r~   r@   r�   ÚeÚlast_exceptionÚfallback_modelÚfallback_requests          r"   Úwrap_model_callz'ModelFallbackMiddleware.wrap_model_callF  sâ   € ð&	Ø�7˜7Ñ#Ô#Ð#øÝð 	ð 	ð 	ØˆNˆNˆNˆNˆNˆNøøøøð	øøøð #œkð 
	ð 
	ˆNõ 5°^ÑDÔDð=��å3°GÑ<Ô<ð ð
Ø�wÐ/×8Ò8¸~Ð8ÑNÔNÑOÔOÐOÐOÐOøÝð ð ð Ø!"�Ø����øøøøðøøøð Ðs(   ‚
 �
#—ž#ÁA1Á1
BÁ;BÂBúGCallable[[ModelRequest[ContextT]], Awaitable[ModelResponse[ResponseT]]]c              ƒ  ó4  K  — 	  ||¦  «        ƒ d{V —†S # t           $ r}|}Y d}~nd}~ww xY w| j        D ]b}t          |¦  «        r|nt          |¦  «        }	  ||                     |¬¦  «        ¦  «        ƒ d{V —†c S # t           $ r}|}Y d}~Œ[d}~ww xY w|‚)aR  Try fallback models in sequence on errors (async version).

        Args:
            request: Initial model request.
            handler: Async callback to execute the model.

        Returns:
            AIMessage from successful model call.

        Raises:
            Exception: If all models fail, re-raises last exception.
        Nr…   r†   rˆ   s          r"   Úawrap_model_callz(ModelFallbackMiddleware.awrap_model_callp  s
  è è € ð&	Ø ˜ Ñ)Ô)Ð)Ð)Ð)Ð)Ð)Ð)Ð)øÝð 	ð 	ð 	ØˆNˆNˆNˆNˆNˆNøøøøð	øøøð #œkð 
	ð 
	ˆNõ 5°^ÑDÔDð=��å3°GÑ<Ô<ð ð
Ø$˜WÐ%5×%>Ò%>À^Ð%>Ñ%TÔ%TÑUÔUÐUÐUÐUÐUÐUÐUÐUÐUÐUøÝð ð ð Ø!"�Ø����øøøøðøøøð Ðs(   „ •
+Ÿ&¦+Á$A?Á?
BÂ	BÂB)rv   rw   rx   rw   r   ry   )r@   rA   r�   r‚   r   rƒ   )r@   rA   r�   rŽ   r   rƒ   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r|   r�   r�   Ú__classcell__)r€   s   @r"   ru   ru     sp   ø€ € € € € ðð ð2*ð *ð *ð *ð *ð *ð,(ð (ð (ð (ðT(ð (ð (ð (ð (ð (ð (ð (r$   ru   )r   r   r   r   )r%   r&   r   r&   )r-   r.   r   r.   )r6   r7   r   r7   )r@   rA   r   rA   )r2   r   r   rM   )r<   r   r   rO   )r<   rS   r   rT   )rY   rS   r   rT   )r   rS   r   rT   )rl   r   r   rm   )-r”   Ú
__future__r   ÚloggingÚtypingr   r   Úlangchain_core.toolsr   Ú!langchain.agents.middleware.typesr   r   r	   r
   r   r   Úlangchain.chat_modelsr   Úcollections.abcr   r   Ú*langchain_core.language_models.chat_modelsr   Úlangchain_core.messagesr   r   r   Ú	getLoggerr‘   rF   r#   r,   r5   r?   rL   r0   r9   r:   rE   r   Ú	frozensetrk   Ú__annotations__rs   ru   rD   r$   r"   ú<module>r¢      sš  ððð ð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø %Ð %Ð %Ð %Ð %Ð %Ð %Ð %à )Ð )Ð )Ð )Ð )Ð )ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð 2Ð 1Ð 1Ð 1Ð 1Ð 1àð MØ3Ð3Ð3Ð3Ð3Ð3Ð3Ð3àHÐHÐHÐHÐHÐHØLÐLÐLÐLÐLÐLÐLÐLÐLÐLà	ˆÔ	˜8Ñ	$Ô	$€ð5ð 5ð 5ð 5ð,Lð Lð Lð Lð
7ð 
7ð 
7ð 
7ð1ð 1ð 1ð 1ð()ð )ð )ð )ðBKð Kð Kð KðNð Nð Nð Nð&Hð Hð Hð Hð,ð ð ð ð$ð $ð $ð $ð^ (1 yðð ð ñ(ô (Ð ð ð ð ñ ð	Jð 	Jð 	Jð 	JðBð Bð Bð Bð B˜o¨j¸Ô.CÀXÈyÐ.XÔYñ Bô Bð Bð Bð Br$   