
    Ng&                     N   d dl Z d dlZd dlmZmZ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j        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 dS )    N)ListOptionalSequence)#AsyncCallbackManagerForRetrieverRunCallbackManagerForRetrieverRun)Document)BaseLanguageModel)BaseOutputParser)BasePromptTemplate)PromptTemplate)BaseRetriever)Runnable)LLMChainc                   .    e Zd ZdZdedee         fdZdS )LineListOutputParserz"Output parser for a list of lines.textreturnc                     |                                                     d          }t          t          d |                    S )N
)stripsplitlistfilter)selfr   liness      \/var/www/html/ai-engine/env/lib/python3.11/site-packages/langchain/retrievers/multi_query.pyparsezLineListOutputParser.parse   s5    

""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                 :      fdt                     D             S )Nc                 2    g | ]\  }}|d |         v|S )Nr$   ).0idocr(   s      r   
<listcomp>z%_unique_documents.<locals>.<listcomp>,   s/    OOOFAsc2A26N6NC6N6N6Nr   )	enumerate)r(   s   `r   _unique_documentsr0   +   s%    OOOOi	22OOOOr   c                      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d
S )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                 J    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
        )r3   r4   r7   )r   )clsr3   r8   r9   r6   r7   output_parserr4   s           r   from_llmzMultiQueryRetriever.from_llm=   s?    , -..SL=0	s-
 
 
 	
r   queryrun_managerc                   K   |                      ||           d{V }| j        r|                    |           |                     ||           d{V }|                     |          S )Get relevant documents given a user query.

        Args:
            query: user query

        Returns:
            Unique union of relevant documents from all generated queries
        N)agenerate_queriesr7   appendaretrieve_documentsunique_unionr   r>   r?   queriesr(   s        r   _aget_relevant_documentsz,MultiQueryRetriever._aget_relevant_documents[   s       ..ukBBBBBBBB  	"NN5!!!227KHHHHHHHH	  +++r   r%   c                   K   | j                             d|id|                                i           d{V }t          | j         t                    r	|d         }n|}| j        rt                              d|            |S )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: )r4   ainvoke	get_child
isinstancer   r5   loggerinfor   r%   r?   responser   s        r   rB   z%MultiQueryRetriever.agenerate_querieso   s       //"K9N9N9P9P+Q 0 
 
 
 
 
 
 
 
 dnh// 	V$EEE< 	7KK5e55666r   rG   c                 d    K   t          j         fd|D               d{V }d |D             S )Run all LLM generated queries.

        Args:
            queries: query list

        Returns:
            List of retrieved Documents
        c              3   x   K   | ]4}j                             |d                                 i          V  5dS )rK   rL   N)r3   rO   rP   )r+   r>   r?   r   s     r   	<genexpr>z:MultiQueryRetriever.aretrieve_documents.<locals>.<genexpr>   sf          &&;0E0E0G0G"H '       r   Nc                     g | ]	}|D ]}|
S r$   r$   )r+   docsr-   s      r   r.   z;MultiQueryRetriever.aretrieve_documents.<locals>.<listcomp>   s%    ???$??3????r   )asynciogather)r   rG   r?   document_listss   ` ` r   rD   z'MultiQueryRetriever.aretrieve_documents   sx        '~     %	   
 
 
 
 
 
 
 @?????r   c                    |                      ||          }| j        r|                    |           |                     ||          }|                     |          S )rA   )generate_queriesr7   rC   retrieve_documentsrE   rF   s        r   _get_relevant_documentsz+MultiQueryRetriever._get_relevant_documents   s_     ''{;;  	"NN5!!!++G[AA	  +++r   c                     | j                             d|id|                                i          }t          | j         t                    r	|d         }n|}| j        rt                              d|            |S )rJ   r%   rK   rL   r   rN   )r4   invokerP   rQ   r   r5   rR   rS   rT   s        r   r`   z$MultiQueryRetriever.generate_queries   s     >(("K9N9N9P9P+Q ) 
 
 dnh// 	V$EEE< 	7KK5e55666r   c                     g }|D ]G}| j                             |d|                                i          }|                    |           H|S )rW   rK   rL   )r3   rd   rP   extend)r   rG   r?   r(   r>   r[   s         r   ra   z&MultiQueryRetriever.retrieve_documents   si     	 	# 	#E>(({K,A,A,C,CD )  D T""""r   r(   c                      t          |          S )zGet unique Documents.

        Args:
            documents: List of retrieved Documents

        Returns:
            List of unique retrieved Documents
        )r0   )r   r(   s     r   rE   z MultiQueryRetriever.unique_union   s     !+++r   )r   r    r!   r"   r   __annotations__r   r5   boolr6   r#   r7   classmethodDEFAULT_QUERY_PROMPTr	   r   r   r=   r   r   r   rH   rB   rD   r   rb   r`   ra   rE   r$   r   r   r2   r2   /   s>         
 GTJO"d"""Q
 &:$(!&
 
 
 
 #	

 SM
 
 

 
 
 [
:,, 9	,
 
h, , , ,(*M	c   ,@Cy@/R@	h@ @ @ @*,, 4	,
 
h, , , ,(*H	c   ,Cy/M	h   &	,d8n 	,h 	, 	, 	, 	, 	, 	,r   r2   )!r\   loggingtypingr   r   r   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   rR   r#   r   rk   r0   r2   r$   r   r   <module>rx      s     + + + + + + + + + +        . - - - - - < < < < < < : : : : : : 5 5 5 5 5 5 8 8 8 8 8 8 3 3 3 3 3 3 - - - - - - ) ) ) ) ) )		8	$	$) ) ) ) )+DI6 ) ) ) &~LF	 	 	 P(!3 PX P P P Pq, q, q, q, q,- q, q, q, q, q,r   