o
    Jjg<                     @  s<  d Z ddlmZ ddlZddlmZmZmZmZm	Z	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mZ ddl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% ddl&m'Z'm(Z(m)Z)m*Z* ddl+m,Z, ddl-m.Z. ddl/m0Z0m1Z1 ddl2m3Z3 eddddG dd de3Z4dddZ5dS )z2Chain that just formats a prompt and calls an LLM.    )annotationsN)AnyDictListOptionalSequenceTupleUnioncast)
deprecated)AsyncCallbackManagerAsyncCallbackManagerForChainRunCallbackManagerCallbackManagerForChainRun	Callbacks)BaseLanguageModelLanguageModelInput)BaseMessage)BaseLLMOutputParserStrOutputParser)ChatGeneration
Generation	LLMResult)PromptValue)BasePromptTemplatePromptTemplate)RunnableRunnableBindingRunnableBranchRunnableWithFallbacks)DynamicRunnable)get_colored_text)
ConfigDictField)Chainz0.1.17z&RunnableSequence, e.g., `prompt | llm`z1.0)sincealternativeremovalc                   @  s  e Zd ZU dZed[ddZded< 	 ded	< 	 d
Zded< ee	dZ
ded< 	 dZded< 	 eedZded< edddZed\ddZed\ddZ	d]d^d!d"Z	d]d_d&d'Z	d]d`d)d*Z	d]dad,d-Z	d]dbd.d/Z	d]dcd3d4Z	d]dcd5d6Zeddd7d8Zded:d;Z	d]dfd<d=Zd]dgd@dAZd]dgdBdCZ	d]dhdEdFZ	d]didHdIZ 	d]djdKdLZ!dkdNdOZ"	d]djdPdQZ#edddRdSZ$edldVdWZ%dmdYdZZ&dS )nLLMChaina^  Chain to run queries against LLMs.

    This class is deprecated. See below for an example implementation using
    LangChain runnables:

        .. code-block:: python

            from langchain_core.output_parsers import StrOutputParser
            from langchain_core.prompts import PromptTemplate
            from langchain_openai import OpenAI

            prompt_template = "Tell me a {adjective} joke"
            prompt = PromptTemplate(
                input_variables=["adjective"], template=prompt_template
            )
            llm = OpenAI()
            chain = prompt | llm | StrOutputParser()

            chain.invoke("your adjective here")

    Example:
        .. code-block:: python

            from langchain.chains import LLMChain
            from langchain_community.llms import OpenAI
            from langchain_core.prompts import PromptTemplate
            prompt_template = "Tell me a {adjective} joke"
            prompt = PromptTemplate(
                input_variables=["adjective"], template=prompt_template
            )
            llm = LLMChain(llm=OpenAI(), prompt=prompt)
    returnboolc                 C     dS )NT selfr,   r,   L/var/www/html/zoom/venv/lib/python3.10/site-packages/langchain/chains/llm.pyis_lc_serializableM      zLLMChain.is_lc_serializabler   promptzSUnion[Runnable[LanguageModelInput, str], Runnable[LanguageModelInput, BaseMessage]]llmtextstr
output_key)default_factoryr   output_parserTreturn_final_onlydict
llm_kwargsforbid)arbitrary_types_allowedextra	List[str]c                 C  s   | j jS )zJWill be whatever keys the prompt expects.

        :meta private:
        )r2   input_variablesr-   r,   r,   r/   
input_keysf   s   zLLMChain.input_keysc                 C  s   | j r| jgS | jdgS )z=Will always return text key.

        :meta private:
        full_generation)r9   r6   r-   r,   r,   r/   output_keysn   s   
zLLMChain.output_keysNinputsDict[str, Any]run_manager$Optional[CallbackManagerForChainRun]Dict[str, str]c                 C  s   | j |g|d}| |d S NrF   r   )generatecreate_outputsr.   rD   rF   responser,   r,   r/   _cally   s   zLLMChain._call
input_listList[Dict[str, Any]]r   c           	      C  s   | j ||d\}}|r| nd}t| jtr%| jj||fd|i| jS | jjdd|i| jt	t
|d|i}g }|D ]}t|trO|t|dg q>|t|dg q>t|dS 	z Generate LLM result from inputs.rJ   N	callbacksstop)message)r4   )generationsr,   )prep_prompts	get_child
isinstancer3   r   generate_promptr;   bindbatchr
   r   r   appendr   r   r   	r.   rP   rF   promptsrT   rS   resultsrV   resr,   r,   r/   rK      s(   

zLLMChain.generate)Optional[AsyncCallbackManagerForChainRun]c           	        s   | j ||dI dH \}}|r| nd}t| jtr,| jj||fd|i| jI dH S | jjdd|i| jt	t
|d|iI dH }g }|D ]}t|trY|t|dg qH|t|dg qHt|dS rR   )aprep_promptsrX   rY   r3   r   agenerate_promptr;   r[   abatchr
   r   r   r]   r   r   r   r^   r,   r,   r/   	agenerate   s*   


zLLMChain.agenerate-Tuple[List[PromptValue], Optional[List[str]]]c           	        s   d}t |dkrg |fS d|d v r|d d }g }|D ]?  fdd| jjD }| jjdi |}t| d}d| }|rH|j|d| jd	 d v rV d |krVtd
|	| q||fS )Prepare prompts from inputs.Nr   rT   c                      i | ]}| | qS r,   r,   .0krD   r,   r/   
<dictcomp>       z)LLMChain.prep_prompts.<locals>.<dictcomp>greenPrompt after formatting:

endverbose=If `stop` is present in any inputs, should be present in all.r,   
lenr2   r@   format_promptr!   	to_stringon_textru   
ValueErrorr]   	r.   rP   rF   rT   r_   selected_inputsr2   _colored_text_textr,   rm   r/   rW      s&   zLLMChain.prep_promptsc           	        s   d}t |dkrg |fS d|d v r|d d }g }|D ]B  fdd| jjD }| jjdi |}t| d}d| }|rL|j|d| jd	I dH  d v rZ d |krZtd
|	| q||fS )rh   Nr   rT   c                   ri   r,   r,   rj   rm   r,   r/   rn      ro   z*LLMChain.aprep_prompts.<locals>.<dictcomp>rp   rq   rr   rs   rv   r,   rw   r}   r,   rm   r/   rc      s(   zLLMChain.aprep_promptsrS   r   List[Dict[str, str]]c              
   C  s   t || j| j}|jdd|i|  d}z	| j||d}W n ty1 } z|| |d}~ww | 	|}|
d|i |S z0Utilize the LLM generate method for speed gains.NrP   )namerJ   outputs)r   	configurerS   ru   on_chain_startget_namerK   BaseExceptionon_chain_errorrL   on_chain_endr.   rP   rS   callback_managerrF   rN   er   r,   r,   r/   apply   s$   


zLLMChain.applyc              
     s   t || j| j}|jdd|i|  dI dH }z| j||dI dH }W n ty; } z
||I dH  |d}~ww | 	|}|
d|iI dH  |S r   )r   r   rS   ru   r   r   rf   r   r   rL   r   r   r,   r,   r/   aapply   s&   

zLLMChain.aapplyc                 C  s   | j S Nr6   r-   r,   r,   r/   _run_output_key  s   zLLMChain._run_output_key
llm_resultc                   s0    fdd|j D } jr fdd|D }|S )zCreate outputs from response.c                   s"   g | ]} j  j|d |iqS )rB   )r6   r8   parse_result)rk   
generationr-   r,   r/   
<listcomp>  s    z+LLMChain.create_outputs.<locals>.<listcomp>c                   s   g | ]
} j | j  iqS r,   r   )rk   rr-   r,   r/   r   $  s    )rV   r9   )r.   r   resultr,   r-   r/   rL     s   
zLLMChain.create_outputsc                   s&   | j |g|dI d H }| |d S rI   )rf   rL   rM   r,   r,   r/   _acall'  s   zLLMChain._acallkwargsr   c                 K  s   | ||d| j  S )S  Format prompt with kwargs and pass to LLM.

        Args:
            callbacks: Callbacks to pass to LLMChain
            **kwargs: Keys to pass to prompt template.

        Returns:
            Completion from LLM.

        Example:
            .. code-block:: python

                completion = llm.predict(adjective="funny")
        rS   r   r.   rS   r   r,   r,   r/   predict/  s   zLLMChain.predictc                   s   | j ||dI dH | j S )r   r   N)acallr6   r   r,   r,   r/   apredict@  s   zLLMChain.apredict%Union[str, List[str], Dict[str, Any]]c                 K  s<   t d | jdd|i|}| jjdur| jj|S |S )z(Call predict and then parse the results.z_The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.rS   Nr,   )warningswarnr   r2   r8   parser.   rS   r   r   r,   r,   r/   predict_and_parseQ  s   zLLMChain.predict_and_parse%Union[str, List[str], Dict[str, str]]c                   sD   t d | jdd|i|I dH }| jjdur | jj|S |S )z)Call apredict and then parse the results.z`The apredict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.rS   Nr,   )r   r   r   r2   r8   r   r   r,   r,   r/   apredict_and_parse_  s   zLLMChain.apredict_and_parse/Sequence[Union[str, List[str], Dict[str, str]]]c                 C  s"   t d | j||d}| |S )&Call apply and then parse the results.z]The apply_and_parse method is deprecated, instead pass an output parser directly to LLMChain.r   )r   r   r   _parse_generationr.   rP   rS   r   r,   r,   r/   apply_and_parsem  s
   
zLLMChain.apply_and_parser   c                   s"    j jd ur fdd|D S |S )Nc                   s    g | ]} j j| j qS r,   )r2   r8   r   r6   )rk   ra   r-   r,   r/   r   |  s    z.LLMChain._parse_generation.<locals>.<listcomp>)r2   r8   )r.   r   r,   r-   r/   r   x  s
   
zLLMChain._parse_generationc                   s*   t d | j||dI dH }| |S )r   z^The aapply_and_parse method is deprecated, instead pass an output parser directly to LLMChain.r   N)r   r   r   r   r   r,   r,   r/   aapply_and_parse  s   
zLLMChain.aapply_and_parsec                 C  r+   )N	llm_chainr,   r-   r,   r,   r/   _chain_type  r1   zLLMChain._chain_typer   templatec                 C  s   t |}| ||dS )z&Create LLMChain from LLM and template.)r3   r2   )r   from_template)clsr3   r   prompt_templater,   r,   r/   from_string  s   
zLLMChain.from_stringintc                 C  s   t | j|S r   )_get_language_modelr3   get_num_tokens)r.   r4   r,   r,   r/   _get_num_tokens  s   zLLMChain._get_num_tokens)r)   r*   )r)   r?   r   )rD   rE   rF   rG   r)   rH   )rP   rQ   rF   rG   r)   r   )rP   rQ   rF   rb   r)   r   )rP   rQ   rF   rG   r)   rg   )rP   rQ   rF   rb   r)   rg   )rP   rQ   rS   r   r)   r   )r)   r5   )r   r   r)   rQ   )rD   rE   rF   rb   r)   rH   )rS   r   r   r   r)   r5   )rS   r   r   r   r)   r   )rS   r   r   r   r)   r   )rP   rQ   rS   r   r)   r   )r   r   r)   r   )r3   r   r   r5   r)   r(   )r4   r5   r)   r   )'__name__
__module____qualname____doc__classmethodr0   __annotations__r6   r#   r   r8   r9   r:   r;   r"   model_configpropertyrA   rC   rO   rK   rf   rW   rc   r   r   r   rL   r   r   r   r   r   r   r   r   r   r   r   r,   r,   r,   r/   r(   &   sr   
 !

r(   llm_liker   r)   r   c                 C  s`   t | tr| S t | trt| jS t | trt| jS t | ttfr't| j	S t
dt|  )NzAUnable to extract BaseLanguageModel from llm_like object of type )rY   r   r   r   boundr   runnabler   r    defaultr|   type)r   r,   r,   r/   r     s   





r   )r   r   r)   r   )6r   
__future__r   r   typingr   r   r   r   r   r   r	   r
   langchain_core._apir   langchain_core.callbacksr   r   r   r   r   langchain_core.language_modelsr   r   langchain_core.messagesr   langchain_core.output_parsersr   r   langchain_core.outputsr   r   r   langchain_core.prompt_valuesr   langchain_core.promptsr   r   langchain_core.runnablesr   r   r   r   %langchain_core.runnables.configurabler    langchain_core.utils.inputr!   pydanticr"   r#   langchain.chains.baser$   r(   r   r,   r,   r,   r/   <module>   s4    (  s