
    CjG                        S r SSKJrJrJrJrJrJrJrJ	r	  SSK
Jr  SSKJrJrJr  SSKJr  SSKJr  SSKJr  SSKJr  SS	KJr  \" \R6                  R8                  15      r\" \R<                  R8                  \R>                  R8                  \R6                  R8                  15      r S
\\\!4   S\!4S jr"S
\!S\#4S jr$S\\!   S
\!S\\%   4S jr&S\S\!4S jr'S\\%   S
\!S\\\%   \\%   4   4S jr(S\\%   S\!4S jr)S\S\\!   4S jr*S\S\\!   4S jr+S\\%   S\\\\,      \\!   4   4S jr-S\\%   S\\,   4S jr. S.S\\/   S\\/   S\/S\\/   4S jjr0S\\%   S\\%   S\\/   S \,S!\!S"\\,   S#\\\,      S\\\,   \\,\%4   4   4S$ jr1S%\\,   S#\\\,      S\\,   4S& jr2\R<                  S'S(S(S(S(4S\\%   S!\!S
\\\!4   S)\,S \\,   S*\\!   S+\\\!\4      S,\\   S\4S- jjr3g()/u   
Main compress() function — normalizes input messages, orchestrates BM25/embedding
scoring, message stubbing, and retrieval tool injection.
    )AnyDictListOptionalSetTupleUnioncast)	DualCache)extract_keystub_messagetruncate_message)build_retrieval_tool)bm25_score_messages)token_counter)CompressedResult)	CallTypes	call_typereturnc                 H    [        U [        5      (       a  U R                  $ U $ )zAReturn the string value for a ``CallTypes`` enum or a raw string.)
isinstancer   valuer   s    n/home/rurouni/.local/share/pipx/venvs/strix-agent/lib/python3.13/site-packages/litellm/compression/compress.py_normalize_call_typer   #   s    )Y''    c                     U [         ;   $ N)_ANTHROPIC_CALL_TYPESr   s    r   _is_anthropic_call_typer    *   s    ---r   keysc                     U (       d  / $ [        U 5      /n[        U5      (       d  U$ SSKJn  U" 5       R	                  U5      u  pE[        [        [           U5      $ )z
Build retrieval tool definitions in the target request schema.

- Chat-completions call types: keep OpenAI function-tool schema.
- Anthropic messages call type: remap to Anthropic's custom tool schema.
r   )AnthropicConfig)r   r    *litellm.llms.anthropic.chat.transformationr#   
_map_toolsr
   r   dict)r!   r   openai_toolsr#   anthropic_tools_mcp_serverss         r   _build_retrieval_toolsr*   .   sW     	(./L"9-- K$3$5$@$@$N!OT
O,,r   contentc                 *   / nU /nU(       a  UR                  5       n[        U[        5      (       a  UR                  U5        O[        U[        5      (       a$  [        U5       H  nUR                  U5        M     O~[        U[        5      (       ai  UR                  S5      nUS:X  a+  UR                  [        UR                  SS5      5      5        O'US:X  a!  UR                  UR                  SS5      5        U(       a  M  SR                  U5      $ )ak  
Convert OpenAI/Anthropic message content blocks to plain text.

Text extraction policy:
- Include text-bearing fields only (`text` blocks + string values).
- For `tool_result`, expand into nested `content` items.
- Ignore non-textual blocks (images/documents/tool metadata/thinking metadata).

Implemented iteratively (stack-based) to avoid unbounded recursion.
typetext tool_resultr+    )	popr   strappendlistreversedr&   getjoin)r+   partsstackitemelement	item_types         r   _content_to_textr>   D   s     EyE
yy{dC  LLd###D>W% *d##(IF"S&"!567m+TXXi45 % 88E?r   messagesc                    U[         ;  a   [        SU< S[        [         5       S35      eU  Vs/ s H  n[        U5      PM     nn/ nU H3  nUR	                  0 UES[        UR                  SS5      5      0E5        M5     XC4$ s  snf )z
Normalize each original message to a text-surrogate content for scoring.

Returns:
    (normalized_messages, original_messages_copy)
zUnsupported call_type=z# for compression. Expected one of: .r+   r/   )_SUPPORTED_CALL_TYPES
ValueErrorsortedr&   r4   r>   r7   )r?   r   moriginal_messagesnormalized_messagesmsgs         r   #_normalize_messages_for_compressionrI   b   s     --$YM 2  &'< =>aA
 	

 AI.I1tAw.I&( ""+CGGIr,BC	
 ! 11 /Js   Bc                     [        U 5       H5  nUR                  S5      S:X  d  M  [        UR                  SS5      5      s  $    g)z1Return the text content of the last user message.roleuserr+   r/   )r6   r7   r>   )r?   rH   s     r   _extract_last_user_messagerM      s<    !776?f$#CGGIr$:;; " r   c                 *   [        U [        5      (       d  / $ / nU  Hs  n[        U[        5      (       d  M  UR                  S5      S:w  a  M1  UR                  S5      n[        U[        5      (       d  MY  U(       d  Mb  UR                  U5        Mu     U$ )Nr-   tool_useid)r   r5   r&   r7   r3   r4   )r+   tool_use_idsparttool_use_ids       r   _extract_tool_use_idsrT      s{    gt$$	 L$%%88Fz)hhtnk3''KK,  r   c                 J   [        U [        5      (       d
  [        5       $ [        5       nU  Hs  n[        U[        5      (       d  M  UR	                  S5      S:w  a  M1  UR	                  S5      n[        U[
        5      (       d  MY  U(       d  Mb  UR                  U5        Mu     U$ )Nr-   r0   rS   )r   r5   setr&   r7   r3   add)r+   tool_result_idsrR   rS   s       r   _extract_tool_result_idsrY      s    gt$$u #O$%%88F},hh}-k3''KK,  r   c                    / nSnU[        U 5      :  a  X   nUR                  S5      S:w  a  US-  nM/  [        UR                  S5      5      nU(       d  US-  nMW  US-   [        U 5      :  a  / S4$ XS-      nUR                  S5      S:w  a  / S4$ [        UR                  S5      5      nU(       d  / S4$ U H  nXv;  d  M
  / S4s  $    UR	                  X"S-   15        US-  nU[        U 5      :  a  M  US	4$ )
z
Return atomic 2-message spans for Anthropic tool exchanges.

Each assistant message containing `tool_use` must be immediately followed by a
user message containing matching `tool_result` blocks for all tool_use ids.
r   rK   	assistant   r+   invalid_anthropic_tool_sequencerL      N)lenr7   rT   rY   r4   )r?   spansicurrentrQ   next_msgrX   rS   s           r   &_extract_anthropic_tool_exchange_spansrd      s    E	A
c(m
+;;v+-FA,W[[-CDFAq5CM!888E?<<6)88828<<	3JK888'K1<<< ( 	aQZ 	Q7 c(m
: $;r   c                    / nSnSn[        U 5       HD  u  pEUR                  SS5      nUS:X  a  UR                  U5        M0  US:X  a  UnM:  US:X  d  MB  UnMF     Ub  UR                  U5        Ub  UR                  U5        U$ )z
Return indices of messages that must never be compressed:
- All system messages
- The last user message
- The last assistant message
NrK   r/   systemrL   r[   )	enumerater7   r4   )r?   	protectedlast_user_idxlast_assistant_idxra   rH   rK   s          r   _get_protected_indicesrk      s     IMH%wwvr"8QV^M[ !" &  '%+,r   bm25_scores
emb_scoresbm25_weightc                     S[         [           S[         [           4S jnU" U 5      nU" U5      nSU-
  n[        XE5       VVs/ s H  u  pxX'-  Xh-  -   PM     snn$ s  snnf )zJWeighted average of BM25 and embedding scores, with min-max normalization.scoresr   c                     U (       a  [        U 5      OSnU (       a  [        U 5      OSnX!-
  nUS:X  a  S/[        U 5      -  $ U  Vs/ s H
  oDU-
  U-  PM     sn$ s  snf )N        r   )minmaxr_   )rp   min_smax_srngss        r   
_normalize#_combine_scores.<locals>._normalize   sZ    %F3%F3m!853v;&&+126aUc!6222s   Ag      ?)r   floatzip)	rl   rm   rn   ry   	norm_bm25norm_emb
emb_weightbes	            r   _combine_scoresr      sg    34; 34; 3 ;'I*%H{"J9<Y9QR9QKOjn,9QRRRs   ArG   rF   combined_scorescompression_targetmodelinitial_kept_indicestool_exchange_spansc                 v  ^^ [        U5      mSnT H9  nU[        U[        [        X   R	                  SS5      =(       d    S5      S9-  nM;     0 n	0 n
[        U5       H  u  pU H  nXU'   M	     M     / n[        [        U 5      5       H(  nX;   d  UT;   a  M  UR                  TU   U4S45        M*     U H\  n[        [        U5      5      n[        U4S jU 5       5      (       a  M3  [        U4S jU 5       5      nUR                  UUS45        M^     UR                  S	 SS
9  U GH  u  nnn[        U4S jU 5       5      (       a  M$  SnU H9  nU[        U[        [        X   R	                  SS5      =(       d    S5      S9-  nM;     X7-
  nUS::  a    TU	4$ UU-   U::  a  TR                  U5        UU-  nM  U(       d  M  [        U5      S:X  d  M  US:  d  M  US   n[        X   U5      n[        UUR	                  SS5      =(       d    SS9nUX'   TR!                  U5        UU-  nGM
     TU	4$ )Nr   r+   r/   )r   r.   Tc              3   ,   >#    U  H	  oT;   v   M     g 7fr    .0idxkept_indicess     r   	<genexpr>2_select_kept_indices_for_budget.<locals>.<genexpr>(  s     ;lsl"l   c              3   .   >#    U  H
  nTU   v   M     g 7fr   r   )r   r   r   s     r   r   r   *  s     F#-s   Fc                     U S   $ )Nr   r   )r;   s    r   <lambda>1_select_kept_indices_for_budget.<locals>.<lambda>.  s    $q'r   )keyreversec              3   ,   >#    U  H	  oT;   v   M     g 7fr   r   r   s     r   r   r   1  s     6gsl"gr   r\   d   )rV   r   r
   r3   r7   rg   ranger_   r4   tuplerD   anyrt   sortupdater   rW   )rG   rF   r   r   r   r   r   current_tokensra   truncated_overridesspan_id_by_indexspan_idspanr   candidate_unitsspan_indices
span_score_scoreindicescan_truncate
msg_tokens	remaining	truncatedtruncated_tokensr   s     `                     @r   _select_kept_indices_for_budgetr     sm    +,LN-c.155iDJK
 	
  ,.')"#67C$+S!  8
 BDOS,-."c\&9 4sfdCD / $VD\*;l;;;FFF

L%@A $ 14@)8%6g666
C-#27;;IrJPbQ J 
 '7	>$ ,,,! J&*<<(j(N\c'la/I4D!*C():)?KI,]]9b17R  (1$S!..N9 *9< ,,,r   r   c                    ^  [        5       nU H0  n[        U 4S jU 5       5      (       a  M  UR                  U5        M2     U$ )Nc              3   ,   >#    U  H	  oT;   v   M     g 7fr   r   r   s     r   r   1_get_dropped_tool_span_indices.<locals>.<genexpr>V       7$3,&$r   )rV   r   r   )r   r   dropped_tool_span_indicesr   s   `   r   _get_dropped_tool_span_indicesr   Q  s>     +.%#7$777%,,T2 $ %$r   i@ Ncompression_triggerembedding_modelembedding_model_paramscompression_cachec           
      \  ^  [        U5      n[        U US9u  pUc  US-  S-  n[        U[        [        [
           U
5      S9nX::  a  [        U
UUS0 / SS9$ [        U	5      n[        X5      nU(       a  SS	K	J
n  U" UU	UUUS
9n[        XSS9nOUn[        U	5      n[        U5      m / n[        U5      (       aV  [        U
5      u  nnUb  [        U
UUS0 / US9$ U H0  n[!        U 4S jU 5       5      (       d  M  T R#                  U5        M2     [%        U	U
UUUT US9u  m n/ n0 n[        5       n['        T US9n[)        U
5       H  u  nnUU;   a  M  UT ;   a#  UR+                  UR-                  UU5      5        M7  [/        U	U   UUS9n[1        UR-                  SS5      5      nUUU'   UR+                  [3        UU5      5        M     [5        [7        UR9                  5       5      US9n[        U[        [        [
           U5      S9n[        UUUUS:  a  [;        SUU-  -
  S5      OSUUS9$ )u  
Compress a list of messages by replacing low-relevance content with stubs.

Messages below ``compression_trigger`` tokens pass through unchanged.
Messages above are scored with BM25 (and optionally embeddings), ranked,
and the lowest-relevance messages are replaced with stubs.  Originals are
cached and a retrieval tool is injected so the model can recover dropped
content on demand.

Parameters:
    messages: The conversation messages to (potentially) compress.
    model: The LLM model name — used for token counting.
    call_type: The LiteLLM call type whose message schema these messages
        follow.  Supported values:
        - ``CallTypes.completion`` / ``CallTypes.acompletion`` — OpenAI
          chat-completions shape (default)
        - ``CallTypes.anthropic_messages`` — Anthropic Messages shape
          (structured content blocks + atomic tool exchanges)
    compression_trigger: Only compress if input exceeds this token count.
    compression_target: Target token count after compression.
        Defaults to ``compression_trigger // 2``.
    embedding_model: If provided, use BM25 + embeddings for scoring.
        If ``None``, BM25 only.
    embedding_model_params: Optional kwargs forwarded to
        ``litellm.embedding()`` when ``embedding_model`` is set.
    compression_cache: Passed through to ``litellm.embedding()`` for
        cross-turn caching of embedding vectors.

Returns:
    A ``CompressedResult`` dict containing compressed messages, token
    counts, a cache of original content, and the retrieval tool definition.
)r?   r      
   )r   r?   rr   below_trigger)r?   original_tokenscompressed_tokenscompression_ratiocachetoolscompression_skipped_reasonr   )embedding_score_messages)r   r   r   皙?)rn   c              3   ,   >#    U  H	  oT;   v   M     g 7fr   r   r   s     r   r   compress.<locals>.<genexpr>  r   r   )rG   rF   r   r   r   r   r   )r   r   )fallback_index	used_keysr+   r/   r   r\      )r?   r   r   r   r   r   )r   rI   r   r
   r   r   r   rM   r   ,litellm.compression.scoring.embedding_scorerr   r   rk   rV   r    rd   r   r   r   r   rg   r4   r7   r   r>   r   r*   r5   r!   round)!r?   r   r   r   r   r   r   r   call_type_strrG   rF   r   queryrl   r   rm   r   protected_indicesr   tool_sequence_errorr   r   compressed_messagesr   r   r   ra   rH   r   r+   r   r   r   s!                                   @r   compressr   [  s   T )3M-P.*
 !014:#d3i!23O -&+-!'6
 	
 '':;E &eAK	
 .!##9

 *+sS% //BC !23L*,}--23DE 	10 *#* /"1"%+>  (D7$777##D) (
 )H/+'-)/)%L% ')E%I >!7J! -.3))&&':'>'>q#'FG#A&qIC 'swwy"'=>G E#J&&|C'=> / #4

#5OE%d3i!45
 $'+ " !(?:;Q? r   )r   )4__doc__typingr   r   r   r   r   r   r	   r
   litellm.caching.dual_cacher   $litellm.compression.message_stubbingr   r   r   "litellm.compression.retrieval_toolr    litellm.compression.scoring.bm25r   (litellm.litellm_core_utils.token_counterr   litellm.types.compressionr   litellm.types.utilsr   	frozensetanthropic_messagesr   r   
completionacompletionrB   r3   r   boolr    r&   r*   r>   rI   rM   rT   rY   intrd   rk   r{   r   r   r   r   r   r   r   <module>r      sU  
 F E E 0 
 D @ B 6 ) "9#?#?#E#E"FG  """##$$** E)S.$9 c .s .t .-c -s -tDz -,c c <24j22 4:tDz!"2:d  3 49 c c#h (4j(
4C>8C=()(VT$Z DI @ SeSUS S 
%[	S,K-dK-DzK- %[K- 	K-
 K- c(K- c#hK- 3s8T#t)_$%K-\%c(%15c#h%X% (1';';&(,%)7;-1f4jff Y^$f 	f
 !f c]f %T#s(^4f  	*f fr   