
    9|h$                        d Z ddlmZ ddlmZmZmZmZ ddlm	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mZmZ dd
lmZ ddlmZ ddZ e	ddd       G d de             Zy)zLCombine documents by doing a first pass and then refining on more documents.    )annotations)AnyDictListTuple)
deprecated)	Callbacks)Document)BasePromptTemplateformat_documentPromptTemplate)
ConfigDictFieldmodel_validator)BaseCombineDocumentsChain)LLMChainc                     t        dgd      S )Npage_contentz{page_content})input_variablestemplater        h/var/www/html/test/engine/venv/lib/python3.12/site-packages/langchain/chains/combine_documents/refine.py_get_default_document_promptr      s    >*:EUVVr   z0.3.1z1.0zThis class is deprecated. Please see the migration guide here for a recommended replacement: https://python.langchain.com/docs/versions/migrating_chains/refine_docs_chain/)sinceremovalmessagec                  `    e Zd ZU dZded<   	 ded<   	 ded<   	 ded<   	  ee      Zd	ed
<   	 dZded<   	 e	d fd       Z
 edd      Z ed      edd              Z ed      edd              Z	 d	 	 	 	 	 	 	 ddZ	 d	 	 	 	 	 	 	 ddZd dZd!dZ	 	 	 	 	 	 d"dZe	d#d       Z xZS )$RefineDocumentsChaina&	  Combine documents by doing a first pass and then refining on more documents.

    This algorithm first calls `initial_llm_chain` on the first document, passing
    that first document in with the variable name `document_variable_name`, and
    produces a new variable with the variable name `initial_response_name`.

    Then, it loops over every remaining document. This is called the "refine" step.
    It calls `refine_llm_chain`,
    passing in that document with the variable name `document_variable_name`
    as well as the previous response with the variable name `initial_response_name`.

    Example:
        .. code-block:: python

            from langchain.chains import RefineDocumentsChain, LLMChain
            from langchain_core.prompts import PromptTemplate
            from langchain_community.llms import OpenAI

            # This controls how each document will be formatted. Specifically,
            # it will be passed to `format_document` - see that function for more
            # details.
            document_prompt = PromptTemplate(
                input_variables=["page_content"],
                 template="{page_content}"
            )
            document_variable_name = "context"
            llm = OpenAI()
            # The prompt here should take as an input variable the
            # `document_variable_name`
            prompt = PromptTemplate.from_template(
                "Summarize this content: {context}"
            )
            initial_llm_chain = LLMChain(llm=llm, prompt=prompt)
            initial_response_name = "prev_response"
            # The prompt here should take as an input variable the
            # `document_variable_name` as well as `initial_response_name`
            prompt_refine = PromptTemplate.from_template(
                "Here's your first summary: {prev_response}. "
                "Now add to it based on the following context: {context}"
            )
            refine_llm_chain = LLMChain(llm=llm, prompt=prompt_refine)
            chain = RefineDocumentsChain(
                initial_llm_chain=initial_llm_chain,
                refine_llm_chain=refine_llm_chain,
                document_prompt=document_prompt,
                document_variable_name=document_variable_name,
                initial_response_name=initial_response_name,
            )
    r   initial_llm_chainrefine_llm_chainstrdocument_variable_nameinitial_response_name)default_factoryr   document_promptFboolreturn_intermediate_stepsc                @    t         |   }| j                  r|dgz   }|S )z2Expect input key.

        :meta private:
        intermediate_steps)superoutput_keysr)   )self_output_keys	__class__s     r   r-   z RefineDocumentsChain.output_keysd   s,     w*))'+?*@@Lr   Tforbid)arbitrary_types_allowedextrabefore)modec                $    d|v r|d   |d<   |d= |S )zFor backwards compatibility.return_refine_stepsr)   r   )clsvaluess     r   get_return_intermediate_stepsz2RefineDocumentsChain.get_return_intermediate_stepst   s+     !F*289N2OF./,-r   c                    d|vrt        d      |d   j                  j                  }d|vr#t        |      dk(  r
|d   |d<   |S t        d      |d   |vrt        d|d    d|       |S )	z4Get default document variable name, if not provided.r!   z"initial_llm_chain must be providedr$      r   zWdocument_variable_name must be provided if there are multiple llm_chain input_variableszdocument_variable_name z- was not found in llm_chain input_variables: )
ValueErrorpromptr   len)r8   r9   llm_chain_variabless      r   "get_default_document_variable_namez7RefineDocumentsChain.get_default_document_variable_name}   s     f,ABB$%89@@PP#61&'1,3Fq3I/0  !9 
 ./7JJ -f5M.N-O P??R>SU  r   c                0    | j                   |fi |} | j                  j                  dd|i|}|g}|dd D ]I  }| j                  ||      }i ||} | j                  j                  dd|i|}|j                  |       K | j                  ||      S )a  Combine by mapping first chain over all, then stuffing into final chain.

        Args:
            docs: List of documents to combine
            callbacks: Callbacks to be passed through
            **kwargs: additional parameters to be passed to LLM calls (like other
                input variables besides the documents)

        Returns:
            The first element returned is the single string output. The second
            element returned is a dictionary of other keys to return.
        	callbacksr<   Nr   )_construct_initial_inputsr!   predict_construct_refine_inputsr"   append_construct_result	r.   docsrC   kwargsinputsresrefine_stepsdocbase_inputss	            r   combine_docsz!RefineDocumentsChain.combine_docs   s     0//??,d$$,,KyKFKu8 	%C77SAK..v.F/$''//N)NvNC$		%
 %%lC88r   c                `  K    | j                   |fi |} | j                  j                  dd|i| d{   }|g}|dd D ]Q  }| j                  ||      }i ||} | j                  j                  dd|i| d{   }|j                  |       S | j                  ||      S 7 r7 +w)a  Async combine by mapping a first chain over all, then stuffing
         into a final chain.

        Args:
            docs: List of documents to combine
            callbacks: Callbacks to be passed through
            **kwargs: additional parameters to be passed to LLM calls (like other
                input variables besides the documents)

        Returns:
            The first element returned is the single string output. The second
            element returned is a dictionary of other keys to return.
        rC   Nr<   r   )rD   r!   apredictrF   r"   rG   rH   rI   s	            r   acombine_docsz"RefineDocumentsChain.acombine_docs   s       0//??3D**33RiR6RRu8 	%C77SAK..v.F6--66UUfUUC$		%
 %%lC88 S
 Vs"   5B.B*AB. B,*B.,B.c                6    | j                   rd|i}||fS i }||fS )Nr+   )r)   )r.   rN   rM   extra_return_dicts       r   rH   z&RefineDocumentsChain._construct_result   s8    ))!5| D %%% !#%%%r   c                ^    | j                   t        || j                        | j                  |iS N)r$   r   r'   r%   )r.   rO   rM   s      r   rF   z-RefineDocumentsChain._construct_refine_inputs   s/    ''d>R>R)S&&
 	
r   c                   d|d   j                   i}|j                  |d   j                         | j                  j                  D ci c]  }|||   
 }}| j
                   | j                  j                  di |i}i ||}|S c c}w )Nr   r   r   )r   updatemetadatar'   r   r$   format)r.   rJ   rK   	base_infokdocument_inforP   rL   s           r   rD   z.RefineDocumentsChain._construct_initial_inputs   s     $T!W%9%9:	a))*262F2F2V2VWQIaLWW'')D)=)=)D)D)U})U
 +K*6* Xs   Bc                     y)Nrefine_documents_chainr   )r.   s    r   _chain_typez RefineDocumentsChain._chain_type   s    'r   )return	List[str])r9   r   rc   r   rX   )rJ   List[Document]rC   r	   rK   r   rc   Tuple[str, dict])rN   rd   rM   r#   rc   rf   )rO   r
   rM   r#   rc   Dict[str, Any])rJ   re   rK   r   rc   rg   )rc   r#   )__name__
__module____qualname____doc____annotations__r   r   r'   r)   propertyr-   r   model_configr   classmethodr:   rA   rQ   rT   rH   rF   rD   rb   __classcell__)r0   s   @r   r    r       sR   0d  /)QL*/4+O'  S&+t+?   $L
 (#  $ (#  $. <@9"9/89KN9	94 <@9"9/89KN9	94&

"
.1
	
 ( (r   r    N)rc   r   )rk   
__future__r   typingr   r   r   r   langchain_core._apir   langchain_core.callbacksr	   langchain_core.documentsr
   langchain_core.promptsr   r   langchain_core.prompts.promptr   pydanticr   r   r   'langchain.chains.combine_documents.baser   langchain.chains.llmr   r   r    r   r   r   <module>r{      sf    R " ) ) * . - F 8 7 7 *W 
	Y	B(4 B(B(r   