o
    Jjgb/                     @  s   d Z ddlmZ ddlmZmZ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 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lmZ eddddG dd deZdS )zOCombining documents by mapping a chain over them first, then combining results.    )annotations)AnyDictListOptionalTupleType)
deprecated)	Callbacks)Document)RunnableConfig)create_model)	BaseModel
ConfigDictmodel_validator)BaseCombineDocumentsChain)ReduceDocumentsChain)LLMChainz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/map_reduce_chain/)sinceremovalmessagec                      s  e Zd ZU dZded< 	 ded< 	 ded< 	 dZd	ed
< 	 	d5d6 fddZed7 fddZe	dddZ
edded8ddZedded8dd Zedded8d!d"Zed9d#d$Zed9d%d&Z		d:d;d/d0Z		d:d;d1d2Zed<d3d4Z  ZS )=MapReduceDocumentsChaina-  Combining documents by mapping a chain over them, then combining results.

    We first call `llm_chain` on each document individually, passing in the
    `page_content` and any other kwargs. This is the `map` step.

    We then process the results of that `map` step in a `reduce` step. This should
    likely be a ReduceDocumentsChain.

    Example:
        .. code-block:: python

            from langchain.chains import (
                StuffDocumentsChain,
                LLMChain,
                ReduceDocumentsChain,
                MapReduceDocumentsChain,
            )
            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}"
            )
            llm_chain = LLMChain(llm=llm, prompt=prompt)
            # We now define how to combine these summaries
            reduce_prompt = PromptTemplate.from_template(
                "Combine these summaries: {context}"
            )
            reduce_llm_chain = LLMChain(llm=llm, prompt=reduce_prompt)
            combine_documents_chain = StuffDocumentsChain(
                llm_chain=reduce_llm_chain,
                document_prompt=document_prompt,
                document_variable_name=document_variable_name
            )
            reduce_documents_chain = ReduceDocumentsChain(
                combine_documents_chain=combine_documents_chain,
            )
            chain = MapReduceDocumentsChain(
                llm_chain=llm_chain,
                reduce_documents_chain=reduce_documents_chain,
            )
            # If we wanted to, we could also pass in collapse_documents_chain
            # which is specifically aimed at collapsing documents BEFORE
            # the final call.
            prompt = PromptTemplate.from_template(
                "Collapse this content: {context}"
            )
            llm_chain = LLMChain(llm=llm, prompt=prompt)
            collapse_documents_chain = StuffDocumentsChain(
                llm_chain=llm_chain,
                document_prompt=document_prompt,
                document_variable_name=document_variable_name
            )
            reduce_documents_chain = ReduceDocumentsChain(
                combine_documents_chain=combine_documents_chain,
                collapse_documents_chain=collapse_documents_chain,
            )
            chain = MapReduceDocumentsChain(
                llm_chain=llm_chain,
                reduce_documents_chain=reduce_documents_chain,
            )
    r   	llm_chainr   reduce_documents_chainstrdocument_variable_nameFboolreturn_intermediate_stepsNconfigOptional[RunnableConfig]returnType[BaseModel]c                   s8   | j rt	di | jtd fdtt d fiS t |S )NMapReduceDocumentsOutputintermediate_steps)r"   )r   r   
output_keyr   r   superget_output_schema)selfr   	__class__ e/var/www/html/zoom/venv/lib/python3.10/site-packages/langchain/chains/combine_documents/map_reduce.pyr&   r   s   
z)MapReduceDocumentsChain.get_output_schema	List[str]c                   s   t  j}| jr|dg }|S )z2Expect input key.

        :meta private:
        r#   )r%   output_keysr   )r'   _output_keysr(   r*   r+   r-      s   
z#MapReduceDocumentsChain.output_keysTforbid)arbitrary_types_allowedextrabefore)modevaluesr   r   c                 C  sV   d|v r)d|v rt d|d }|d}t||d}||d< |d= d|v r)|d= |S )For backwards compatibility.combine_document_chainr   zBoth `reduce_documents_chain` and `combine_document_chain` cannot be provided at the same time. `combine_document_chain` is deprecated, please only provide `reduce_documents_chain`collapse_document_chain)combine_documents_chaincollapse_documents_chain)
ValueErrorgetr   )clsr4   combine_chaincollapse_chainreduce_chainr*   r*   r+   get_reduce_chain   s    
z(MapReduceDocumentsChain.get_reduce_chainc                 C  s   d|v r|d |d< |d= |S )r5   return_map_stepsr   r*   )r<   r4   r*   r*   r+   get_return_intermediate_steps   s   z5MapReduceDocumentsChain.get_return_intermediate_stepsc                 C  sp   d|vrt d|d jj}d|vr$t|dkr |d |d< |S t d|d |vr6t d|d  d| |S )	z4Get default document variable name, if not provided.r   z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: )r:   promptinput_variableslen)r<   r4   llm_chain_variablesr*   r*   r+   "get_default_document_variable_name   s"   z:MapReduceDocumentsChain.get_default_document_variable_namec                 C  s:   t | jtr| jjr| jjS | jjS tdt| j dz Kept for backward compatibility.z$`reduce_documents_chain` is of type z$ so it does not have this attribute.)
isinstancer   r   r9   r8   r:   typer'   r*   r*   r+   r7      s   z/MapReduceDocumentsChain.collapse_document_chainc                 C  s*   t | jtr
| jjS tdt| j drI   )rJ   r   r   r8   r:   rK   rL   r*   r*   r+   r6      s   z.MapReduceDocumentsChain.combine_document_chaindocsList[Document]	token_maxOptional[int]	callbacksr
   kwargsTuple[str, dict]c           
        s   j jfdd D |d}j j fddt|D }jj|f||d\}}jr?fdd|D }	|	|d< ||fS )Combine documents in a map reduce manner.

        Combine by mapping first chain over all documents, then reducing the results.
        This reducing can be done recursively if needed (if there are many documents).
        c                   s   g | ]
}j |ji qS r*   r   page_content.0drR   r'   r*   r+   
<listcomp>   s    z8MapReduceDocumentsChain.combine_docs.<locals>.<listcomp>rQ   c                   &   g | ]\}}t |  | jd qS )rV   metadatar   r_   rX   irrM   question_result_keyr*   r+   r[          rO   rQ   c                      g | ]}|  qS r*   r*   rX   rc   re   r*   r+   r[          r#   )r   applyr$   	enumerater   combine_docsr   
r'   rM   rO   rQ   rR   map_resultsresult_docsresultextra_return_dictr#   r*   rM   rR   re   r'   r+   rn      s&   
z$MapReduceDocumentsChain.combine_docsc           
        s   j jfdd D |dI dH }j j fddt|D }jj|f||dI dH \}}jrFfdd|D }	|	|d< ||fS )	rT   c                   s    g | ]}i j |ji qS r*   rU   rW   rZ   r*   r+   r[     s     z9MapReduceDocumentsChain.acombine_docs.<locals>.<listcomp>r\   Nc                   r]   r^   r`   ra   rd   r*   r+   r[     rf   rg   c                   rh   r*   r*   ri   rj   r*   r+   r[     rk   r#   )r   aapplyr$   rm   r   acombine_docsr   ro   r*   rt   r+   rv     s(   z%MapReduceDocumentsChain.acombine_docsc                 C  s   dS )Nmap_reduce_documents_chainr*   rL   r*   r*   r+   _chain_type"  s   z#MapReduceDocumentsChain._chain_type)N)r   r   r    r!   )r    r,   )r4   r   r    r   )r    r   )NN)
rM   rN   rO   rP   rQ   r
   rR   r   r    rS   )r    r   )__name__
__module____qualname____doc____annotations__r   r&   propertyr-   r   model_configr   classmethodr@   rB   rH   r7   r6   rn   rv   rx   __classcell__r*   r*   r(   r+   r      sN   
 
J
"r   N)r|   
__future__r   typingr   r   r   r   r   r   langchain_core._apir	   langchain_core.callbacksr
   langchain_core.documentsr   langchain_core.runnables.configr   langchain_core.runnables.utilsr   pydanticr   r   r   'langchain.chains.combine_documents.baser   )langchain.chains.combine_documents.reducer   langchain.chains.llmr   r   r*   r*   r*   r+   <module>   s$     	