o
    Zh#                     @  s
  d dl mZ d dlZd dl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 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" e#e$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tokenZlogprob)Zresponse_metadataappend)r   tokens	log_probsr    r   R/var/www/html/lang_env/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_keys1   s   z!QuestionGeneratorChain.input_keysN)r   r$   r   r'   )__name__
__module____qualname____doc__r   r#   __annotations__classmethodr&   propertyr.   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  zdd l }|||k d }W n ty0   td dd l  fddt|D }Y nw fdd|D }t|dkrBg S |d |d | d gg}t|dd  D ] \}	}
|
| d }|
||	  |k rp||d d< qW|	|
|g qWfdd|D S )	Nr   a  NumPy not found in the current Python environment. FlareChain will use a pure Python implementation for internal calculations, which may significantly impact performance, especially for large datasets. For optimal speed and efficiency, consider installing NumPy: pip install numpyc                   s"   g | ]\}}  |k r|qS r   )exp).0idxZlog_prob)mathr9   r   r    
<listcomp>K   s
    z)_low_confidence_spans.<locals>.<listcomp>c                   s    g | ]}t d  | r|qS )z\w)research)r?   ir   r   r    rB   P   s        c                   s"   g | ]\}}d   || qS ) )join)r?   startendrF   r   r    rB   Z   s   " )
numpywherer>   ImportErrorloggerwarningrA   	enumeratelenr   )r   r   r9   r;   r=   npZ_low_idxZlow_idxspansrE   r@   rL   r   )rA   r9   r   r    _low_confidence_spans7   s,   
rV   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:   r9      r<   r;      r=   
   max_iterTr$   start_with_retrievalr   r'   c                 C     dgS )r(   r*   r   r,   r   r   r    r.   w      zFlareChain.input_keysc                 C  rb   )zOutput keys for the chain.r   r   r,   r   r   r    output_keys|   rc   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)Zpage_content)r?   dr   r   r    	<genexpr>   s    z,FlareChain._do_generation.<locals>.<genexpr>r)   	callbacks)	get_childextendr\   invokerJ   rY   
isinstancer   r   r[   parse)r-   re   r*   r   rg   rl   docsquestionr+   resultmarginalfinishedr   r   r    _do_generation   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*   Zcurrent_responseZuncertain_spanr   )r?   span)ry   r*   r   r    rB      s    z,FlareChain._do_retrieval.<locals>.<listcomp>)rl   c                   s   g | ]
}| j jd   qS )r   )rX   rd   )r?   outputr,   r   r    rB      s    rl   )configzGenerated Questions: yellow
colorrL   )rm   rp   rX   r   applybatchon_textrw   )
r-   rx   rg   r*   r   ry   Zquestion_gen_inputsrl   Zquestion_gen_outputsre   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   rI   zCurrent Response: bluer~   r   r)   rl    )r	   Zget_noop_managerr.   ranger`   r   r!   rY   ro   rm   rV   r9   r;   r=   striprJ   r[   rq   rd   r   )r-   r   r   rg   r*   r   rE   _inputr   r   rx   ry   Z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)Zmax_completion_tokensr   Ztemperature)rX   rY   Nr   )Zlangchain_openair   rO   r   r   r   )r%   r   r   r   r   rY   Zquestion_gen_chainr   r   r    from_llm   s$   zFlareChain.from_llmr/   )
re   r'   r*   rf   r   rf   rg   r	   r   rh   )rx   r'   rg   r	   r*   rf   r   rf   ry   rf   r   rh   ri   )r   r   r   r   r   r   )r   )r   r
   r   r<   r   r   r   rW   )r0   r1   r2   r3   r4   r   r   r[   r9   r;   r=   r`   ra   r6   r.   rd   rw   r   r   r5   r   r   r   r   r    rW   ]   s>   
 

%0rW   )r   r   r   r   )r   r7   r   r8   r9   r:   r;   r<   r=   r<   r   r'   )*
__future__r   loggingrC   typingr   r   r   r   r   r   Zlangchain_core.callbacksr	   Zlangchain_core.language_modelsr
   Zlangchain_core.messagesr   Zlangchain_core.output_parsersr   Zlangchain_core.promptsr   Zlangchain_core.retrieversr   Zlangchain_core.runnablesr   Zpydanticr   Zlangchain.chains.baser   Zlangchain.chains.flare.promptsr   r   r   Zlangchain.chains.llmr   	getLoggerr0   rP   r!   r"   rV   rW   r   r   r   r    <module>   s(     



&