
    
i%                    f   d Z ddlmZ ddlmZ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mZmZmZ ddlmZ dd	lmZ dd
lmZmZmZmZmZmZ dZeee         gef         Z  G d de          Z! ed           G d de!                      Z" G d deee         eef                   Z#ddgZ$dS )a  Context editing middleware.

Mirrors Anthropic's context editing capabilities by clearing older tool results once the
conversation grows beyond a configurable token threshold.

The implementation is intentionally model-agnostic so it can be used with any LangChain
chat model.
    )annotations)	AwaitableCallableIterableSequence)deepcopy)	dataclass)Literal)	AIMessage
AnyMessageBaseMessageToolMessagecount_tokens_approximately)Protocol)AgentMiddleware
AgentStateContextTModelRequestModelResponse	ResponseTz	[cleared]c                      e Zd ZdZd
dZd	S )ContextEditz/Protocol describing a context editing strategy.messageslist[AnyMessage]count_tokensTokenCounterreturnNonec                   dS )z+Apply an edit to the message list in place.N )selfr   r   s      C:\Users\Dell Inspiron 16\Desktop\tws\AgrotaPowerBi\back-agrota-powerbi\mcp-client-agrota\venv\Lib\site-packages\langchain/agents/middleware/context_editing.pyapplyzContextEdit.apply/   s	     	    Nr   r   r   r   r   r   )__name__
__module____qualname____doc__r$   r!   r%   r#   r   r   ,   s.        99     r%   r   T)slotsc                      e Zd ZU dZdZded<   	 dZded<   	 dZded<   	 d	Zd
ed<   	 dZ	ded<   	 e
Zded<   	 ddZedd            ZdS )ClearToolUsesEditzGConfiguration for clearing tool outputs when token limits are exceeded.i inttriggerr   clear_at_least   keepFboolclear_tool_inputsr!   zSequence[str]exclude_toolsstrplaceholderr   r   r   r   r   r   c          
     x    ||          }|| j         k    rdS d t          |          D             }| j        t          |          k    rg }n| j        r|d| j                  }d}t	          | j                  }|D ];\  }j                            di                               d          r5t          d t          |d|                   D             d          }|gt          fd|j
        D             d          }	|	j        p|	d         |v r                    d| j        i j        dd	d
did          ||<   | j        r1|                     |j                  ||                    |          <   | j        dk    r+ ||          }
t'          d||
z
            }|| j        k    r n=dS )z#Apply the clear-tool-uses strategy.Nc                F    g | ]\  }}t          |t                    ||fS r!   )
isinstancer   ).0idxmsgs      r#   
<listcomp>z+ClearToolUsesEdit.apply.<locals>.<listcomp>[   s?     
 
 
#3jk>Z>Z
#J
 
 
r%   r   context_editingclearedc              3  D   K   | ]}t          |t                    |V  d S N)r:   r   )r;   ms     r#   	<genexpr>z*ClearToolUsesEdit.apply.<locals>.<genexpr>l   s1      QQq
1i8P8PQQQQQQQr%   c              3  X   K   | ]$}|                     d           j        k     |V  %dS )idN)gettool_call_id)r;   calltool_messages     r#   rD   z*ClearToolUsesEdit.apply.<locals>.<genexpr>s   sG        xx~~)BBB BBBB r%   nameTclear_tool_uses)r@   strategy)artifactcontentresponse_metadataupdate)r/   	enumerater2   lensetr5   rP   rG   nextreversed
tool_callsrK   
model_copyr7   r4   !_build_cleared_tool_input_messagerH   indexr0   max)r"   r   r   tokens
candidatescleared_tokensexcluded_toolsr<   
ai_message	tool_callnew_token_countrJ   s              @r#   r$   zClearToolUsesEdit.applyO   sa    h''T\!!F
 
'0':':
 
 

 9J''JJY 	2#LtyjL1JT/00!+ 2	 2	C-112CRHHLLYWW QQHXdsd^44QQQSW J !    * 5  
  I  !6Yv%6>II(33 $#/*&8*)'+(9, ,* *
 
 4  HSM % 7;7]7] -8 8
334
 "Q&&".,x"8"8!$Q(@!A!A!T%888Er%   messager   rH   c                   g }d}| j         D ]F}t          |          }|                    d          |k    ri |d<   d}|                    |           Gt          t	          | di                     }t          |                    di                     }|rOt          |                    dg                     }|                    |           t          |          |d<   ||d<   |                     ||d	          S )
NFrF   argsTrP   r?   cleared_tool_inputs)rX   rP   rQ   )	rX   dictrG   appendgetattrrU   addsortedrY   )	rd   rH   updated_tool_callscleared_anyrb   updated_callmetadatacontext_entrycleared_idss	            r#   rZ   z3ClearToolUsesEdit._build_cleared_tool_input_message   s$   
   + 	4 	4I	??L%%55')V$"%%l3333)<bAABBX\\*;R@@AA 	8m//0ErJJKKKOOL)))39+3F3FM/0*7H&'!!0%-  " 
 
 	
r%   Nr&   )rd   r   rH   r6   r   r   )r'   r(   r)   r*   r/   __annotations__r0   r2   r4   r5   DEFAULT_TOOL_PLACEHOLDERr7   r$   staticmethodrZ   r!   r%   r#   r-   r-   9   s         QQG-NADMMMMD#####R#%M%%%%6/K////=L L L L\ 
 
 
 \
 
 
r%   r-   c                  R     e Zd ZU dZded<   ded<   dddd fdZddZddZ xZS )ContextEditingMiddlewarea  Automatically prune tool results to manage context size.

    The middleware applies a sequence of edits when the total input token count exceeds
    configured thresholds.

    Currently the `ClearToolUsesEdit` strategy is supported, aligning with Anthropic's
    `clear_tool_uses_20250919` behavior [(read more)](https://platform.claude.com/docs/en/agents-and-tools/tool-use/memory-tool).
    zlist[ContextEdit]editsLiteral['approximate', 'model']token_count_methodNapproximate)rx   rz   Iterable[ContextEdit] | Noner   r   c                   t                                                       t          |pt                      f          | _        || _        dS )a  Initialize an instance of context editing middleware.

        Args:
            edits: Sequence of edit strategies to apply.

                Defaults to a single `ClearToolUsesEdit` mirroring Anthropic defaults.
            token_count_method: Whether to use approximate token counting
                (faster, less accurate) or exact counting implemented by the
                chat model (potentially slower, more accurate).
        N)super__init__listr-   rx   rz   )r"   rx   rz   	__class__s      r#   r   z!ContextEditingMiddleware.__init__   sG      	%9$5$7$7#9::
"4r%   requestModelRequest[ContextT]handler<Callable[[ModelRequest[ContextT]], ModelResponse[ResponseT]]$ModelResponse[ResponseT] | AIMessagec                <   j         s |          S | j        dk    rd
d}nj        rj        gng d
fd}t          t	          j                             }| j        D ]}|                    ||            |                    |	                    S )r  Apply context edits before invoking the model via handler.

        Args:
            request: Model request to execute (includes state and runtime).
            handler: Async callback that executes the model request and returns
                `ModelResponse`.

        Returns:
            The result of invoking the handler with potentially edited messages.
        r{   r   Sequence[BaseMessage]r   r.   c                     t          |           S rB   r   r   s    r#   r   z>ContextEditingMiddleware.wrap_model_call.<locals>.count_tokens       1(;;;r%   c                d    j                             t          |           z   j                  S rB   modelget_num_tokens_from_messagesr   toolsr   r   
system_msgs    r#   r   z>ContextEditingMiddleware.wrap_model_call.<locals>.count_tokens   /    }AAh/  r%   r   r   r   r   r   r.   r   rz   system_messager   r   rx   r$   overrider"   r   r   r   edited_messageseditr   s    `    @r#   wrap_model_callz(ContextEditingMiddleware.wrap_model_call   s      	$77###"m33< < < < < 6=5KS'011QSJ      
 #4(8#9#9::J 	C 	CDJJ\JBBBBww'''AABBBr%   GCallable[[ModelRequest[ContextT]], Awaitable[ModelResponse[ResponseT]]]c                X  K   j         s |           d{V S | j        dk    rdd}nj        rj        gng dfd}t          t	          j                             }| j        D ]}|                    ||	            |                    |
                     d{V S )r   Nr{   r   r   r   r.   c                     t          |           S rB   r   r   s    r#   r   z?ContextEditingMiddleware.awrap_model_call.<locals>.count_tokens  r   r%   c                d    j                             t          |           z   j                  S rB   r   r   s    r#   r   z?ContextEditingMiddleware.awrap_model_call.<locals>.count_tokens  r   r%   r   r   r   r   r   s    `    @r#   awrap_model_callz)ContextEditingMiddleware.awrap_model_call  s       	* )))))))))"m33< < < < < 6=5KS'011QSJ      
 #4(8#9#9::J 	C 	CDJJ\JBBBBWW---GGHHHHHHHHHr%   )rx   r|   rz   ry   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )	r'   r(   r)   r*   rs   r   r   r   __classcell__)r   s   @r#   rw   rw      s           7777
 /3>K	5 5 5 5 5 5 5 5(#C #C #C #CJ#I #I #I #I #I #I #I #Ir%   rw   N)%r*   
__future__r   collections.abcr   r   r   r   copyr   dataclassesr	   typingr
   langchain_core.messagesr   r   r   r   langchain_core.messages.utilsr   typing_extensionsr   !langchain.agents.middleware.typesr   r   r   r   r   r   rt   r.   r   r   r-   rw   __all__r!   r%   r#   <module>r      s.    # " " " " " C C C C C C C C C C C C       ! ! ! ! ! !                  E D D D D D & & & & & &                '  k	
 
 
 
 
( 
 
 
 ~
 ~
 ~
 ~
 ~
 ~
 ~
 ~
BiI iI iI iI iIz)/DhPY/YZ iI iI iIZ r%   