Ë
    uPêjg  ã                   ó„   — d Z ddlZddlZddlmZ ddlmZ dedee   fd„Z	de
defd	„Z	 	 dd
edee
   dededee   f
d„Zy)ua   
Pure Python BM25 (Okapi BM25) relevance scorer.

No external dependencies â€” uses only stdlib.
é    N)ÚCounter)ÚFinalÚtextÚreturnc                 óJ   — t        j                  d| j                  «       «      S )z4Split text into lowercase tokens on word boundaries.z
[a-z0-9_]+)ÚreÚfindallÚlower)r   s    úe/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/compression/scoring/bm25.pyÚ	_tokenizer      s   € ä�:‰:�m T§Z¡Z£\Ó2Ð2ó    Úmessagec                 óp  — | j                  dd«      }t        |t        «      r|S t        |t        «      r‚g }|D ]j  }t        |t        «      r6|j                  d«      dk(  r"|j                  |j                  dd«      «       ŒIt        |t        «      sŒZ|j                  |«       Œl dj                  |«      S y)z)Extract text content from a message dict.ÚcontentÚ Útyper   ú )ÚgetÚ
isinstanceÚstrÚlistÚdictÚappendÚjoin)r   r   ÚpartsÚparts       r   Ú_extract_contentr      s™   € à—[‘[ ¨BÓ/€GÜ�'œ3ÔØˆÜ�'œ4Ô ØˆØò 	#ˆDÜ˜$¤Ô%¨$¯(©(°6Ó*:¸fÒ*DØ—‘˜TŸX™X f¨bÓ1Õ2Ü˜D¤#Õ&Ø—‘˜TÕ"ð		#ð
 �x‰x˜‹ÐØr   ÚqueryÚmessagesÚk1Úbc                 óh  — t        | «      }|sdgt        |«      z  S g }|D ]%  }|j                  t        t        |«      «      «       Œ' t        |«      }|dk(  rg S |D �cg c]  }t        |«      ‘Œ }	}|dkD  rt	        |	«      |z  nd}
i }|D ],  }t        |«      }|D ]  }|j                  |d«      dz   ||<   Œ Œ. i }t        |«      D ];  }|j                  |d«      }t        j                  ||z
  dz   |dz   z  dz   «      ||<   Œ= dt        dt        dt        fd	„}g }t        |«      D ]�  \  }}|s|j                  d«       Œt        |«      }|	|   }d}|D ]@  }||vrŒ |||«      }|dk(  rŒ||dz   z  }||d|z
  ||z  |
z  z   z  z   }|||   |z  |z  z  }ŒB |j                  |«       Œƒ |S c c}w )
a¥  
    Score each message's relevance to the query using BM25 (Okapi BM25).

    Parameters:
        query: The reference text to score against (typically the last user message).
        messages: List of message dicts with "content" fields.
        k1: Term frequency saturation parameter.
        b: Length normalization parameter.

    Returns:
        List of float scores, one per message. Higher = more relevant.
    g        r   g      ð?é   g      à?Ú
query_termÚ	tf_countsr   c                 ó’   ‡ — |j                  ‰ d«      }|r|S t        ‰ «      dk  ryt        ˆ fd„|j                  «       D «       «      S )z=Sum TF across all doc tokens that are prefixed by query_term.r   é   c              3   óX   •K  — | ]!  \  }}|‰k7  sŒ|j                  ‰«      sŒ|–— Œ# y ­w)N)Ú
startswith)Ú.0ÚtokenÚcountr$   s      €r   ú	<genexpr>z:bm25_score_messages.<locals>._expand_tf.<locals>.<genexpr>^   s+   øè ø€ Òw™\˜U EÀ%È:ÓBUÐZ_×ZjÑZjÐkuÕZv”5Ñwùs   ƒ*‘*£*)r   ÚlenÚsumÚitems)r$   r%   Úexacts   `  r   Ú
_expand_tfz'bm25_score_messages.<locals>._expand_tfW   sB   ø€ à —}‘} Z°Ó3ˆÙØˆLÜˆz‹?˜QÒØÜÓw¨Y¯_©_Ó->ÔwÓwÐwr   )r   r.   r   r   r/   Úsetr   ÚmathÚlogr   r   ÚintÚ	enumerate)r   r   r    r!   Úquery_termsÚ
doc_tokensÚmsgÚnÚdtÚdoc_lengthsÚavgdlÚdfÚseenÚtermÚidfÚterm_dfr2   ÚscoresÚir%   ÚdlÚscoreÚtfÚ	numeratorÚdenominators                            r   Úbm25_score_messagesrK   "   s(  € ô$ # 5Ó)€KÙØˆu”s˜8“}Ñ$Ð$ð *,€JØò <ˆØ×Ñœ)Ô$4°SÓ$9Ó:Õ;ð<ô �:‹€AØˆA‚vØˆ	ð -7Ö7 bœ#˜b�'Ð7€KÐ7Ø+,¨qª5”3�{Ó# aÒ'°c€Eð !#€BØò +ˆÜ�2‹wˆØò 	+ˆDØ—v‘v˜d A“¨Ñ*ˆBˆtŠHñ	+ð+ð $&€CÜ�KÓ ò JˆØ—&‘&˜˜q“/ˆä—H‘H˜a '™k¨CÑ/°G¸c±MÑBÀSÑHÓIˆˆDŠ	ðJðxœsð x¬wð x¼3ó xð "$€FÜ˜:Ó&ò ‰ˆˆ2ÙØ�M‰M˜#ÔØä˜B“Kˆ	Ø˜‰^ˆØˆàò 	9ˆDØ˜3‰ØÙ˜D )Ó,ˆBØ�QŠwØØ˜b 1™f™ˆIØ˜r Q¨¡U¨Q°©V°e©^Ñ%;Ñ<Ñ<ˆKØ�S˜‘Y Ñ*¨[Ñ8Ñ8‰Eð	9ð 	�‰�eÕð'ð* €Mùòk 8s   ÁF/)g      ø?g      è?)Ú__doc__r4   r   Úcollectionsr   Útypingr   r   r   r   r   r   ÚfloatrK   © r   r   ú<module>rQ      s‹   ðñó Û 	Ý Ý ð3�Cð 3˜D ™Ió 3ð
˜dð  só ð& Øñ	UØðUà�4‰jðUð 	ðUð ð	Uð
 
ˆ%�[ôUr   