a
    bge+                     @   s   d Z ddlZddlmZ ddl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mZ ddlmZ dd	lmZmZmZ dd
lmZmZ eeZG dd deZG dd deZG dd deZ dS )z.Tools for interacting with a Power BI dataset.    N)perf_counter)AnyDictOptionalTuple)AsyncCallbackManagerForToolRunCallbackManagerForToolRun)BaseTool)
ConfigDictFieldmodel_validator)_import_tiktoken)BAD_REQUEST_RESPONSEDEFAULT_FEWSHOT_EXAMPLESRETRY_RESPONSE)PowerBIDataset
json_to_mdc                   @   sL  e Zd ZU dZdZeed< dZeed< dZe	ed< e
dd	Zeed
< eZee ed< e
eddZeee	f ed< dZeed< dZeed< dZee ed< eddZeddeeedddZeee dddZd'eee e	edddZd(eee e	eddd Z eee	f e!ee ee	 f d!d"d#Z"ee!e#ef d$d%d&Z$dS ))QueryPowerBIToolz%Tool for querying a Power BI Dataset.Zquery_powerbinamea  
    Input to this tool is a detailed question about the dataset, output is a result from the dataset. It will try to answer the question using the dataset, and if it cannot, it will ask for clarification.

    Example Input: "How many rows are in table1?"
    descriptionN	llm_chainTexcludepowerbiexamples)default_factoryr   session_cache   max_iterationsi  output_token_limittiktoken_model_nameZarbitrary_types_allowedbefore)mode)valuesreturnc                 C   s0   |d }|j jD ]}|dvrtd|j jq|S )z8Make sure the LLM chain has the correct input variables.r   )
tool_inputtablesschemasr   zrLLM chain for QueryPowerBITool must have input variables ['tool_input', 'tables', 'schemas', 'examples'], found %s)promptZinput_variables
ValueError)clsr$   r   var r-   t/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_community/tools/powerbi/tool.py"validate_llm_chain_input_variables.   s    z3QueryPowerBITool.validate_llm_chain_input_variables)r&   r%   c                 C   s   || j vrdS | j | S )zCheck if the input is present in the cache.

        If the value is a bad request, overwrite with the escalated version,
        if not present return None.N)r   )selfr&   r-   r-   r.   _check_cache=   s    
zQueryPowerBITool._check_cache)r&   run_managerkwargsr%   c              
   K   s  |  | }r td|| |S z@td| | jj|| j | j | j	|rV|
 ndd}W n> ty } z&d| | j|< | j| W  Y d}~S d}~0 0 |dkr|| j|< | j| S td| t }| jj|d}t }	td	| td
|	| d | |\}
}|dur:d|v r:d| j|< | j| S |dd}|rx|| jk rx| jtj|||d||d dS |
r|
n
tj|d| j|< | j| S ):Execute the query, return the results or an error message.Found cached result for %s: %s%Running PBI Query Tool with input: %sNr&   r'   r(   r   	callbacksError on call to LLM: I cannot answer thiszPBI Query:
%scommandPBI Result: %sPBI Query duration: 0.6fTokenExpiredzCAuthentication token expired or invalid, please try reauthenticate.
iterationsr   r&   queryerror   r&   r2   rA   rD   )r1   loggerdebuginfor   Zpredictr   get_table_namesget_schemasr   	get_child	Exceptionr   r   run_parse_outputgetr   _runr   formatr   r0   r&   r2   r3   cacherC   exc
start_time
pbi_resultend_timeresultrD   rA   r-   r-   r.   rR   F   sR    
 


	zQueryPowerBITool._runc              
      s  |  | }r&td|| | dS zFtd| | jj|| j | j | j	|r\|
 nddI dH }W n> ty } z&d| | j|< | j| W  Y d}~S d}~0 0 |dkr|| j|< | j| S td| t }| jj|d	I dH }t }	td
| td|	| d | |\}
}|durVd|v sBd|v rVd| j|< | j| S |dd}|r|| jk r| jtj|||d||d dI dH S |
r|
n
tj|d| j|< | j| S )r4   r5   z3, from cache, you have already asked this question.r6   Nr7   r9   r:   zPBI Query: %sr;   r=   r>   r?   r@   
TokenErrorzkAuthentication token expired or invalid, please try to reauthenticate or check the scope of the credential.rA   r   rB   rE   rF   rG   )r1   rH   rI   rJ   r   Zapredictr   rK   rL   r   rM   rN   r   r   ZarunrP   rQ   r   _arunr   rS   r   rT   r-   r-   r.   r\   |   sR    
 


	zQueryPowerBITool._arun)rX   r%   c                 C   s   d|v rt|d d d d d }t |dkr:td dS t|}| |\}}|rld| d| j d	d
fS |d
fS d|v rd|d v rd|d d v rd
|d d d d d fS d
|d fS d
|fS )z2Parse the output of the query to a markdown table.resultsr   r'   rowsz%0 records in result, query was valid.)Nz^0 rows returned, this might be correct, but please validate if all filter values were correct?z[Result too large, please try to be more specific or use the `TOPN` function. The result is z tokens long, the limit is z tokens.NrD   z	pbi.errordetailsdetail)lenrH   rJ   r   _result_too_larger   )r0   rX   r^   rZ   Ztoo_longlengthr-   r-   r.   rP      s(    

zQueryPowerBITool._parse_output)rZ   r%   c                 C   sD   | j r@t }|| j }t||}td| || jk|fS dS )z!Tokenize the output of the query.zResult length: %s)Fr   )r    r   Zencoding_for_modelra   encoderH   rJ   r   )r0   rZ   Z	tiktoken_encodingrc   r-   r-   r.   rb      s    z"QueryPowerBITool._result_too_large)N)N)%__name__
__module____qualname____doc__r   str__annotations__r   r   r   r   r   r   r   r   r   dictr   r   r   intr   r    r
   model_configr   classmethodr/   r1   r   rR   r   r\   r   rP   boolrb   r-   r-   r-   r.   r      sJ   
 9 7
r   c                   @   sv   e Zd ZU dZdZeed< dZeed< eddZ	e
ed< edd	Zdeee edddZdeee edddZd
S )InfoPowerBIToolz2Tool for getting metadata about a PowerBI Dataset.Zschema_powerbir   z
    Input to this tool is a comma-separated list of tables, output is the schema and sample rows for those tables.
    Be sure that the tables actually exist by calling list_tables_powerbi first!

    Example Input: "table1, table2, table3"
    r   Tr   r   r!   Nr&   r2   r%   c                 C   s   | j |dS )z4Get the schema for tables in a comma-separated list., )r   Zget_table_infosplitr0   r&   r2   r-   r-   r.   rR      s    zInfoPowerBITool._runc                    s   | j |dI d H S )Nrs   )r   Zaget_table_infort   ru   r-   r-   r.   r\      s    zInfoPowerBITool._arun)N)Nrf   rg   rh   ri   r   rj   rk   r   r   r   r   r
   rn   r   r   rR   r   r\   r-   r-   r-   r.   rq      s&   
  rq   c                   @   s~   e Zd ZU dZdZeed< dZeed< eddZ	e
ed< edd	Zdee ee edddZdee ee edddZd
S )ListPowerBIToolzTool for getting tables names.Zlist_tables_powerbir   zUInput is an empty string, output is a comma separated list of tables in the database.r   Tr   r   r!   Nrr   c                 C   s   d | j S zGet the names of the tables.rs   joinr   rK   ru   r-   r-   r.   rR     s    zListPowerBITool._runc                    s   d | j S rx   ry   ru   r-   r-   r.   r\     s    zListPowerBITool._arun)NN)NNrv   r-   r-   r-   r.   rw      s*   
  
  rw   )!ri   loggingtimer   typingr   r   r   r   Zlangchain_core.callbacksr   r   Zlangchain_core.toolsr	   Zpydanticr
   r   r   Z&langchain_community.chat_models.openair   Z(langchain_community.tools.powerbi.promptr   r   r   Z%langchain_community.utilities.powerbir   r   	getLoggerrf   rH   r   rq   rw   r-   r-   r-   r.   <module>   s   
 C 