o
    Jjg(                     @   s  d Z ddlmZ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mZ ddlmZ ddlmZmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZmZ ddlm Z  dZ!dZ"e#dZ$dede%ddfddZ&G dd de eZ'eddddG dd de Z(dS )z.Base interface for chains combining documents.    )ABCabstractmethod)AnyDictListOptionalTupleType)
deprecated)AsyncCallbackManagerForChainRunCallbackManagerForChainRun)Document)BasePromptTemplatePromptTemplate)RunnableConfig)create_model)RecursiveCharacterTextSplitterTextSplitter)	BaseModelField)Chainz

contextz{page_content}promptdocument_variable_namereturnNc                 C   s$   || j vrtd| d| j  d S )NzPrompt must accept z= as an input variable. Received prompt with input variables: )input_variables
ValueError)r   r    r   _/var/www/html/zoom/venv/lib/python3.10/site-packages/langchain/chains/combine_documents/base.py_validate_prompt   s   
r   c                	   @   s`  e Zd ZU dZdZeed< dZeed< 	ddee	 de
e fd	d
Z	ddee	 de
e fddZedee fddZedee fddZdee dedee fddZedee dedeeef fddZedee dedeeef fddZ	ddeeee f dee deeef fddZ	ddeeee f dee deeef fddZdS ) BaseCombineDocumentsChainaW  Base interface for chains combining documents.

    Subclasses of this chain deal with combining documents in a variety of
    ways. This base class exists to add some uniformity in the interface these types
    of chains should expose. Namely, they expect an input key related to the documents
    to use (default `input_documents`), and then also expose a method to calculate
    the length of a prompt from documents (useful for outside callers to use to
    determine whether it's safe to pass a list of documents into this chain or whether
    that will be longer than the context length).
    input_documents	input_keyoutput_text
output_keyNconfigr   c                 C   s   t 	di | jtt d fiS )NCombineDocumentsInput)r&   )r   r"   r   r   selfr%   r   r   r   get_input_schema0   s
   z*BaseCombineDocumentsChain.get_input_schemac                 C      t 	di | jtd fiS )NCombineDocumentsOutput)r+   )r   r$   strr'   r   r   r   get_output_schema8   
   z+BaseCombineDocumentsChain.get_output_schemac                 C      | j gS z2Expect input key.

        :meta private:
        r"   r(   r   r   r   
input_keys@      z$BaseCombineDocumentsChain.input_keysc                 C   r/   z3Return output key.

        :meta private:
        )r$   r2   r   r   r   output_keysH   r4   z%BaseCombineDocumentsChain.output_keysdocskwargsc                 K      dS )aV  Return the prompt length given the documents passed in.

        This can be used by a caller to determine whether passing in a list
        of documents would exceed a certain prompt length. This useful when
        trying to ensure that the size of a prompt remains below a certain
        context limit.

        Args:
            docs: List[Document], a list of documents to use to calculate the
                total prompt length.

        Returns:
            Returns None if the method does not depend on the prompt length,
            otherwise the length of the prompt in tokens.
        Nr   r(   r7   r8   r   r   r   prompt_lengthP   s   z'BaseCombineDocumentsChain.prompt_lengthc                 K   r9   a  Combine documents into a single string.

        Args:
            docs: List[Document], the documents to combine
            **kwargs: Other parameters to use in combining documents, often
                other inputs to the prompt.

        Returns:
            The first element returned is the single string output. The second
            element returned is a dictionary of other keys to return.
        Nr   r:   r   r   r   combine_docsb   s    z&BaseCombineDocumentsChain.combine_docsc                    s   dS r<   r   r:   r   r   r   acombine_docsp   s    z'BaseCombineDocumentsChain.acombine_docsinputsrun_managerc                    sX   |pt  }| j } fdd| D } j|fd| i|\}}|| j< |S )3Prepare inputs, call combine docs, prepare outputs.c                        i | ]\}}| j kr||qS r   r1   .0kvr2   r   r   
<dictcomp>        z3BaseCombineDocumentsChain._call.<locals>.<dictcomp>	callbacks)r   get_noop_managerr"   itemsr=   	get_childr$   r(   r?   r@   _run_managerr7   
other_keysoutputextra_return_dictr   r2   r   _call   s   


zBaseCombineDocumentsChain._callc                    s`   |pt  }| j } fdd| D } j|fd| i|I dH \}}|| j< |S )rA   c                    rB   r   r1   rC   r2   r   r   rG      rH   z4BaseCombineDocumentsChain._acall.<locals>.<dictcomp>rI   N)r   rJ   r"   rK   r>   rL   r$   rM   r   r2   r   _acall   s   

z BaseCombineDocumentsChain._acallN) __name__
__module____qualname____doc__r"   r,   __annotations__r$   r   r   r	   r   r)   r-   propertyr   r3   r6   r   r   intr;   r   r   dictr=   r>   r   r   rR   r   rS   r   r   r   r   r    !   s^   
 
	
$



r    z0.2.7zexample in API reference with more detail: https://api.python.langchain.com/en/latest/chains/langchain.chains.combine_documents.base.AnalyzeDocumentChain.htmlz1.0)sincealternativeremovalc                	   @   s   e Zd ZU dZdZeed< eedZ	e
ed< eed< edee fdd	Zedee fd
dZ	ddee dee fddZ	ddee dee fddZ	ddeeef dee deeef fddZdS )AnalyzeDocumentChaina  Chain that splits documents, then analyzes it in pieces.

    This chain is parameterized by a TextSplitter and a CombineDocumentsChain.
    This chain takes a single document as input, and then splits it up into chunks
    and then passes those chucks to the CombineDocumentsChain.

    This class is deprecated. See below for alternative implementations which
    supports async and streaming modes of operation.

    If the underlying combine documents chain takes one ``input_documents`` argument
    (e.g., chains generated by ``load_summarize_chain``):

        .. code-block:: python

            split_text = lambda x: text_splitter.create_documents([x])

            summarize_document_chain = split_text | chain

    If the underlying chain takes additional arguments (e.g., ``load_qa_chain``, which
    takes an additional ``question`` argument), we can use the following:

        .. code-block:: python

            from operator import itemgetter
            from langchain_core.runnables import RunnableLambda, RunnableParallel

            split_text = RunnableLambda(
                lambda x: text_splitter.create_documents([x])
            )
            summarize_document_chain = RunnableParallel(
                question=itemgetter("question"),
                input_documents=itemgetter("input_document") | split_text,
            ) | chain.pick("output_text")

    To additionally return the input parameters, as ``AnalyzeDocumentChain`` does,
    we can wrap this construction with ``RunnablePassthrough``:

        .. code-block:: python

            from operator import itemgetter
            from langchain_core.runnables import (
                RunnableLambda,
                RunnableParallel,
                RunnablePassthrough,
            )

            split_text = RunnableLambda(
                lambda x: text_splitter.create_documents([x])
            )
            summarize_document_chain = RunnablePassthrough.assign(
                output_text=RunnableParallel(
                    question=itemgetter("question"),
                    input_documents=itemgetter("input_document") | split_text,
                ) | chain.pick("output_text")
            )
    input_documentr"   )default_factorytext_splittercombine_docs_chainr   c                 C   r/   r0   r1   r2   r   r   r   r3      r4   zAnalyzeDocumentChain.input_keysc                 C   s   | j jS r5   )rd   r6   r2   r   r   r   r6      r4   z AnalyzeDocumentChain.output_keysNr%   c                 C   r*   )Nr`   )r`   )r   r"   r,   r'   r   r   r   r)      r.   z%AnalyzeDocumentChain.get_input_schemac                 C   s   | j |S rT   )rd   r-   r'   r   r   r   r-      s   z&AnalyzeDocumentChain.get_output_schemar?   r@   c                    sZ   |pt  }| j } j|g} fdd| D }|| jj<  j|d| dS )z=Split document into chunks and pass to CombineDocumentsChain.c                    rB   r   r1   rC   r2   r   r   rG     rH   z.AnalyzeDocumentChain._call.<locals>.<dictcomp>T)return_only_outputsrI   )r   rJ   r"   rc   create_documentsrK   rd   rL   )r(   r?   r@   rN   documentr7   rO   r   r2   r   rR     s   

zAnalyzeDocumentChain._callrT   )rU   rV   rW   rX   r"   r,   rY   r   r   rc   r   r    rZ   r   r3   r6   r   r   r	   r   r)   r-   r   r   rR   r   r   r   r   r`      s:   
 	9
	


r`   ))rX   abcr   r   typingr   r   r   r   r   r	   langchain_core._apir
   langchain_core.callbacksr   r   langchain_core.documentsr   langchain_core.promptsr   r   langchain_core.runnables.configr   langchain_core.runnables.utilsr   langchain_text_splittersr   r   pydanticr   r   langchain.chains.baser   DEFAULT_DOCUMENT_SEPARATORDOCUMENTS_KEYfrom_templateDEFAULT_DOCUMENT_PROMPTr,   r   r    r`   r   r   r   r   <module>   s0     
 