§
    œŠtj‹  ã                   óP  — U d Z ddlZddlZddlmZmZmZ ddlmZ ddl	m
Z
mZmZmZ ddlmZmZmZmZmZ ddlmZ ddl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&m'Z' eee         ge(f         Z)dZ*	 dZ+dZ,dZ-d e.ddh¦  «        iZ/e0e1e.e1         f         e2d<   de1de1dz  de3fd„Z4e5ed         e6f         Z7	 e5ed         e(f         Z8	 e5ed         e(f         Z9	 e7e8z  e9z  Z:	  G d„ ded¬ ¦  «        Z;d!e&de)fd"„Z< G d#„ d$e!e"e$         e#e$f         ¦  «        Z=dS )%zSummarization middleware.é    N)ÚCallableÚIterableÚMapping)Úpartial)ÚAnyÚLiteralÚ	TypedDictÚcast)Ú	AIMessageÚ
AnyMessageÚMessageLikeRepresentationÚRemoveMessageÚToolMessage©ÚHumanMessage)Úcount_tokens_approximatelyÚget_buffer_stringÚtrim_messages)ÚREMOVE_ALL_MESSAGES)ÚRuntime)Úoverride)ÚAgentMiddlewareÚ
AgentStateÚContextTÚ	ResponseT)ÚBaseChatModelÚinit_chat_modela¤
  <role>
Context Extraction Assistant
</role>

<primary_objective>
Your sole objective in this task is to extract the highest quality/most relevant context from the conversation history below.
</primary_objective>

<objective_information>
You're nearing the total number of input tokens you can accept, so you must extract the highest quality/most relevant pieces of information from your conversation history.
This context will then overwrite the conversation history presented below. Because of this, ensure the context you extract is only the most important information to continue working toward your overall goal.
</objective_information>

<instructions>
The conversation history below will be replaced with the context you extract in this step.
You want to ensure that you don't repeat any actions you've already completed, so the context you extract from the conversation history should be focused on the most important information to your overall goal.

You should structure your summary using the following sections. Each section acts as a checklist - you must populate it with relevant information or explicitly state "None" if there is nothing to report for that section:

## SESSION INTENT

What is the user's primary goal or request? What overall task are you trying to accomplish? This should be concise but complete enough to understand the purpose of the entire session.

## SUMMARY

Extract and record all of the most important context from the conversation history. Include important choices, conclusions, or strategies determined during this conversation. Include the reasoning behind key decisions. Document any rejected options and why they were not pursued.

## ARTIFACTS

What artifacts, files, or resources were created, modified, or accessed during this conversation? For file modifications, list specific file paths and briefly describe the changes made to each. This section prevents silent loss of artifact information.

## NEXT STEPS

What specific tasks remain to be completed to achieve the session intent? What should you do next?

</instructions>

The user will message you with the full message history from which you'll extract context to create a replacement. Carefully read through it all and think deeply about what information is most important to your overall goal and should be saved:

With all of this in mind, please carefully read over the entire conversation history, and extract the most important and relevant context to replace it so that you can free up space in the conversation history.
Respond ONLY with the extracted context. Do not include any additional information, or text before or after the extracted context.

<messages>
Messages to summarize:
{messages}
</messages>é   i   é   Úamazon_bedrockÚbedrockÚbedrock_converseÚ_LS_PROVIDER_ALIASESÚmessage_providerÚmodel_ls_providerÚreturnc                 ó^   — |€dS | |k    rdS t                                |¦  «        }|d uo| |v S )NFT)r#   Úget)r$   r%   Úaliasess      úg/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/langchain/agents/middleware/summarization.pyÚ_provider_matchesr+   g   sH   € ØÐ ØˆuØÐ,Ò,Ð,ØˆtÝ"×&Ò&Ð'8Ñ9Ô9€GØ˜$ÐÐ>Ð#3°wÐ#>Ð>ó    ÚfractionÚtokensÚmessagesc                   ó6   — e Zd ZU dZeed<   	 eed<   	 eed<   dS )ÚTriggerClausea   Dictionary-based trigger specification for AND conditions.

    All specified thresholds in a single `TriggerClause` must be met for the clause to
    trigger summarization (AND semantics). When multiple clauses are provided in a list,
    summarization triggers if any clause is met (OR semantics).

    Example:
        ```python
        # AND: Trigger when tokens >= 4000 AND messages >= 10
        trigger_clause: TriggerClause = {"tokens": 4000, "messages": 10}

        # Use in a list for OR semantics:
        trigger_list: list[TriggerClause] = [
            {"tokens": 5000, "messages": 3},
            {"tokens": 3000, "messages": 6},
        ]
        ```
    r.   r/   r-   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚintÚ__annotations__Úfloat© r,   r*   r1   r1   ®   sG   € € € € € € ðð ð& €K€K�Kðð €M€M�MØCà€O€O�Oðð r,   r1   F)ÚtotalÚmodelc                 ó�   — | j                              d¦  «        rt          t          dd¬¦  «        S t          t          d¬¦  «        S )zATune parameters of approximate token counter based on model type.zanthropic-chatTgffffff
@)Úuse_usage_metadata_scalingÚchars_per_token©r=   )Ú	_llm_typeÚ
startswithr   r   )r;   s    r*   Ú_get_approximate_token_counterrB   Ð   sR   € à„×!Ò!Ð"2Ñ3Ô3ð 
õ Ý&À4ÐY\ð
ñ 
ô 
ð 	
õ Õ-È$ÐOÑOÔOÐOr,   c                   ó&  ‡ — e Zd ZdZddefeeedœdee	z  de
ez  ee
ez           z  dz  de
ded	ed
edz  deddfˆ fd„Zedee         dee         deeef         dz  fd„¦   «         Zedee         dee         deeef         dz  fd„¦   «         Zede
ez  ee
ez           z  dz  de
ez  ee
ez           z  dz  fd„¦   «         Zde
ez  ee
ez           z  dz  dee
         fd„Zde
ez  ee
ez           z  dz  dee         fd„Zdee         dedefd„Zdee         dedefd„Z dee         defd„Z!dee         dedz  fd„Z"dedz  fd„Z#ede
dede
fd„¦   «         Z$ededee%         fd „¦   «         Z&edee         ddfd!„¦   «         Z'ed"ee         d#ede(ee         ee         f         fd$„¦   «         Z)dee         d%edefd&„Z*edee         d#edefd'„¦   «         Z+d(ee         defd)„Z,d(ee         defd*„Z-dee         dee         fd+„Z.ˆ xZ/S ),ÚSummarizationMiddlewarea;  Summarizes conversation history when token limits are approached.

    This middleware monitors message token counts and automatically summarizes older
    messages when a threshold is reached, preserving recent messages and maintaining
    context continuity by ensuring AI/Tool message pairs remain together.
    Nr/   )ÚtriggerÚkeepÚtoken_counterÚsummary_promptÚtrim_tokens_to_summarizer;   rE   rF   rG   rH   rI   Údeprecated_kwargsr&   c                ó¾  •— d|v r,|d         }t          j        dt          d¬¦  «         |€|�d|f}d|v r5|d         }t          j        dt          d¬¦  «         |d	t          fk    rd	|f}t	          ¦   «                              ¦   «          t          |t          ¦  «        rt          |¦  «        }|| _	        |  
                    |¦  «        | _        |                      | j        ¦  «        | _        |                      | j        ¦  «        | _        |                      |d
¦  «        | _        |t$          u r5t'          | j	        ¦  «        | _        t+          | j        d¬¦  «        | _        n|| _        || _        || _        || _        t3          d„ | j        D ¦   «         ¦  «        }	| j        d         dk    rd}	|	r%|                      ¦   «         €d}
t7          |
¦  «        ‚dS dS )a  Initialize summarization middleware.

        Args:
            model: The language model to use for generating summaries.
            trigger: One or more thresholds that trigger summarization.

                Provide a single
                [`ContextSize`][langchain.agents.middleware.summarization.ContextSize]
                tuple, or a single
                [`TriggerClause`][langchain.agents.middleware.summarization.TriggerClause]
                dict, or a list mixing either form.

                A `ContextSize` tuple expresses one threshold. A `TriggerClause` dict
                expresses multiple thresholds that must *all* be met (AND). When a list is
                provided, summarization runs if *any* item is met (OR).

                !!! example

                    ```python
                    # Trigger summarization when 50 messages is reached
                    ("messages", 50)

                    # Trigger summarization when 3000 tokens is reached
                    ("tokens", 3000)

                    # Trigger summarization either when 80% of model's max input tokens
                    # is reached or when 100 messages is reached (whichever comes first)
                    [("fraction", 0.8), ("messages", 100)]

                    # Trigger when tokens >= 4000 AND messages >= 10
                    {"tokens": 4000, "messages": 10}

                    # Trigger when (tokens >= 5000 AND messages >= 3) OR
                    # (tokens >= 3000 AND messages >= 6)
                    [{"tokens": 5000, "messages": 3}, {"tokens": 3000, "messages": 6}]
                    ```

                    See [`ContextSize`][langchain.agents.middleware.summarization.ContextSize]
                    for more details.
            keep: Context retention policy applied after summarization.

                Provide a [`ContextSize`][langchain.agents.middleware.summarization.ContextSize]
                tuple to specify how much history to preserve.

                Defaults to keeping the most recent `20` messages.

                Does not support multiple values like `trigger`.

                !!! example

                    ```python
                    # Keep the most recent 20 messages
                    ("messages", 20)

                    # Keep the most recent 3000 tokens
                    ("tokens", 3000)

                    # Keep the most recent 30% of the model's max input tokens
                    ("fraction", 0.3)
                    ```
            token_counter: Function to count tokens in messages.
            summary_prompt: Prompt template for generating summaries.
            trim_tokens_to_summarize: Maximum tokens to keep when preparing messages for
                the summarization call.

                Pass `None` to skip trimming entirely.
        Úmax_tokens_before_summaryzOmax_tokens_before_summary is deprecated. Use trigger=('tokens', value) instead.é   )Ú
stacklevelNr.   Úmessages_to_keepzEmessages_to_keep is deprecated. Use keep=('messages', value) instead.r/   rF   Fr?   c              3   ó   K  — | ]}d |v V — Œ	dS )r-   Nr9   )Ú.0Úclauses     r*   ú	<genexpr>z3SummarizationMiddleware.__init__.<locals>.<genexpr>d  s'   è è € ÐXÐX¸˜z¨VÐ3ÐXÐXÐXÐXÐXÐXr,   r   r-   Ta  Model profile information is required to use fractional token limits, and is unavailable for the specified model. Please use absolute token counts instead, or pass `

ChatModel(..., profile={"max_input_tokens": ...})`.

with a desired integer value of the model's maximum input tokens.)ÚwarningsÚwarnÚDeprecationWarningÚ_DEFAULT_MESSAGES_TO_KEEPÚsuperÚ__init__Ú
isinstanceÚstrr   r;   Ú_copy_triggerrE   Ú_normalize_triggerÚ_trigger_clausesÚ_legacy_trigger_conditionsÚ_trigger_conditionsÚ_validate_context_sizerF   r   rB   rG   r   Ú_partial_token_counterrH   rI   ÚanyÚ_get_profile_limitsÚ
ValueError)Úselfr;   rE   rF   rG   rH   rI   rJ   ÚvalueÚrequires_profileÚmsgÚ	__class__s              €r*   rY   z SummarizationMiddleware.__init__ã   s'  ø€ ð^ 'Ð*;Ð;Ð;Ø%Ð&AÔBˆEÝŒMØaÝ"Øðñ ô ð ð
 ˆ 5Ð#4Ø# UÐ+�àÐ!2Ð2Ð2Ø%Ð&8Ô9ˆEÝŒMØWÝ"Øðñ ô ð ð
 ˜
Õ$=Ð>Ò>Ð>Ø" EÐ*�å‰Œ×ÒÑÔÐå�e�SÑ!Ô!ð 	+Ý# EÑ*Ô*ˆEàˆŒ
ð ×Ò˜wÑ'Ô'ð 	Œð
 !%× 7Ò 7¸¼Ñ EÔ EˆÔð $(×#BÒ#BÀ4Ä<Ñ#PÔ#PˆÔ à×/Ò/°°fÑ=Ô=ˆŒ	ØÕ6Ð6Ð6Ý!?ÀÄ
Ñ!KÔ!KˆDÔÝ8?ØÔ"¸uð9ñ 9ô 9ˆDÔ'Ð'ð "/ˆDÔØ*7ˆDÔ'Ø,ˆÔØ(@ˆÔ%åÐXÐXÀ$ÔBWÐXÑXÔXÑXÔXÐØŒ9�QŒ<˜:Ò%Ð%Ø#ÐØð 	" × 8Ò 8Ñ :Ô :Ð BðTð õ ˜S‘/”/Ð!ð	"ð 	"Ð BÐ Br,   ÚstateÚruntimec                 óŽ  — |d         }|                       |¦  «         |                      |¦  «        }|                      ||¦  «        sdS |                      |¦  «        }|dk    rdS |                      ||¦  «        \  }}|                      |¦  «        }|                      |¦  «        }	dt          t          ¬¦  «        g|	¢|¢iS ©a!  Process messages before model invocation, potentially triggering summarization.

        Args:
            state: The agent state.
            runtime: The runtime environment.

        Returns:
            An updated state with summarized messages if summarization was performed.
        r/   Nr   ©Úid)	Ú_ensure_message_idsrG   Ú_should_summarizeÚ_determine_cutoff_indexÚ_partition_messagesÚ_create_summaryÚ_build_new_messagesr   r   ©
rf   rk   rl   r/   Útotal_tokensÚcutoff_indexÚmessages_to_summarizeÚpreserved_messagesÚsummaryÚnew_messagess
             r*   Úbefore_modelz$SummarizationMiddleware.before_modelq  sî   € ð ˜Ô$ˆØ× Ò  Ñ*Ô*Ð*à×)Ò)¨(Ñ3Ô3ˆØ×%Ò% h°Ñ=Ô=ð 	Ø�4à×3Ò3°HÑ=Ô=ˆà˜1ÒÐØ�4à48×4LÒ4LÈXÐWcÑ4dÔ4dÑ1ÐÐ1à×&Ò&Ð'<Ñ=Ô=ˆØ×/Ò/°Ñ8Ô8ˆð ÝÕ!4Ð5Ñ5Ô5ðàðð $ðð
ð 	
r,   c              ƒ   óž  K  — |d         }|                       |¦  «         |                      |¦  «        }|                      ||¦  «        sdS |                      |¦  «        }|dk    rdS |                      ||¦  «        \  }}|                      |¦  «        ƒ d{V —†}|                      |¦  «        }	dt          t          ¬¦  «        g|	¢|¢iS rn   )	rq   rG   rr   rs   rt   Ú_acreate_summaryrv   r   r   rw   s
             r*   Úabefore_modelz%SummarizationMiddleware.abefore_model—  s  è è € ð ˜Ô$ˆØ× Ò  Ñ*Ô*Ð*à×)Ò)¨(Ñ3Ô3ˆØ×%Ò% h°Ñ=Ô=ð 	Ø�4à×3Ò3°HÑ=Ô=ˆà˜1ÒÐØ�4à48×4LÒ4LÈXÐWcÑ4dÔ4dÑ1ÐÐ1à×-Ò-Ð.CÑDÔDÐDÐDÐDÐDÐDÐDˆØ×/Ò/°Ñ8Ô8ˆð ÝÕ!4Ð5Ñ5Ô5ðàðð $ðð
ð 	
r,   c                 ó¬   — t          | t          ¦  «        rt          dt          | ¦  «        ¦  «        S t          | t          ¦  «        rd„ | D ¦   «         S | S )zPCopy mutable trigger containers so caller mutations do not affect this instance.r1   c                 óv   — g | ]6}t          |t          ¦  «        rt          d t          |¦  «        ¦  «        n|‘Œ7S )r1   )rZ   r   r
   Údict)rQ   Úitems     r*   ú
<listcomp>z9SummarizationMiddleware._copy_trigger.<locals>.<listcomp>Å  sN   € ð ð ð àõ 6@ÀÅgÑ5NÔ5NÐX•�_¥d¨4¡j¤jÑ1Ô1Ð1ÐTXðð ð r,   )rZ   r   r
   r„   Úlist)rE   s    r*   r\   z%SummarizationMiddleware._copy_trigger½  sf   € õ
 �g�wÑ'Ô'ð 	8Ý˜­¨g©¬Ñ7Ô7Ð7Ý�g�tÑ$Ô$ð 	ðð à#ðñ ô ð ð ˆr,   c           
      ó  — |€g S t          |t          ¦  «        r|                      |d¦  «        gS t          |t          ¦  «        rmt	          |¦  «        dk    rg S t          t          |                     ¦   «         ¦  «        ¦  «        \  }}|                      t          d||f¦  «        d¦  «        gS g }|D ]Ó}t          |t          ¦  «        r*| 	                    |                      |d¦  «        ¦  «         ŒAt          |t          ¦  «        r}t	          |¦  «        dk    rjt          t          |                     ¦   «         ¦  «        ¦  «        \  }}| 	                    |                      t          d||f¦  «        d¦  «        ¦  «         ŒÔ|S )zHProject tuple-expressible triggers to the legacy private representation.NrE   é   ÚContextSize)
rZ   Útuplera   r   ÚlenÚnextÚiterÚitemsr
   Úappend)rf   rE   Úkindrg   Ú
conditionsr…   s         r*   r_   z2SummarizationMiddleware._legacy_trigger_conditionsË  s}  € ð
 ˆ?ØˆIÝ�g�uÑ%Ô%ð 	EØ×/Ò/°¸ÑCÔCÐDÐDÝ�g�wÑ'Ô'ð 	`Ý�7‰|Œ|˜qÒ Ð Ø�	Ý�t G§M¢M¡O¤OÑ4Ô4Ñ5Ô5‰KˆD�%Ø×/Ò/µ°]ÀTÈ5ÀMÑ0RÔ0RÐT]Ñ^Ô^Ð_Ð_à(*ˆ
Øð 	ð 	ˆDÝ˜$¥Ñ&Ô&ð Ø×!Ò! $×"=Ò"=¸dÀIÑ"NÔ"NÑOÔOÐOÐOÝ˜D¥'Ñ*Ô*ð ­s°4©y¬y¸Aª~¨~Ý"¥4¨¯
ª
©¬Ñ#5Ô#5Ñ6Ô6‘��eØ×!Ò!Ø×/Ò/µ°]ÀTÈ5ÀMÑ0RÔ0RÐT]Ñ^Ô^ñô ð øð Ðr,   c           	      ó  ‡ — |€g S dt           dt          fˆ fd„}dt          t          t          f         dt          fˆ fd„}g }|}t          |t          ¦  «        r |                      ||¦  «        ¦  «         �nt          |t          ¦  «        r-|                      |t          d|¦  «        ¦  «        ¦  «         nÒt          |t          ¦  «        rœ|D ]˜}t          |t          ¦  «        r|                      ||¦  «        ¦  «         Œ6t          |t          ¦  «        r-|                      |t          d|¦  «        ¦  «        ¦  «         Œxdt          |¦  «        › �}t          |¦  «        ‚n!d	t          |¦  «        › �}t          |¦  «        ‚|S )
a  Normalize supported trigger inputs into list of Trigger clauses.

        - tuple ("tokens", 3000) -> [{"tokens": 3000}]
        - dict {"tokens": 4000, "messages": 10} -> [{"tokens": 4000, "messages": 10}]
        - list of either -> OR across items
        NÚtr&   c                 óZ   •— ‰                      | d¦  «        \  }}t          d||i¦  «        S )NrE   r1   )ra   r
   )r”   r‘   rg   rf   s      €r*   Ú_validate_and_convert_tuplezOSummarizationMiddleware._normalize_trigger.<locals>._validate_and_convert_tupleò  s0   ø€ Ø×5Ò5°a¸ÑCÔC‰KˆD�%Ý˜¨$°¨Ñ7Ô7Ð7r,   Úmc                 ó"  •— | sd}t          |¦  «        ‚i }|                      ¦   «         D ]Õ\  }}|dvrd|›�}t          |¦  «        ‚t          |t          ¦  «        r|› d|›�}t          |¦  «        ‚|dk    r1t          |t          t
          f¦  «        sd|›�}t          |¦  «        ‚n+t          |t          ¦  «        s|› d|›�}t          |¦  «        ‚‰                     t          d||f¦  «        d	¦  «         |||<   ŒÖt          d
|¦  «        S )aÃ  Validate and convert a mapping to a TriggerClause.

            Type checks reject silent coercion (booleans, numeric strings, and
            fractional floats for integer metrics) so a misconfigured clause fails loudly
            at construction. Range and positivity checks are delegated to
            `_validate_context_size`, keeping a single source of truth for the rules and
            error messages shared with the tuple form.
            zLtrigger clause must specify at least one of 'tokens', 'messages', 'fraction'>   r.   r-   r/   zUnsupported trigger metric: z$ trigger value must be numeric, got r-   z-Fraction trigger values must be numeric, got z& trigger values must be integers, got rŠ   rE   r1   )re   r�   rZ   Úboolr6   r8   ra   r
   )r—   ri   ÚoutÚkÚvrf   s        €r*   Ú_validate_mappingzESummarizationMiddleware._normalize_trigger.<locals>._validate_mappingö  sG  ø€ ð ð &Ød�Ý  ‘o”oÐ%Ø*,ˆCØŸš™	œ	ð ð ‘��1ØÐ>Ð>Ð>Ø>¸Ð>Ð>�CÝ$ S™/œ/Ð)õ ˜a¥Ñ&Ô&ð *ØÐIÐIÀAÐIÐI�CÝ$ S™/œ/Ð)Ø˜
’?�?Ý% a­#­u¨Ñ6Ô6ð .ØSÈaÐSÐS˜Ý(¨™oœoÐ-ð.õ $ A¥sÑ+Ô+ð *àÐKÐKÀaÐKÐK�CÝ$ S™/œ/Ð)ð ×+Ò+­D°ÀÀAÀÑ,GÔ,GÈÑSÔSÐSØ��A‘�Ý˜¨Ñ-Ô-Ð-r,   rŠ   zUnsupported trigger item type: zUnsupported trigger type: )rŠ   r1   r   r[   r   rZ   r�   r‹   r
   r‡   ÚtypeÚ	TypeError)rf   rE   r–   r�   ÚclausesÚsubjectr…   ri   s   `       r*   r]   z*SummarizationMiddleware._normalize_triggerå  sË  ø€ ð ˆ?ØˆIð	8­;ð 	8½=ð 	8ð 	8ð 	8ð 	8ð 	8ð 	8ð#	.¥­­c¨Ô!2ð #	.µ}ð #	.ð #	.ð #	.ð #	.ð #	.ð #	.ðJ (*ˆð ˆÝ�g�wÑ'Ô'ð 	!Ø�NŠNÐ,Ð,¨WÑ5Ô5Ñ6Ô6Ð6Ñ6Ý˜¥Ñ'Ô'ð 	!Ø�NŠNÐ6Ð6µt¸MÈ7Ñ7SÔ7SÑTÔTÑUÔUÐUÐUÝ˜¥Ñ&Ô&ð 	!Øð )ð )�Ý˜d¥GÑ,Ô,ð )Ø—N’NÐ#4Ð#4°TÑ#:Ô#:Ñ;Ô;Ð;Ð;Ý ¥eÑ,Ô,ð )Ø—N’NÐ#>Ð#>½tÀMÐSWÑ?XÔ?XÑ#YÔ#YÑZÔZÐZÐZàH½DÀ¹J¼JÐHÐH�CÝ# C™.œ.Ð(ð)ð ?­t°G©}¬}Ð>Ð>ˆCÝ˜C‘.”.Ð Øˆr,   Ú	thresholdc                 ó‚  — t          d„ t          |¦  «        D ¦   «         d¦  «        }t          |t          ¦  «        r‚|j        �{|j                             dd¦  «        x}r^||k    rX|j                             d¦  «        x}r<t          || j         	                    ¦   «                              d¦  «        ¦  «        rdS dS )	zDCheck if reported token usage from last AIMessage exceeds threshold.c              3   óD   K  — | ]}t          |t          ¦  «        ¯|V — Œd S )N)rZ   r   )rQ   ri   s     r*   rS   zUSummarizationMiddleware._should_summarize_based_on_reported_tokens.<locals>.<genexpr>6  s1   è è € ÐMÐM�Sµ*¸SÅ)Ñ2LÔ2LÐMˆSÐMÐMÐMÐMÐMÐMr,   Nrx   éÿÿÿÿÚmodel_providerÚls_providerTF)
r�   ÚreversedrZ   r   Úusage_metadatar(   Úresponse_metadatar+   r;   Ú_get_ls_params)rf   r/   r¢   Úlast_ai_messageÚreported_tokensr$   s         r*   Ú*_should_summarize_based_on_reported_tokenszBSummarizationMiddleware._should_summarize_based_on_reported_tokens1  sØ   € õ ØMÐM�H XÑ.Ô.ÐMÑMÔMØñ
ô 
ˆõ
 �­	Ñ2Ô2ð	àÔ.Ð:Ø$3Ô$B×$FÒ$FÀ~ÐWYÑ$ZÔ$ZÐZ�ð ;à 9Ò,Ð,Ø%4Ô%F×%JÒ%JÐK[Ñ%\Ô%\Ð\Ð!ð -å!Ø Ø”
×)Ò)Ñ+Ô+×/Ò/°Ñ>Ô>ñô ð -ð �4Øˆur,   rx   c           	      ó8  — | j         sdS | j         D �]}d}|                     ¦   «         D ]è\  }}|dk    r%t          |¦  «        t          d|¦  «        k     rd} n¹|dk    r=t          d|¦  «        }||k     r'|                      |t          |¦  «        ¦  «        sd} nv|dk    ro|                      ¦   «         }|€d} nVt          |t          d|¦  «        z  ¦  «        }	|	d	k    rd
}	||	k     r'|                      |t          |	¦  «        ¦  «        sd} nŒé|r dS �Œ	dS )zGDetermine whether summarization should run for the current token usage.FTr/   r6   r.   r-   Nr8   r   r‰   )r^   r�   rŒ   r
   r®   r8   rd   r6   )
rf   r/   rx   rR   Ú
clause_metr‘   rg   Úthreshold_tokensÚmax_input_tokensr¢   s
             r*   rr   z)SummarizationMiddleware._should_summarizeG  s|  € àÔ$ð 	Ø�5àÔ+ð "	ñ "	ˆFØˆJØ%Ÿ|š|™~œ~ð ð ‘��eØ˜:Ò%Ð%­#¨h©-¬-½$¸uÀeÑ:LÔ:LÒ*LÐ*LØ!&�JØ�EØ˜8Ò#Ð#Ý'+¨E°5Ñ'9Ô'9Ð$ð %Ð'7Ò7Ð7Ø $× OÒ OØ$¥eÐ,<Ñ&=Ô&=ñ!ô !ð 8ð
 &+˜
Ø˜Ø˜:Ò%Ð%Ø'+×'?Ò'?Ñ'AÔ'AÐ$Ø'Ð/Ø%*˜
Ø˜Ý #Ð$4µt¸GÀUÑ7KÔ7KÑ$KÑ LÔ L�IØ  A’~�~Ø$%˜	à$ yÒ0Ð0Ø $× OÒ OØ$¥e¨IÑ&6Ô&6ñ!ô !ð 1ð
 &+˜
Ø˜øØð Ø�t�tñàˆur,   c                 óÎ   — | j         \  }}|dv r4|                      |¦  «        }|�|S |                      |t          ¦  «        S |                      |t	          d|¦  «        ¦  «        S )z7Choose cutoff index respecting retention configuration.>   r.   r-   Nr6   )rF   Ú_find_token_based_cutoffÚ_find_safe_cutoffrW   r
   )rf   r/   r‘   rg   Útoken_based_cutoffs        r*   rs   z/SummarizationMiddleware._determine_cutoff_indexq  sr   € à”i‰ˆˆeØÐ)Ð)Ð)Ø!%×!>Ò!>¸xÑ!HÔ!HÐØ!Ð-Ø)Ð)ð ×)Ò)¨(Õ4MÑNÔNÐNØ×%Ò% hµ°U¸EÑ0BÔ0BÑCÔCÐCr,   c                 óâ  — |sdS | j         \  }}|dk    r+|                      ¦   «         }|€dS t          ||z  ¦  «        }n|dk    rt          |¦  «        }ndS |dk    rd}|                      |¦  «        |k    rdS dt	          |¦  «        }}t	          |¦  «        }t	          |¦  «                             ¦   «         dz   }	t          |	¦  «        D ]=}
||k    r n4||z   dz  }|                      ||d…         ¦  «        |k    r|}|}Œ8|dz   }Œ>|t	          |¦  «        k    r|}|t	          |¦  «        k    r't	          |¦  «        dk    rdS t	          |¦  «        dz
  }|                      ||¦  «        S )z2Find cutoff index based on target token retention.r   r-   Nr.   r‰   rM   )	rF   rd   r6   rG   rŒ   Ú
bit_lengthÚrangerb   Ú_find_safe_cutoff_point)rf   r/   r‘   rg   r²   Útarget_token_countÚleftÚrightÚcutoff_candidateÚmax_iterationsÚ_Úmids               r*   r´   z0SummarizationMiddleware._find_token_based_cutoff}  s¶  € àð 	Ø�1à”i‰ˆˆeØ�:ÒÐØ#×7Ò7Ñ9Ô9ÐØÐ'Ø�tÝ!$Ð%5¸Ñ%=Ñ!>Ô!>ÐÐØ�XÒÐÝ!$ U¡¤ÐÐà�4à Ò"Ð"Ø!"Ðà×Ò˜hÑ'Ô'Ð+=Ò=Ð=Ø�1ð �˜X™œˆeˆÝ˜x™=œ=ÐÝ˜X™œ×1Ò1Ñ3Ô3°aÑ7ˆÝ�~Ñ&Ô&ð 		ð 		ˆAØ�uŠ}ˆ}Ø�à˜%‘< AÑ%ˆCØ×*Ò*¨8°C°D°D¬>Ñ:Ô:Ð>PÒPÐPØ#&Ð Ø��à˜Q‘w��à�s 8™}œ}Ò,Ð,Ø#Ðà�s 8™}œ}Ò,Ð,Ý�8‰}Œ} Ò!Ð!Ø�qÝ" 8™}œ}¨qÑ0Ðð ×+Ò+¨HÐ6FÑGÔGÐGr,   c                 óÊ   — 	 | j         j        }n# t          $ r Y dS w xY wt          |t          ¦  «        sdS |                     d¦  «        }t          |t          ¦  «        sdS |S )z6Retrieve max input token limit from the model profile.Nr²   )r;   ÚprofileÚAttributeErrorrZ   r   r(   r6   )rf   rÃ   r²   s      r*   rd   z+SummarizationMiddleware._get_profile_limits®  s   € ð	Ø”jÔ(ˆGˆGøÝð 	ð 	ð 	Ø�4�4ð	øøøõ ˜'¥7Ñ+Ô+ð 	Ø�4à"Ÿ;š;Ð'9Ñ:Ô:ÐåÐ*­CÑ0Ô0ð 	Ø�4àÐs   ‚ �
œÚcontextÚparameter_namec                 óà   — | \  }}|dk    r(d|cxk     rdk    sn d|› d|› d�}t          |¦  «        ‚n:|dv r|dk    r|› d|› d�}t          |¦  «        ‚nd	|› d
|› d�}t          |¦  «        ‚| S )z&Validate context configuration tuples.r-   r   r‰   zFractional z% values must be between 0 and 1, got ú.>   r.   r/   z( thresholds must be greater than 0, got zUnsupported context size type z for )re   )rÅ   rÆ   r‘   rg   ri   s        r*   ra   z.SummarizationMiddleware._validate_context_size¿  sÄ   € ð ‰ˆˆeØ�:ÒÐØ�u�>�>’>�> ’>�>�>�>Øa NÐaÐaÐY^ÐaÐaÐa�Ý  ‘o”oÐ%ð "ð Ð+Ð+Ð+Ø˜ŠzˆzØ'ÐYÐYÐQVÐYÐYÐY�Ý  ‘o”oÐ%ð ð P°4ÐOÐO¸nÐOÐOÐOˆCÝ˜S‘/”/Ð!Øˆr,   r|   c                 ó0   — t          d| › �ddi¬¦  «        gS )Nz0Here is a summary of the conversation to date:

Ú	lc_sourceÚsummarization)ÚcontentÚadditional_kwargsr   )r|   s    r*   rv   z+SummarizationMiddleware._build_new_messagesÐ  s3   € õ ØVÈWÐVÐVØ#.°Ð"@ðñ ô ð
ð 	
r,   c                 óh   — | D ].}|j         €%t          t          j        ¦   «         ¦  «        |_         Œ/dS )zAEnsure all messages have unique IDs for the add_messages reducer.N)rp   r[   ÚuuidÚuuid4)r/   ri   s     r*   rq   z+SummarizationMiddleware._ensure_message_idsÙ  s:   € ð ð 	+ð 	+ˆCØŒvˆ~Ý�TœZ™\œ\Ñ*Ô*�”øð	+ð 	+r,   Úconversation_messagesry   c                 ó2   — | d|…         }| |d…         }||fS )zAPartition messages into those to summarize and those to preserve.Nr9   )rÑ   ry   rz   r{   s       r*   rt   z+SummarizationMiddleware._partition_messagesà  s.   € ð !6°m°|°mÔ DÐØ2°<°=°=ÔAÐà$Ð&8Ð8Ð8r,   rO   c                 ó|   — t          |¦  «        |k    rdS t          |¦  «        |z
  }|                      ||¦  «        S )a†  Find safe cutoff point that preserves AI/Tool message pairs.

        Returns the index where messages can be safely cut without separating
        related AI and Tool messages. Returns `0` if no safe cutoff is found.

        This is aggressive with summarization - if the target cutoff lands in the
        middle of tool messages, we advance past all of them (summarizing more).
        r   )rŒ   rº   )rf   r/   rO   Útarget_cutoffs       r*   rµ   z)SummarizationMiddleware._find_safe_cutoffë  sB   € õ ˆx‰=Œ=Ð,Ò,Ð,Ø�1å˜H™œÐ(8Ñ8ˆØ×+Ò+¨H°mÑDÔDÐDr,   c                 ó`  — |t          | ¦  «        k    st          | |         t          ¦  «        s|S t          ¦   «         }|}|t          | ¦  «        k     r…t          | |         t          ¦  «        rjt	          d| |         ¦  «        }|j        r|                     |j        ¦  «         |dz  }|t          | ¦  «        k     rt          | |         t          ¦  «        °jt          |dz
  dd¦  «        D ]@}| |         }t          |t          ¦  «        r!|j	        rd„ |j	        D ¦   «         }||z  r|c S ŒA|S )aË  Find a safe cutoff point that doesn't split AI/Tool message pairs.

        If the message at `cutoff_index` is a `ToolMessage`, search backward for the
        `AIMessage` containing the corresponding `tool_calls` and adjust the cutoff to
        include it. This ensures tool call requests and responses stay together.

        Falls back to advancing forward past `ToolMessage` objects only if no matching
        `AIMessage` is found (edge case).
        r   r‰   r¥   c                 ób   — h | ],}|                      d ¦  «        ¯|                      d ¦  «        ’Œ-S ro   )r(   )rQ   Útcs     r*   ú	<setcomp>zBSummarizationMiddleware._find_safe_cutoff_point.<locals>.<setcomp>  s2   € Ð#ZÐ#ZÐ#Z°RÈRÏVÊVÐTXÉ\Ì\Ð#Z B§F¢F¨4¡L¤LÐ#ZÐ#ZÐ#Zr,   )
rŒ   rZ   r   Úsetr
   Útool_call_idÚaddr¹   r   Ú
tool_calls)r/   ry   Útool_call_idsÚidxÚtool_msgÚiri   Úai_tool_call_idss           r*   rº   z/SummarizationMiddleware._find_safe_cutoff_pointú  sC  € ð �3˜x™=œ=Ò(Ð(µ
¸8ÀLÔ;QÕS^Ñ0_Ô0_Ð(ØÐõ #&¡%¤%ˆØˆØ•C˜‘M”MÒ!Ð!¥j°¸#´ÅÑ&LÔ&LÐ!Ý˜M¨8°C¬=Ñ9Ô9ˆHØÔ$ð 9Ø×!Ò! (Ô"7Ñ8Ô8Ð8Ø�1‰HˆCð	 •C˜‘M”MÒ!Ð!¥j°¸#´ÅÑ&LÔ&LÐ!õ �| aÑ'¨¨RÑ0Ô0ð 	ð 	ˆAØ˜1”+ˆCÝ˜#�yÑ)Ô)ð ¨c¬nð Ø#ZÐ#Z¸3¼>Ð#ZÑ#ZÔ#ZÐ Ø Ð#3Ñ3ð à�H�H�Høð ˆ
r,   rz   c                 ó`  — |sdS |                       |¦  «        }|sdS t          |d¬¦  «        }	 | j                             | j                             |¬¦  «                             ¦   «         dddii¬	¦  «        }|j                             ¦   «         S # t          $ r}d
|›�cY d}~S d}~ww xY w)úzGenerate summary for the given messages.

        Args:
            messages_to_summarize: Messages to summarize.
        ú!No previous conversation history.ú0Previous conversation was too long to summarize.Úxml©Úformat©r/   ÚmetadatarÊ   rË   ©ÚconfigúError generating summary: N)
Ú_trim_messages_for_summaryr   r;   ÚinvokerH   rè   ÚrstripÚtextÚstripÚ	Exception©rf   rz   Útrimmed_messagesÚformatted_messagesÚresponseÚes         r*   ru   z'SummarizationMiddleware._create_summary  sð   € ð %ð 	7Ø6Ð6à×:Ò:Ð;PÑQÔQÐØð 	FØEÐEõ /Ð/?ÈÐNÑNÔNÐð	6Ø”z×(Ò(ØÔ#×*Ò*Ð4FÐ*ÑGÔG×NÒNÑPÔPØ" [°/Ð$BÐCð )ñ ô ˆHð ”=×&Ò&Ñ(Ô(Ð(øÝð 	6ð 	6ð 	6Ø5°Ð5Ð5Ð5Ð5Ð5Ð5Ð5Ð5øøøøð	6øøøs   °A#B Â
B-ÂB(Â"B-Â(B-c              ƒ   óp  K  — |sdS |                       |¦  «        }|sdS t          |d¬¦  «        }	 | j                             | j                             |¬¦  «                             ¦   «         dddii¬	¦  «        ƒ d
{V —†}|j                             ¦   «         S # t          $ r}d|›�cY d
}~S d
}~ww xY w)rã   rä   rå   ræ   rç   ré   rê   rÊ   rË   rë   Nrí   )
rî   r   r;   ÚainvokerH   rè   rð   rñ   rò   ró   rô   s         r*   r€   z(SummarizationMiddleware._acreate_summary8  s  è è € ð %ð 	7Ø6Ð6à×:Ò:Ð;PÑQÔQÐØð 	FØEÐEõ /Ð/?ÈÐNÑNÔNÐð	6Ø!œZ×/Ò/ØÔ#×*Ò*Ð4FÐ*ÑGÔG×NÒNÑPÔPØ" [°/Ð$BÐCð 0ñ ô ð ð ð ð ð ð ˆHð ”=×&Ò&Ñ(Ô(Ð(øÝð 	6ð 	6ð 	6Ø5°Ð5Ð5Ð5Ð5Ð5Ð5Ð5Ð5øøøøð	6øøøs   ²A)B Â
B5Â&B0Â*B5Â0B5c                 ó²   — 	 | j         €|S t          dt          || j         | j        dddd¬¦  «        ¦  «        S # t          $ r |t
           d…         cY S w xY w)z6Trim messages to fit within summary generation limits.Nzlist[AnyMessage]ÚhumanÚlastT)Ú
max_tokensrG   Ústart_onÚstrategyÚallow_partialÚinclude_system)rI   r
   r   rG   ró   Ú_DEFAULT_FALLBACK_MESSAGE_COUNT)rf   r/   s     r*   rî   z2SummarizationMiddleware._trim_messages_for_summaryR  s�   € ð	?ØÔ,Ð4Ø�ÝØ"ÝØØ#Ô<Ø"&Ô"4Ø$Ø#Ø"&Ø#'ðñ ô ñô ð øõ ð 	?ð 	?ð 	?ØÕ<Ð<Ð=Ð=Ô>Ð>Ð>Ð>ð	?øøøs   ‚9 ‹-9 ¹AÁA)0r2   r3   r4   r5   rW   r   ÚDEFAULT_SUMMARY_PROMPTÚ_DEFAULT_TRIM_TOKEN_LIMITr[   r   rŠ   r1   r‡   ÚTokenCounterr6   r   rY   r   r   r   r   r„   r~   r�   Ústaticmethodr\   r_   r]   r   r8   r™   r®   rr   rs   r´   rd   ra   r   rv   rq   r‹   rt   rµ   rº   ru   r€   rî   Ú__classcell__)rj   s   @r*   rD   rD   Û   s8  ø€ € € € € ðð ð ]aØ'Ð)BÐCØ&@Ø4Ø/HðL"ð L"ð L"à�]Ñ"ðL"ð  Ñ-°°[À=Ñ5PÔ0QÑQÐTXÑXð	L"ð
 ðL"ð $ðL"ð ðL"ð #&¨¡*ðL"ð !ðL"ð 
ðL"ð L"ð L"ð L"ð L"ð L"ð\ ð#
Ø ”_ð#
Ø/6°xÔ/@ð#
à	ˆc�3ˆhŒ˜$Ñ	ð#
ð #
ð #
ñ „Xð#
ðJ ð#
Ø ”_ð#
Ø/6°xÔ/@ð#
à	ˆc�3ˆhŒ˜$Ñ	ð#
ð #
ð #
ñ „Xð#
ðJ ðØ˜}Ñ,¨t°KÀ-Ñ4OÔ/PÑPÐSWÑWðà	�}Ñ	$ t¨K¸-Ñ,GÔ'HÑ	HÈ4Ñ	Oðð ð ñ „\ððà˜}Ñ,¨t°KÀ-Ñ4OÔ/PÑPÐSWÑWðð 
ˆkÔ	ðð ð ð ð4Jà Ñ-°°[À=Ñ5PÔ0QÑQÐTXÑXðJð 
ˆmÔ	ðJð Jð Jð JðXØ˜ZÔ(ðØ5:ðà	ðð ð ð ð,(¨$¨zÔ*:ð (È#ð (ÐRVð (ð (ð (ð (ðT
D°°ZÔ0@ð 
DÀSð 
Dð 
Dð 
Dð 
Dð/H°°jÔ1Að /HÀcÈDÁjð /Hð /Hð /Hð /Hðb  S¨4¡Zð  ð  ð  ð  ð" ð¨ð ÀSð È[ð ð ð ñ „\ðð  ð
 Sð 
¨T°,Ô-?ð 
ð 
ð 
ñ „\ð
ð ð+ d¨:Ô&6ð +¸4ð +ð +ð +ñ „\ð+ð ð9Ø# JÔ/ð9àð9ð 
ˆt�JÔ  jÔ!1Ð1Ô	2ð9ð 9ð 9ñ „\ð9ðE¨$¨zÔ*:ð EÈcð EÐVYð Eð Eð Eð Eð ð!¨$¨zÔ*:ð !È#ð !ÐRUð !ð !ð !ñ „\ð!ðF6°T¸*Ô5Eð 6È#ð 6ð 6ð 6ð 6ð46¸DÀÔ<Lð 6ÐQTð 6ð 6ð 6ð 6ð4?°4¸
Ô3Cð ?ÈÈZÔHXð ?ð ?ð ?ð ?ð ?ð ?ð ?ð ?r,   rD   )>r5   rÏ   rT   Úcollections.abcr   r   r   Ú	functoolsr   Útypingr   r   r	   r
   Úlangchain_core.messagesr   r   r   r   r   Úlangchain_core.messages.humanr   Úlangchain_core.messages.utilsr   r   r   Úlanggraph.graph.messager   Úlanggraph.runtimer   Útyping_extensionsr   Ú!langchain.agents.middleware.typesr   r   r   r   Úlangchain.chat_modelsr   r   r6   r  r  rW   r  r  Ú	frozensetr#   r„   r[   r7   r™   r+   r‹   r8   ÚContextFractionÚContextTokensÚContextMessagesrŠ   r1   rB   rD   r9   r,   r*   ú<module>r     s5  ðØ Ð Ð à €€€Ø €€€Ø 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ø Ð Ð Ð Ð Ð Ø 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0ðð ð ð ð ð ð ð ð ð ð ð ð ð ð 7Ð 6Ð 6Ð 6Ð 6Ð 6ðð ð ð ð ð ð ð ð ð ð
ð ð ð ð ð ð &Ð %Ð %Ð %Ð %Ð %Ø &Ð &Ð &Ð &Ð &Ð &à ^Ð ^Ð ^Ð ^Ð ^Ð ^Ð ^Ð ^Ð ^Ð ^Ð ^Ð ^Ø @Ð @Ð @Ð @Ð @Ð @Ð @Ð @à˜Ð";Ô<Ð=¸sÐBÔC€ð-Ð ð\
ð Ð Ø Ð Ø"$Ð ð �i�i Ð,>Ð ?Ñ@Ô@ð3Ð �d˜3 	¨#¤Ð.Ô/ð ð ñ ð
?¨ð ?ÀÀdÁ
ð ?Ètð ?ð ?ð ?ð ?ð ˜ 
Ô+¨UÐ2Ô3€ðð �g˜hÔ'¨Ð,Ô-€ðð ˜ 
Ô+¨SÐ0Ô1€ðð  Ñ-°Ñ?€ðð8ð ð ð ð �I Uð ñ ô ð ðDP¨-ð P¸Lð Pð Pð Pð PðI
?ð I
?ð I
?ð I
?ð I
?˜o¨j¸Ô.CÀXÈyÐ.XÔYñ I
?ô I
?ð I
?ð I
?ð I
?r,   