o
    粪gS!                     @  s   d dl mZ d dlZd dlmZmZmZmZmZm	Z	 d dl
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 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dZ$G dd de#Z%d&d!d"Z&G d#d$ d$eZ'dS )'    )annotationsN)AnyDictListOptionalSequenceTuple)CallbackManagerForChainRun)BaseLanguageModel)	AIMessage)StrOutputParser)BasePromptTemplate)BaseRetriever)Runnable)Field)Chain)PROMPTQUESTION_GENERATOR_PROMPTFinishedOutputParser)LLMChainresponser   returnTuple[List[str], List[float]]c                 C  s@   g }g }| j d d D ]}||d  ||d  q||fS )z>Extract tokens and log probabilities from chat model response.logprobscontenttokenlogprob)response_metadataappend)r   tokens	log_probsr    r!   W/var/www/html/chatdoc2/venv/lib/python3.10/site-packages/langchain/chains/flare/base.py_extract_tokens_and_log_probs   s   r#   c                   @  s<   e Zd ZU dZeZded< 	 edddZe	dd	d
Z
dS )QuestionGeneratorChainz4Chain that generates questions from uncertain spans.r   promptr   boolc                 C  s   dS )NFr!   )clsr!   r!   r"   is_lc_serializable+   s   z)QuestionGeneratorChain.is_lc_serializable	List[str]c                 C  s   g dS )Input keys for the chain.
user_inputcontextr   r!   selfr!   r!   r"   
input_keys/   s   z!QuestionGeneratorChain.input_keysN)r   r&   r   r)   )__name__
__module____qualname____doc__r   r%   __annotations__classmethodr(   propertyr0   r!   r!   r!   r"   r$   %   s   
 r$   r   Sequence[str]r    Sequence[float]min_probfloatmin_token_gapintnum_pad_tokensr)   c                   s   t t ||k d } fdd|D }t|dkrg S |d |d | d gg}t|dd  D ] \}}	|	| d }
|	||  |k rK|
|d d< q2||	|
g q2 fdd|D S )Nr   c                   s    g | ]}t d  | r|qS )z\w)research).0ir   r!   r"   
<listcomp>=   s     z)_low_confidence_spans.<locals>.<listcomp>   c                   s"   g | ]\}}d   || qS ) )join)rB   startendrD   r!   r"   rE   G   s   " )npwhereexplen	enumerater   )r   r    r;   r=   r?   _low_idxlow_idxspansrC   idxrK   r!   rD   r"   _low_confidence_spans5   s   rU   c                   @  s   e Zd ZU dZded< 	 ded< 	 eedZded< 	 ded	< 	 d
Zded< 	 dZ	ded< 	 dZ
ded< 	 dZded< 	 dZded< 	 ed9ddZed9ddZd:d$d%Zd;d(d)Z	*d<d=d/d0Ze	1d>d?d7d8Zd*S )@
FlareChainzChain that combines a retriever, a question generator,
    and a response generator.

    See [Active Retrieval Augmented Generation](https://arxiv.org/abs/2305.06983) paper.
    r   question_generator_chainresponse_chain)default_factoryr   output_parserr   	retrieverg?r<   r;      r>   r=      r?   
   max_iterTr&   start_with_retrievalr   r)   c                 C     dgS )r*   r,   r!   r.   r!   r!   r"   r0   d      zFlareChain.input_keysc                 C  ra   )zOutput keys for the chain.r   r!   r.   r!   r!   r"   output_keysi   rb   zFlareChain.output_keys	questionsr,   strr   _run_managerr	   Tuple[str, bool]c                 C  s~   |  }g }|D ]}|| j| qddd |D }| j|||dd|i}	t|	tr3|	j}	| j	
|	\}
}|
|fS )Nz

c                 s  s    | ]}|j V  qd S N)page_content)rB   dr!   r!   r"   	<genexpr>y   s    z,FlareChain._do_generation.<locals>.<genexpr>r+   	callbacks)	get_childextendr[   invokerI   rX   
isinstancer   r   rZ   parse)r/   rd   r,   r   rf   rl   docsquestionr-   resultmarginalfinishedr!   r!   r"   _do_generationn   s    
zFlareChain._do_generationlow_confidence_spansinitial_responsec           
        s    fdd|D }|  }tjtr&jj||d}fdd|D }	n
jj|d|id}	|jd|	 dd	d
 |	||S )Nc                   s   g | ]} |d qS ))r,   current_responseuncertain_spanr!   )rB   span)ry   r,   r!   r"   rE      s    z,FlareChain._do_retrieval.<locals>.<listcomp>)rl   c                   s   g | ]
}| j jd   qS )r   )rW   rc   )rB   outputr.   r!   r"   rE      s    rl   )configzGenerated Questions: yellow
colorrK   )rm   rp   rW   r   applybatchon_textrw   )
r/   rx   rf   r,   r   ry   question_gen_inputsrl   question_gen_outputsrd   r!   )ry   r/   r,   r"   _do_retrieval   s$   
zFlareChain._do_retrievalNinputsDict[str, Any]run_manager$Optional[CallbackManagerForChainRun]c                 C  s  |pt  }|| jd  }d}t| jD ]g}|jd| ddd |d|d}t| j|d|	 i\}}	t
||	| j| j| j}
| d	 d| }|
sd|}| j|\}}|rc| jd |i  S q| |
||||\}}| d	 | }|r{ nq| jd |iS )
Nr   rH   zCurrent Response: bluer   r   r+   rl    )r	   get_noop_managerr0   ranger_   r   r#   rX   ro   rm   rU   r;   r=   r?   striprI   rZ   rq   rc   r   )r/   r   r   rf   r,   r   rC   _inputr   r    rx   ry   final_responserv   ru   r!   r!   r"   _call   sN   zFlareChain._call    llmr
   max_generation_lenkwargsr   c                 K  s`   zddl m} W n ty   tdw ||ddd}t|B }t|B t B }| d||d|S )	aH  Creates a FlareChain from a language model.

        Args:
            llm: Language model to use.
            max_generation_len: Maximum length of the generated response.
            kwargs: Additional arguments to pass to the constructor.

        Returns:
            FlareChain class with the given language model.
        r   )
ChatOpenAIz_OpenAI is required for FlareChain. Please install langchain-openai.pip install langchain-openaiT)max_completion_tokensr   temperature)rW   rX   Nr!   )langchain_openair   ImportErrorr   r   r   )r'   r   r   r   r   rX   question_gen_chainr!   r!   r"   from_llm   s$   zFlareChain.from_llmr1   )
rd   r)   r,   re   r   re   rf   r	   r   rg   )rx   r)   rf   r	   r,   re   r   re   ry   re   r   rg   rh   )r   r   r   r   r   r   )r   )r   r
   r   r>   r   r   r   rV   )r2   r3   r4   r5   r6   r   r   rZ   r;   r=   r?   r_   r`   r8   r0   rc   rw   r   r   r7   r   r!   r!   r!   r"   rV   J   s>   
 

%0rV   )r   r   r   r   )r   r9   r    r:   r;   r<   r=   r>   r?   r>   r   r)   )(
__future__r   r@   typingr   r   r   r   r   r   numpyrL   langchain_core.callbacksr	   langchain_core.language_modelsr
   langchain_core.messagesr   langchain_core.output_parsersr   langchain_core.promptsr   langchain_core.retrieversr   langchain_core.runnablesr   pydanticr   langchain.chains.baser   langchain.chains.flare.promptsr   r   r   langchain.chains.llmr   r#   r$   rU   rV   r!   r!   r!   r"   <module>   s&     


