
    gh$                        d 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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dS )zLCombine documents by doing a first pass and then refining on more documents.    )annotations)Any)
deprecated)	Callbacks)Document)BasePromptTemplateformat_documentPromptTemplate)
ConfigDictFieldmodel_validator)BaseCombineDocumentsChain)LLMChainreturnr   c                 &    t          dgd          S )Npage_contentz{page_content})input_variablestemplater
        f/var/www/FlaskApp/flask-venv/lib/python3.11/site-packages/langchain/chains/combine_documents/refine.py_get_default_document_promptr      s    >*:EUVV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                  t    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/d0d"Z	 d/d0d#Zd1d&Zd2d*Zd3d+Ze	d4d,            Z xZS )5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_stepsr   	list[str]c                H    t                      j        }| 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   s1     ww*) 	A'+?*@@Lr   Tforbid)arbitrary_types_allowedextrabefore)modevaluesdictr   c                *    d|v r|d         |d<   |d= |S )zFor backwards compatibility.return_refine_stepsr'   r   )clsr5   s     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<   n4t          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)r9   r5   llm_chain_variabless      r   "get_default_document_variable_namez7RefineDocumentsChain.get_default_document_variable_name}   s     f,,ABBB$%89@P#611&''1,,3Fq3I/00 9  
 ./7JJJ Uf5M.N U U?RU U   r   Ndocslist[Document]	callbacksr   kwargstuple[str, dict]c                    | j         |fi |} | j        j        dd|i|}|g}|dd         D ]G}|                     ||          }i ||} | j        j        dd|i|}|                    |           H|                     ||          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.
        rD   r<   Nr   )_construct_initial_inputsr   predict_construct_refine_inputsr    append_construct_result	r-   rB   rD   rE   inputsresrefine_stepsdocbase_inputss	            r   combine_docsz!RefineDocumentsChain.combine_docs   s     0/????,d$,KKyKFKKu8 	% 	%C77SAAK..v.F/$'/NN)NvNNC$$$$%%lC888r   c                8  K    | j         |fi |} | j        j        dd|i| d{V }|g}|dd         D ]M}|                     ||          }i ||} | j        j        dd|i| d{V }|                    |           N|                     ||          S )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.
        rD   Nr<   r   )rH   r   apredictrJ   r    rK   rL   rM   s	            r   acombine_docsz"RefineDocumentsChain.acombine_docs   s        0/????3D*3RRiR6RRRRRRRRu8 	% 	%C77SAAK..v.F6-6UUUfUUUUUUUUC$$$$%%lC888r   rP   rO   c                &    | j         rd|i}ni }||fS )Nr*   )r'   )r-   rP   rO   extra_return_dicts       r   rL   z&RefineDocumentsChain._construct_result   s-    ) 	#!5| D "%%%r   rQ   r   dict[str, Any]c                H    | j         t          || j                  | j        |iS N)r"   r	   r%   r#   )r-   rQ   rO   s      r   rJ   z-RefineDocumentsChain._construct_refine_inputs   s)    'd>R)S)S&
 	
r   c                    d|d         j         i                    |d         j                   fd| j        j        D             }| j         | j        j        di |i}i ||}|S )Nr   r   c                "    i | ]}||         S r   r   ).0k	base_infos     r   
<dictcomp>zBRefineDocumentsChain._construct_initial_inputs.<locals>.<dictcomp>   s    WWWQIaLWWWr   r   )r   updatemetadatar%   r   r"   format)r-   rB   rE   document_inforR   rN   r`   s         @r   rH   z.RefineDocumentsChain._construct_initial_inputs   s     $T!W%9:	a)***WWWW$2F2VWWW')D)=)D)U)U})U)U
 +K*6*r   c                    dS )Nrefine_documents_chainr   )r-   s    r   _chain_typez RefineDocumentsChain._chain_type   s    ''r   )r   r(   )r5   r6   r   r   r[   )rB   rC   rD   r   rE   r   r   rF   )rP   r(   rO   r!   r   rF   )rQ   r   rO   r!   r   rY   )rB   rC   rE   r   r   rY   )r   r!   )__name__
__module____qualname____doc____annotations__r   r   r%   r'   propertyr,   r   model_configr   classmethodr:   rA   rS   rV   rL   rJ   rH   rh   __classcell__)r/   s   @r   r   r      s        0 0d  /)QL*/%4+ + +O     S&+++++?     X : $  L
 _(###   [ $# _(###   [ $#. <@9 9 9 9 94 <@9 9 9 9 94& & & &
 
 
 

 
 
 
 ( ( ( X( ( ( ( (r   r   N)r   r   )rl   
__future__r   typingr   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|      sb   R R " " " " " "       * * * * * * . . . . . . - - - - - - F F F F F F F F 8 8 8 8 8 8 7 7 7 7 7 7 7 7 7 7      * ) ) ) ) )W W W W 
	Y	  B( B( B( B( B(4 B( B( B( B( B(r   