
    KKio*                     &   S r SSKrSSKJr  SSK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Jr  SSKJr  SS	KJrJr  SS
KJr  SSKJrJr  SSKJrJr  SSKJ r   SSK!J"r"  \" S5      r#\" S\S9r$S\\#   S\\#/\$4   S\\#   4S jr% " S S\5      r&g)zEnsemble Retriever.

Ensemble retriever that ensemble the results of
multiple retrievers by using weighted  Reciprocal Rank Fusion.
    N)defaultdict)CallableHashableIterableIterator)chain)AnyTypeVarcast)#AsyncCallbackManagerForRetrieverRunCallbackManagerForRetrieverRun)Document)BaseRetrieverRetrieverLike)RunnableConfig)ensure_configpatch_config)ConfigurableFieldSpecget_unique_config_specs)model_validator)overrideTH)bounditerablekeyreturnc              #   z   #    [        5       nU  H'  nU" U5      =oB;  d  M  UR                  U5        Uv   M)     g7f)zYield unique elements of an iterable based on a key function.

Args:
    iterable: The iterable to filter.
    key: A function that returns a hashable key for each element.

Yields:
    Unique elements of the iterable based on the key function.
N)setadd)r   r   seeneks        g/var/www/html/dynamic-report/venv/lib/python3.13/site-packages/langchain_classic/retrievers/ensemble.pyunique_by_keyr%   $   s6      5DQKA$HHQKG s   ;;c                      \ rS rSr% Sr\\   \S'   \\   \S'   Sr	\
\S'   Sr\S-  \S'   \S	\\   4S
 j5       r\" SS9\S\\\4   S	\4S j5       5       r\ SS\S\S-  S\S	\\   4S jj5       r\ SS\S\S-  S\S	\\   4S jj5       rS\S\S	\\   4S jrS\S\S	\\   4S jrSS.S\S\S\S-  S	\\   4S jjrSS.S\S\S\S-  S	\\   4S jjrS\\\      S	\\   4S jr Sr!g)EnsembleRetriever5   a"  Retriever that ensembles the multiple retrievers.

It uses a rank fusion.

Args:
    retrievers: A list of retrievers to ensemble.
    weights: A list of weights corresponding to the retrievers. Defaults to equal
        weighting for all retrievers.
    c: A constant added to the rank, controlling the balance between the importance
        of high-ranked items and the consideration given to lower-ranked items.
    id_key: The key in the document's metadata used to determine unique documents.
        If not specified, page_content is used.

retrieversweights<   cNid_keyr   c                 :    [        S U R                   5       5      $ )z+List configurable fields for this runnable.c              3   J   #    U  H  oR                     H  o"v   M     M     g 7fN)config_specs).0	retrieverspecs      r$   	<genexpr>1EnsembleRetriever.config_specs.<locals>.<genexpr>L   s       '
"1Y>T>TdD>TD/s   !#)r   r)   )selfs    r$   r1   EnsembleRetriever.config_specsI   s"     ' '
"&//'
 
 	
    before)modevaluesc                 f    UR                  S5      (       d  [        US   5      nSU-  /U-  US'   U$ )Nr*   r)      )getlen)clsr<   n_retrieverss      r$   _set_weightsEnsembleRetriever._set_weightsP   s>     zz)$$vl34L!"\!1 2\ AF9r9   inputconfigkwargsc                     SSK Jn  [        U5      nUR                  UR	                  S5      S UR	                  SS5      UR	                  S/ 5      U R
                  UR	                  S0 5      U R                  S9nUR                  " S U4S	UR	                  S
5      =(       d    U R                  5       0UD6n U R                  XUS9nUR                  " U40 UD6  U$ ! [         a  nUR                  U5        e S nAff = f)Nr   )CallbackManager	callbacksverboseFtagsmetadatarK   inheritable_tags
local_tagsinheritable_metadatalocal_metadatanamerun_namerun_managerrF   )langchain_core.callbacksrI   r   	configurer?   rL   rM   on_retriever_startget_namerank_fusionon_retriever_end	Exceptionon_retriever_error)	r7   rE   rF   rG   rI   callback_managerrV   resultr"   s	            r$   invokeEnsembleRetriever.invokeX   s    	=v&*44JJ{#JJy%0#ZZ3yy!'J!;== 5 
 '99
 J':4==?
 	

	%%eV%TF
 (( M  	**1-	s   7C 
C=&C88C=c                 X  #    SSK Jn  [        U5      nUR                  UR	                  S5      S UR	                  SS5      UR	                  S/ 5      U R
                  UR	                  S0 5      U R                  S9nUR                  " S U4S	UR	                  S
5      =(       d    U R                  5       0UD6I S h  vN n U R                  UUUS9I S h  vN nUR                  " U40 UD6I S h  vN   U$  N; N# N
! [         a   nUR                  U5      I S h  vN    e S nAff = f7f)Nr   )AsyncCallbackManagerrJ   rK   FrL   rM   rN   rS   rT   rU   )rW   rd   r   rX   r?   rL   rM   rY   rZ   arank_fusionr\   r]   r^   )	r7   rE   rF   rG   rd   r_   rV   r`   r"   s	            r$   ainvokeEnsembleRetriever.ainvoke}   sB     	Bv&/99JJ{#JJy%0#ZZ3yy!'J!;== : 
 -??
 J':4==?
 	
 
	,,' -  F ..   M)
	  	00333	sf   B9D*;C7<D*C= C9C= D*0C;1D*9C= ;D*=
D'D"DD""D''D*queryrV   c                $    U R                  X5      $ )zGet the relevant documents for a given query.

Args:
    query: The query to search for.
    run_manager: The callback handler to use.

Returns:
    A list of reranked documents.
)r[   r7   rh   rV   s      r$   _get_relevant_documents)EnsembleRetriever._get_relevant_documents   s      33r9   c                @   #    U R                  X5      I Sh  vN $  N7f)zAsynchronously get the relevant documents for a given query.

Args:
    query: The query to search for.
    run_manager: The callback handler to use.

Returns:
    A list of reranked documents.
N)re   rj   s      r$   _aget_relevant_documents*EnsembleRetriever._aget_relevant_documents   s       &&u::::s   )rF   c                   [        U R                  5       VVs/ s H2  u  pEUR                  U[        UUR	                  SUS-    3S9S95      PM4     nnn[        [        U5      5       HB  nXd    Vs/ s H-  n[        U[        5      (       a  [        [        SU5      S9OUPM/     snXd'   MD     U R                  U5      $ s  snnf s  snf )a#  Rank fusion.

Retrieve the results of the retrievers and use rank_fusion_func to get
the final result.

Args:
    query: The query to search for.
    run_manager: The callback handler to use.
    config: Optional configuration for the retrievers.

Returns:
    A list of reranked documents.

retriever_r>   tagrJ   strpage_content)	enumerater)   ra   r   	get_childranger@   
isinstanceru   r   r   weighted_reciprocal_rankr7   rh   rV   rF   ir3   retriever_docsdocs           r$   r[   EnsembleRetriever.rank_fusion   s    : !*$// :	
 !; )33*QUG8L3M !; 	 	
 s>*+A *,!,C <Fc3;O;Od5#&67UXX,!N , ,,^<<'	
!s   9C 24Cc                  #    [         R                  " [        U R                  5       VVs/ s H2  u  pEUR	                  U[        UUR                  SUS-    3S9S95      PM4     snn6 I Sh  vN n[        [        U5      5       H8  nXd    Vs/ s H#  n[        U[        5      (       d	  [        US9OUPM%     snXd'   M:     U R                  U5      $ s  snnf  Nks  snf 7f)a2  Rank fusion.

Asynchronously retrieve the results of the retrievers
and use rank_fusion_func to get the final result.

Args:
    query: The query to search for.
    run_manager: The callback handler to use.
    config: Optional configuration for the retrievers.

Returns:
    A list of reranked documents.
rq   r>   rr   rt   Nrv   )asynciogatherrx   r)   rf   r   ry   rz   r@   r{   r   r|   r}   s           r$   re   EnsembleRetriever.arank_fusion   s     *  '~~ %.doo$>	 %?LA !! "-"7"7jQ<P"7"Q %?	 
 
 s>*+A *,!,C 3=S(2K2Kc*QTT,!N , ,,^<<)	
!s.   )C9C
$C,C-!C*C8!CC	doc_listsc                   ^ ^ [        U5      [        T R                  5      :w  a  Sn[        U5      e[        [        5      m[        UT R                  SS9 Hd  u  p4[        USS9 HQ  u  pVTT R                  c  UR                  OUR                  T R                     ==   XET R                  -   -  -  ss'   MS     Mf     [        R                  " U5      n[        [        UU 4S j5      SUU 4S jS	9$ )
al  Perform weighted Reciprocal Rank Fusion on multiple rank lists.

You can find more details about RRF here:
https://plg.uwaterloo.ca/~gvcormac/cormacksigir09-rrf.pdf.

Args:
    doc_lists: A list of rank lists, where each rank list contains unique items.

Returns:
    The final aggregated list of items sorted by their weighted RRF
    scores in descending order.
z<Number of rank lists must be equal to the number of weights.F)strictr>   )startc                 h   > TR                   c  U R                  $ U R                  TR                      $ r0   r-   rw   rM   )r   r7   s    r$   <lambda><EnsembleRetriever.weighted_reciprocal_rank.<locals>.<lambda>F  s2    {{* $$ 3dkk23r9   Tc                 r   > TTR                   c  U R                     $ U R                  TR                         $ r0   r   )r   	rrf_scorer7   s    r$   r   r   M  s1    I$(KK$7  =@\\$++=Vr9   )reverser   )r@   r*   
ValueErrorr   floatziprx   r-   rw   rM   r,   r   from_iterablesortedr%   )	r7   r   msgdoc_listweightrankr   all_docsr   s	   `       @r$   r|   *EnsembleRetriever.weighted_reciprocal_rank   s      y>S..PCS/! '2%&8	 #It||E JH&xq9	  ;;. (( \\$++6	 dff}-.  : !K &&y1 
 	
r9    r0   )"__name__
__module____qualname____firstlineno____doc__listr   __annotations__r   r,   intr-   ru   propertyr   r1   r   classmethoddictr	   rC   r   r   r   ra   rf   r   rk   r   rn   r[   re   r|   __static_attributes__r   r9   r$   r'   r'   5   s    ]##%[AsKFC$J
d#89 
 
 (#$sCx. S   $  )-"" %" 	"
 
h" "H  )-&& %& 	&
 
h& &P44 4	4
 
h4$;; 9	;
 
h;. )-(=(= 4(=
 %(= 
h(=^ )-*=*= 9*=
 %*= 
h*=X0
X'0
 
h0
r9   r'   )'r   r   collectionsr   collections.abcr   r   r   r   	itertoolsr   typingr	   r
   r   rW   r   r   langchain_core.documentsr   langchain_core.retrieversr   r   langchain_core.runnablesr   langchain_core.runnables.configr   r   langchain_core.runnables.utilsr   r   pydanticr   typing_extensionsr   r   r   r%   r'   r   r9   r$   <module>r      s     # B B   . B 3 G % &CLCx HQK hsAv.> 8A; "[
 [
r9   