a
    agb/                     @  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/)ZsinceZremovalmessagec                      s2  e Zd ZU dZded< ded< ded< dZd	ed
< d2ddd fddZedd fddZe	dddZ
eddedddddZeddeddddd Zeddedddd!d"Zeddd#d$Zeddd%d&Zd3d'd(d)dd*d+d,d-Zd4d'd(d)dd*d+d.d/Zeddd0d1Z  ZS )5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_stepsNzOptional[RunnableConfig]zType[BaseModel])configreturnc                   s6   | 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__ {/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain/chains/combine_documents/map_reduce.pyr"   r   s     
z)MapReduceDocumentsChain.get_output_schemaz	List[str])r   c                   s   t  j}| jr|dg }|S )z2Expect input key.

        :meta private:
        r   )r!   output_keysr   )r#   Z_output_keysr$   r&   r'   r(      s    
z#MapReduceDocumentsChain.output_keysTZforbid)Zarbitrary_types_allowedextrabefore)moder   r   )valuesr   c                 C  sV   d|v rRd|v rt d|d }|d}t||d}||d< |d= d|v rR|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   )clsr,   Zcombine_chainZcollapse_chainZreduce_chainr&   r&   r'   get_reduce_chain   s     
z(MapReduceDocumentsChain.get_reduce_chainc                 C  s   d|v r|d |d< |d= |S )r-   Zreturn_map_stepsr   r&   )r4   r,   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rHt|dkr>|d |d< qlt dn$|d |vrlt 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: )r2   promptZinput_variableslen)r4   r,   Z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 ntdt| j ddS z Kept for backward compatibility.z$`reduce_documents_chain` is of type z$ so it does not have this attribute.N)
isinstancer   r   r1   r0   r2   typer#   r&   r&   r'   r/      s    
z/MapReduceDocumentsChain.collapse_document_chainc                 C  s.   t | jtr| jjS tdt| j ddS r;   )r<   r   r   r0   r2   r=   r>   r&   r&   r'   r.      s    z.MapReduceDocumentsChain.combine_document_chainzList[Document]zOptional[int]r
   zTuple[str, dict])docs	token_max	callbackskwargsr   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rB   r#   r&   r'   
<listcomp>       z8MapReduceDocumentsChain.combine_docs.<locals>.<listcomp>rA   c                   s&   g | ]\}}t |  | jd qS )rE   metadatar   rN   rG   irr?   question_result_keyr&   r'   rJ      s   r@   rA   c                   s   g | ]}|  qS r&   r&   rG   rR   rT   r&   r'   rJ      rK   r   )r   applyr    	enumerater   combine_docsr   
r#   r?   r@   rA   rB   Zmap_resultsZresult_docsresultZextra_return_dictr   r&   r?   rB   rT   r#   r'   rZ      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rfdd|D }	|	|d< ||fS )	rC   c                   s    g | ]}i j |ji qS r&   rD   rF   rI   r&   r'   rJ     rK   z9MapReduceDocumentsChain.acombine_docs.<locals>.<listcomp>rL   Nc                   s&   g | ]\}}t |  | jd qS rM   rO   rP   rS   r&   r'   rJ     s   rU   c                   s   g | ]}|  qS r&   r&   rV   rW   r&   r'   rJ     rK   r   )r   Zaapplyr    rY   r   acombine_docsr   r[   r&   r]   r'   r^     s&    z%MapReduceDocumentsChain.acombine_docsc                 C  s   dS )NZmap_reduce_documents_chainr&   r>   r&   r&   r'   _chain_type"  s    z#MapReduceDocumentsChain._chain_type)N)NN)NN)__name__
__module____qualname____doc____annotations__r   r"   propertyr(   r   Zmodel_configr   classmethodr5   r6   r:   r/   r.   rZ   r^   r_   __classcell__r&   r&   r$   r'   r      sD   

J 
  "  r   N)rc   
__future__r   typingr   r   r   r   r   r   Zlangchain_core._apir	   Zlangchain_core.callbacksr
   Zlangchain_core.documentsr   Zlangchain_core.runnables.configr   Zlangchain_core.runnables.utilsr   Zpydanticr   r   r   Z'langchain.chains.combine_documents.baser   Z)langchain.chains.combine_documents.reducer   Zlangchain.chains.llmr   r   r&   r&   r&   r'   <module>   s"    	