
    3fi;-                     >   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mZ dd	lmZmZ dd
lmZmZmZ ddlmZ ddlmZmZmZmZmZ ddl m!Z! ddeedde
dededz  dedz  de"de"dee#e"ef   ef   fdZ$ eddd       G d de             Z%y)z7Chain that combines documents by stuffing into context.    )Any)
deprecated)	Callbacks)Document)LanguageModelLike)BaseOutputParserStrOutputParser)BasePromptTemplateformat_document)RunnableRunnablePassthrough)
ConfigDictFieldmodel_validator)override)DEFAULT_DOCUMENT_PROMPTDEFAULT_DOCUMENT_SEPARATORDOCUMENTS_KEYBaseCombineDocumentsChain_validate_prompt)LLMChainN)output_parserdocument_promptdocument_separatordocument_variable_namellmpromptr   r   r   r   returnc                    t        |       |xs t        |xs
 t               }dt        dt        ffd}t        j                  di |ij                  d      |z  | z  |z  j                  d      S )a  Create a chain for passing a list of Documents to a model.

    Args:
        llm: Language model.
        prompt: Prompt template. Must contain input variable `"context"` (override by
            setting document_variable), which will be used for passing in the formatted
            documents.
        output_parser: Output parser. Defaults to `StrOutputParser`.
        document_prompt: Prompt used for formatting each document into a string. Input
            variables can be "page_content" or any metadata keys that are in all
            documents. "page_content" will automatically retrieve the
            `Document.page_content`, and all other inputs variables will be
            automatically retrieved from the `Document.metadata` dictionary. Default to
            a prompt that only contains `Document.page_content`.
        document_separator: String separator to use between formatted document strings.
        document_variable_name: Variable name to use for the formatted documents in the
            prompt. Defaults to `"context"`.

    Returns:
        An LCEL Runnable. The input is a dictionary that must have a `"context"` key
        that maps to a `list[Document]`, and any other input variables expected in the
        prompt. The `Runnable` return type depends on `output_parser` used.

    Example:
        ```python
        # pip install -U langchain langchain-openai

        from langchain_openai import ChatOpenAI
        from langchain_core.documents import Document
        from langchain_core.prompts import ChatPromptTemplate
        from langchain_classic.chains.combine_documents import (
            create_stuff_documents_chain,
        )

        prompt = ChatPromptTemplate.from_messages(
            [("system", "What are everyone's favorite colors:\n\n{context}")]
        )
        model = ChatOpenAI(model="gpt-3.5-turbo")
        chain = create_stuff_documents_chain(model, prompt)

        docs = [
            Document(page_content="Jesse loves red but not yellow"),
            Document(
                page_content="Jamal loves green but not as much as he loves orange"
            ),
        ]

        chain.invoke({"context": docs})
        ```
    inputsr   c                 >    j                  fd|    D              S )Nc              3   6   K   | ]  }t        |        y wN)r   ).0doc_document_prompts     n/var/www/auto_recruiter/arenv/lib/python3.12/site-packages/langchain_classic/chains/combine_documents/stuff.py	<genexpr>zDcreate_stuff_documents_chain.<locals>.format_docs.<locals>.<genexpr>Y   s!      '
 C!12'
s   )join)r    r&   r   r   s    r'   format_docsz1create_stuff_documents_chain.<locals>.format_docsX   s)    !&& '
45'
 
 	
    format_inputs)run_namestuff_documents_chain )r   r   r	   dictstrr   assignwith_config)	r   r   r   r   r   r   _output_parserr*   r&   s	       ``  @r'   create_stuff_documents_chainr5      s    v V34&A*A"7o&7N
D 
S 
 	""K&<k%JKWW$ 	X 	
 	 		
 	 k2k34r+   z0.2.13z1.0zThis class is deprecated. Use the `create_stuff_documents_chain` constructor instead. See migration guide here: https://python.langchain.com/docs/versions/migrating_chains/stuff_docs_chain/)sinceremovalmessagec                   z    e Zd ZU dZeed<   	  ed       Zeed<   	 e	ed<   	 dZ
e	ed<   	  ed	d
      Z ed      ededefd              Zeedee	   f fd              Zdee   dedefdZdee   dededz  fdZ	 ddee   dededee	ef   fdZ	 ddee   dededee	ef   fdZede	fd       Z xZS )StuffDocumentsChaina  Chain that combines documents by stuffing into context.

    This chain takes a list of documents and first combines them into a single string.
    It does this by formatting each document into a string with the `document_prompt`
    and then joining them together with `document_separator`. It then adds that new
    string to the inputs with the variable name set by `document_variable_name`.
    Those inputs are then passed to the `llm_chain`.

    Example:
        ```python
        from langchain_classic.chains import StuffDocumentsChain, LLMChain
        from langchain_core.prompts import PromptTemplate
        from langchain_openai 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"
        model = 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=model, prompt=prompt)
        chain = StuffDocumentsChain(
            llm_chain=llm_chain,
            document_prompt=document_prompt,
            document_variable_name=document_variable_name,
        )
        ```
    	llm_chainc                      t         S r#   )r   r/   r+   r'   <lambda>zStuffDocumentsChain.<lambda>   s     7 r+   )default_factoryr   r   z

r   Tforbid)arbitrary_types_allowedextrabefore)modevaluesr   c                     |d   j                   j                  }d|vr%t        |      dk(  r
|d   |d<   |S d}t        |      |d   |vrd|d    d| }t        |      |S )zGet default document variable name, if not provided.

        If only one variable is present in the llm_chain.prompt,
        we can infer that the formatted documents should be passed in
        with this variable name.
        r;   r      r   zQdocument_variable_name must be provided if there are multiple llm_chain_variableszdocument_variable_name z- was not found in llm_chain input_variables: )r   input_variableslen
ValueError)clsrD   llm_chain_variablesmsgs       r'   "get_default_document_variable_namez6StuffDocumentsChain.get_default_document_variable_name   s     %[188HH#61&'1,3Fq3I/0 3  !o%,-5HH)&1I*J)K L;;N:OQ  S/!r+   c                     | j                   j                  D cg c]  }|| j                  k7  s| }}t        |   |z   S c c}w r#   )r;   
input_keysr   super)selfk
extra_keys	__class__s      r'   rO   zStuffDocumentsChain.input_keys   sM     ~~00
A9T9T4TA

 
 w!J..
s
   AAdocskwargsc                 <   |D cg c]  }t        || j                         }}|j                         D ci c]*  \  }}|| j                  j                  j
                  v r||, }}}| j                  j                  |      || j                  <   |S c c}w c c}}w )a  Construct inputs from kwargs and docs.

        Format and then join all the documents together into one input with name
        `self.document_variable_name`. Also pluck any additional variables
        from **kwargs.

        Args:
            docs: List of documents to format and then join into single input
            **kwargs: additional inputs to chain, will pluck any other required
                arguments from here.

        Returns:
            dictionary of inputs to LLMChain
        )	r   r   itemsr;   r   rG   r   r)   r   )rQ   rU   rV   r%   doc_stringsrR   vr    s           r'   _get_inputszStuffDocumentsChain._get_inputs   s      NRRcsD,@,@ARR 
1DNN))999 qD
 

 /3.E.E.J.J;.Wt**+ S
s
   B/BNc                      | j                   |fi |} | j                  j                  j                  di |}| j                  j	                  |      S )a  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: a list of documents to use to calculate the total prompt length.
            **kwargs: additional parameters to use to get inputs to LLMChain.

        Returns:
            Returns None if the method does not depend on the prompt length,
            otherwise the length of the prompt in tokens.
        r/   )r[   r;   r   format_get_num_tokens)rQ   rU   rV   r    r   s        r'   prompt_lengthz!StuffDocumentsChain.prompt_length   sO      "!!$1&1-&&--77~~--f55r+   	callbacksc                 h     | j                   |fi |} | j                  j                  dd|i|i fS )a  Stuff all documents into one prompt and pass to LLM.

        Args:
            docs: List of documents to join together into one variable
            callbacks: Optional callbacks to pass along
            **kwargs: additional parameters to use to get inputs to LLMChain.

        Returns:
            The first element returned is the single string output. The second
            element returned is a dictionary of other keys to return.
        r`   r/   )r[   r;   predictrQ   rU   r`   rV   r    s        r'   combine_docsz StuffDocumentsChain.combine_docs   s?    " "!!$1&1%t~~%%D	DVDbHHr+   c                    K    | j                   |fi |} | j                  j                  dd|i| d{   i fS 7 w)a  Async stuff all documents into one prompt and pass to LLM.

        Args:
            docs: List of documents to join together into one variable
            callbacks: Optional callbacks to pass along
            **kwargs: additional parameters to use to get inputs to LLMChain.

        Returns:
            The first element returned is the single string output. The second
            element returned is a dictionary of other keys to return.
        r`   Nr/   )r[   r;   apredictrc   s        r'   acombine_docsz!StuffDocumentsChain.acombine_docs  sI     " "!!$1&1,T^^,,KyKFKKROOKs   5A >A c                      y)Nr.   r/   )rQ   s    r'   _chain_typezStuffDocumentsChain._chain_type!  s    &r+   r#   ) __name__
__module____qualname____doc__r   __annotations__r   r   r
   r1   r   r   model_configr   classmethodr0   r   rM   propertyr   listrO   r   r[   intr_   r   tuplerd   rg   ri   __classcell__)rT   s   @r'   r:   r:   h   s    D $*/7+O'  SI$$? $L
 (#    $2 /DI /  /X # $ 46$x. 6C 6C$J 6.  $I8nI I 	I
 
sDy	I0  $P8nP P 	P
 
sDy	P* 'S ' 'r+   r:   )&rm   typingr   langchain_core._apir   langchain_core.callbacksr   langchain_core.documentsr   langchain_core.language_modelsr   langchain_core.output_parsersr   r	   langchain_core.promptsr
   r   langchain_core.runnablesr   r   pydanticr   r   r   typing_extensionsr   /langchain_classic.chains.combine_documents.baser   r   r   r   r   langchain_classic.chains.llmr   r1   r0   r5   r:   r/   r+   r'   <module>r      s    =  * . - < K F B 7 7 &  2 .2158"/L4	L4L4 $d*	L4
 ($.L4 L4  L4 d38nc!"L4^ 
	X	r'3 r'r'r+   