U
    h-                      @  s   d 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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 dd
lmZ ddlmZ ddlmZmZ erddlmZ dZG dd deZ dS )z2Chain for interacting with Elasticsearch Database.    )annotations)TYPE_CHECKINGAnyDictListOptional)CallbackManagerForChainRun)BaseLanguageModel)BaseOutputParserStrOutputParser)SimpleJsonOutputParser)BasePromptTemplate)root_validator)Runnable)Chain)ANSWER_PROMPT
DSL_PROMPT)Elasticsearchintermediate_stepsc                
   @  sJ  e Zd ZU dZded< 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< dZ
ded< dZded< G dd dZeddddddddZed d!d"d#Zed d!d$d%Zd d!d&d'Zd dd(d)d*Zd ddd+d,d-Zd=d.d/d.d0d1d2Zedd!d3d4Zed
d
d
d5d6d7d8d8d9dd d:d;d<Zd
S )>ElasticsearchDatabaseChaina  Chain for interacting with Elasticsearch Database.

    Example:
        .. code-block:: python

            from langchain.chains import ElasticsearchDatabaseChain
            from langchain_community.llms import OpenAI
            from elasticsearch import Elasticsearch

            database = Elasticsearch("http://localhost:9200")
            db_chain = ElasticsearchDatabaseChain.from_llm(OpenAI(), database)
    r   query_chainanswer_chainr   database
   inttop_kNzOptional[List[str]]ignore_indicesinclude_indicesZquestionstr	input_keyresult
output_key   sample_documents_in_index_infoFboolreturn_intermediate_stepsc                   @  s   e Zd ZdZdZdS )z!ElasticsearchDatabaseChain.ConfigTZforbidN)__name__
__module____qualname__Zarbitrary_types_allowedextra r*   r*   P/tmp/pip-unpacked-wheel-bo69hh5q/langchain/chains/elasticsearch_database/base.pyConfig6   s   r,   T)preZskip_on_failuredict)valuesreturnc                 C  s   |d r|d rt d|S )Nr   r   z;Cannot specify both 'include_indices' and 'ignore_indices'.)
ValueError)clsr/   r*   r*   r+   validate_indices:   s
    z+ElasticsearchDatabaseChain.validate_indicesz	List[str])r0   c                 C  s   | j gS )z?Return the singular input key.

        :meta private:
        )r   selfr*   r*   r+   
input_keysB   s    z%ElasticsearchDatabaseChain.input_keysc                 C  s   | j s| jgS | jtgS dS )z@Return the singular output key.

        :meta private:
        N)r%   r!   INTERMEDIATE_STEPS_KEYr4   r*   r*   r+   output_keysJ   s    z&ElasticsearchDatabaseChain.output_keysc                   sN   dd  j jjddD } jr2 fdd|D } jrJ fdd|D }|S )Nc                 S  s   g | ]}|d  qS indexr*   .0r:   r*   r*   r+   
<listcomp>V   s    z<ElasticsearchDatabaseChain._list_indices.<locals>.<listcomp>jsonformatc                   s   g | ]}| j kr|qS r*   )r   r<   ir4   r*   r+   r=   [   s     
 c                   s   g | ]}| j kr|qS r*   )r   rA   r4   r*   r+   r=   ]   s     
 )r   catindicesr   r   )r5   Zall_indicesr*   r4   r+   _list_indicesU   s    z(ElasticsearchDatabaseChain._list_indices)rD   r0   c                   s   | j jjd|d | jdkr  D ]X\}}| j j|di i| jdd d }dd |D }t|d	 d
| d  | d< q(d fdd D S )N,r9   r   Z	match_all)r:   querysizehitsc                 S  s   g | ]}t |d  qS )_source)r   )r<   hitr*   r*   r+   r=   j   s     zAElasticsearchDatabaseChain._get_indices_infos.<locals>.<listcomp>z

/*

z
*/mappingsz

c                   s    g | ]}d  | | d qS )zMapping for index {}:
{}rM   r?   r;   rM   r*   r+   r=   m   s   )r   rD   Zget_mappingjoinr#   itemssearchr   )r5   rD   kvrI   r*   rN   r+   _get_indices_infosa   s&    
$
z-ElasticsearchDatabaseChain._get_indices_infos)rD   rG   r0   c                 C  s   | j jd||d}t|S )NrF   )r:   body)r   rQ   rO   r   )r5   rD   rG   r    r*   r*   r+   _searchs   s    z"ElasticsearchDatabaseChain._searchzDict[str, Any]z$Optional[CallbackManagerForChainRun])inputsrun_managerr0   c              
   C  s  |p
t  }|| j  d}|j|| jd |  }| |}|t| j|dgd}g }z|	| | j
j|d| id}	|j|	d| jd |	|	 |	d	|	i | j||	d
}
|	t|
 |jd| jd |j|
d| jd |jd| jd |
|d}|	| | jj|d| id}|	| |j|d| jd | j|i}| jrX||t< |W S  tk
r } z||_|W 5 d }~X Y nX d S )Nz	
ESQuery:)verbosez

ESResult:)inputr   indices_infostop	callbacks)configZgreen)colorrY   es_cmd)rD   rG   z
ESResult: Zyellowz
Answer:)datarZ   )r   Zget_noop_managerr   Zon_textrY   rE   rT   r   r   appendr   ZinvokeZ	get_childrV   r   r!   r%   r7   	Exceptionr   )r5   rW   rX   Z_run_managerZ
input_textrD   r[   Zquery_inputsr   r`   r    Zanswer_inputsZfinal_resultZchain_resultexcr*   r*   r+   _callw   sT    







z ElasticsearchDatabaseChain._callc                 C  s   dS )NZelasticsearch_database_chainr*   r4   r*   r*   r+   _chain_type   s    z&ElasticsearchDatabaseChain._chain_type)query_promptanswer_promptquery_output_parserr	   r   zOptional[BasePromptTemplate]zOptional[BaseOutputParser])llmr   rg   rh   ri   kwargsr0   c          	      K  sJ   |pt }|pt }||B |B }|p$t}||B t B }| f |||d|S )a)  Convenience method to construct ElasticsearchDatabaseChain from an LLM.

        Args:
            llm: The language model to use.
            database: The Elasticsearch db.
            query_prompt: The prompt to use for query construction.
            answer_prompt: The prompt to use for answering user question given data.
            query_output_parser: The output parser to use for parsing model-generated
                ES query. Defaults to SimpleJsonOutputParser.
            kwargs: Additional arguments to pass to the constructor.
        )r   r   r   )r   r   r   r   )	r2   rj   r   rg   rh   ri   rk   r   r   r*   r*   r+   from_llm   s    
z#ElasticsearchDatabaseChain.from_llm)N)r&   r'   r(   __doc____annotations__r   r   r   r   r!   r#   r%   r,   r   r3   propertyr6   r8   rE   rT   rV   re   rf   classmethodrl   r*   r*   r*   r+   r      s<   


 7r   N)!rm   
__future__r   typingr   r   r   r   r   Zlangchain_core.callbacksr   Zlangchain_core.language_modelsr	   Zlangchain_core.output_parsersr
   r   Z"langchain_core.output_parsers.jsonr   Zlangchain_core.promptsr   Zlangchain_core.pydantic_v1r   Zlangchain_core.runnablesr   Zlangchain.chains.baser   Z/langchain.chains.elasticsearch_database.promptsr   r   Zelasticsearchr   r7   r   r*   r*   r*   r+   <module>   s   