
    h                     *   d dl Z d dlZd dlmZ d dlmZ d dlmZmZ d dl	m
Z
 d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ  ej2                  e      Z G d deee            Z edgd      Zdee
   dee
   fdZ  G d de      Z!y)    N)Sequence)Optional)#AsyncCallbackManagerForRetrieverRunCallbackManagerForRetrieverRun)Document)BaseLanguageModel)BaseOutputParser)BasePromptTemplate)PromptTemplate)BaseRetriever)Runnable)LLMChainc                   &    e Zd ZdZdedee   fdZy)LineListOutputParserz"Output parser for a list of lines.textreturnc                 j    |j                         j                  d      }t        t        d |            S )N
)stripsplitlistfilter)selfr   liness      ^/var/www/html/eduruby.in/venv/lib/python3.12/site-packages/langchain/retrievers/multi_query.pyparsezLineListOutputParser.parse   s*    

""4(F4'((    N)__name__
__module____qualname____doc__strr   r    r   r   r   r      s    ,)# )$s) )r   r   questiona  You are an AI language model assistant. Your task is
    to generate 3 different versions of the given user
    question to retrieve relevant documents from a vector  database.
    By generating multiple perspectives on the user question,
    your goal is to help the user overcome some of the limitations
    of distance-based similarity search. Provide these alternative
    questions separated by newlines. Original question: {question})input_variablestemplate	documentsr   c                 Z    t        |       D cg c]  \  }}|| d | vs| c}}S c c}}w )N)	enumerate)r'   idocs      r   _unique_documentsr,   ,   s,    '	2OFAsc2A6NCOOOs   ''c                   P   e Zd ZU dZeed<   eed<   dZeed<   dZ	e
ed<   	 dZeed	<   	 eed
dfdedededee
   d	edd fd       Zde
dedee   fdZde
dedee
   fdZdee
   dedee   fdZde
dedee   fdZde
dedee
   fdZdee
   dedee   fdZdee   dee   fdZy
)MultiQueryRetrieverzGiven a query, use an LLM to write a set of queries.

    Retrieve docs for each query. Return the unique union of all retrieved docs.
    	retriever	llm_chainTverboser   
parser_keyFinclude_originalNllmpromptr   c                 <    t               }||z  |z  } | |||      S )a  Initialize from llm using default template.

        Args:
            retriever: retriever to query documents from
            llm: llm for query generation using DEFAULT_QUERY_PROMPT
            prompt: The prompt which aims to generate several different versions
                of the given user query
            include_original: Whether to include the original query in the list of
                generated queries.

        Returns:
            MultiQueryRetriever
        )r/   r0   r3   )r   )clsr/   r4   r5   r2   r3   output_parserr0   s           r   from_llmzMultiQueryRetriever.from_llm>   s0    , -.SL=0	-
 	
r   queryrun_managerc                   K   | j                  ||       d{   }| j                  r|j                  |       | j                  ||       d{   }| j	                  |      S 7 L7 w)Get relevant documents given a user query.

        Args:
            query: user query

        Returns:
            Unique union of relevant documents from all generated queries
        N)agenerate_queriesr3   appendaretrieve_documentsunique_unionr   r:   r;   queriesr'   s        r   _aget_relevant_documentsz,MultiQueryRetriever._aget_relevant_documents\   se      ..ukBB  NN5!227KHH	  ++	 C Is!   A)A%6A)A'A)'A)r$   c                   K   | j                   j                  d|id|j                         i       d{   }t        | j                   t              r|d   n|}| j
                  rt        j                  d|       |S 7 Iw)Generate queries based upon user input.

        Args:
            question: user query

        Returns:
            List of LLM generated queries that are similar to the user input
        r$   	callbacksconfigNr   Generated queries: %s)r0   ainvoke	get_child
isinstancer   r1   loggerinfor   r$   r;   responser   s        r   r>   z%MultiQueryRetriever.agenerate_queriesp   sz      //"!6!6!89 0 
 
 %/t~~x$H h<<KK/7
s   3BA?A
BrC   c                     K   t        j                   fd|D          d{   }|D cg c]  }|D ]  }|  c}}S 7 c c}}w w)Run all LLM generated queries.

        Args:
            queries: query list

        Returns:
            List of retrieved Documents
        c              3   x   K   | ]1  }j                   j                  |d j                         i       3 yw)rG   rH   N)r/   rK   rL   ).0r:   r;   r   s     r   	<genexpr>z:MultiQueryRetriever.aretrieve_documents.<locals>.<genexpr>   sC      
 	 &&')>)>)@A ' s   7:N)asynciogather)r   rC   r;   document_listsdocsr+   s   ` `   r   r@   z'MultiQueryRetriever.aretrieve_documents   sU       '~~
 % 
 
 !/?$?3???
 @s    A
A	A
AA
A
c                    | j                  ||      }| j                  r|j                  |       | j                  ||      }| j	                  |      S )r=   )generate_queriesr3   r?   retrieve_documentsrA   rB   s        r   _get_relevant_documentsz+MultiQueryRetriever._get_relevant_documents   sN     ''{;  NN5!++G[A	  ++r   c                     | j                   j                  d|id|j                         i      }t        | j                   t              r|d   n|}| j
                  rt        j                  d|       |S )rF   r$   rG   rH   r   rJ   )r0   invokerL   rM   r   r1   rN   rO   rP   s        r   r\   z$MultiQueryRetriever.generate_queries   sl     >>(("!6!6!89 ) 
 %/t~~x$H h<<KK/7r   c                     g }|D ]@  }| j                   j                  |d|j                         i      }|j                  |       B |S )rS   rG   rH   )r/   r`   rL   extend)r   rC   r;   r'   r:   rZ   s         r   r]   z&MultiQueryRetriever.retrieve_documents   s]     	 	#E>>((#[%:%:%<= ) D T"	# r   r'   c                     t        |      S )zGet unique Documents.

        Args:
            documents: List of retrieved Documents

        Returns:
            List of unique retrieved Documents
        )r,   )r   r'   s     r   rA   z MultiQueryRetriever.unique_union   s     !++r   )r   r   r    r!   r   __annotations__r   r1   boolr2   r"   r3   classmethodDEFAULT_QUERY_PROMPTr   r
   r   r9   r   r   r   rD   r>   r@   r   r^   r\   r]   rA   r#   r   r   r.   r.   0   s   
 GTJO"d"Q
 &:$(!&
 
 
 #	

 SM
 
 

 
:,, 9	,
 
h,( 9 
c	,@c@ 9@ 
h	@0,, 4	,
 
h,( 4 
c	,c 4 
h	,	,d8n 	,h 	,r   r.   )"rW   loggingcollections.abcr   typingr   langchain_core.callbacksr   r   langchain_core.documentsr   langchain_core.language_modelsr   langchain_core.output_parsersr	   langchain_core.promptsr
   langchain_core.prompts.promptr   langchain_core.retrieversr   langchain_core.runnablesr   langchain.chains.llmr   	getLoggerr   rN   r   r"   r   rg   r,   r.   r#   r   r   <module>ru      s      $  . < : 5 8 3 - )			8	$)+DI6 ) &LF	 P(!3 PX Pw,- w,r   