o
    Age+                     @   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                	   @   sd  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dedefddZdedee fddZ	d)dedee de	defdd Z	d)dedee de	defd!d"Z d#eee	f de!ee ee	 f fd$d%Z"d&ede!e#ef fd'd(Z$dS )*QueryPowerBIToolz%Tool for querying a Power BI Dataset.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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)promptinput_variables
ValueError)clsr&   r   var r0   m/var/www/html/development/chatbot/venv/lib/python3.10/site-packages/langchain_community/tools/powerbi/tool.py"validate_llm_chain_input_variables.   s   z3QueryPowerBITool.validate_llm_chain_input_variablesr(   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(   r0   r0   r1   _check_cache=   s   

zQueryPowerBITool._check_cacherun_managerkwargsc              
   K   s  |  | }rtd|| |S z td| | jj|| j | j | j	|r+|
 ndd}W n tyO } zd| | j|< | j| W  Y d}~S d}~ww |dkr^|| j|< | j| S td| t }| jj|d}t }	td	| td
|	| d | |\}
}|durd|v rd| j|< | j| S |dd}|r|| jk r| 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(   r5   rD   rG   )r4   loggerdebuginfor   predictr   get_table_namesget_schemasr   	get_child	Exceptionr   r   run_parse_outputgetr   _runr   formatr   r3   r(   r5   r6   cacherF   exc
start_time
pbi_resultend_timeresultrG   rD   r0   r0   r1   rV   F   sV   



	
zQueryPowerBITool._runc              
      s  |  | }rtd|| | dS z#td| | jj|| j | j | j	|r/|
 nddI dH }W n tyV } zd| | j|< | j| W  Y d}~S d}~ww |dkre|| j|< | j| S td| t }| jj|d	I dH }t }	td
| td|	| d | |\}
}|durd|v sd|v rd| 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 )r7   r8   z3, from cache, you have already asked this question.r9   Nr:   r<   r=   zPBI Query: %sr>   r@   rA   rB   rC   
TokenErrorzkAuthentication token expired or invalid, please try to reauthenticate or check the scope of the credential.rD   r   rE   rH   rI   rJ   )r4   rK   rL   rM   r   apredictr   rO   rP   r   rQ   rR   r   r   arunrT   rU   r   _arunr   rW   r   rX   r0   r0   r1   rb   |   sX   



	
zQueryPowerBITool._arunr\   c                 C   s   d|v r:|d d d d d }t |dkrtd dS t|}| |\}}|r6d| d| j d	d
fS |d
fS d|v r`d|d v rZd|d d v rZd
|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.NrG   z	pbi.errordetailsdetail)lenrK   rM   r   _result_too_larger    )r3   r\   rd   r^   too_longlengthr0   r0   r1   rT      s$   
zQueryPowerBITool._parse_outputr^   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   encoding_for_modelrg   encoderK   rM   r    )r3   r^   	tiktoken_encodingrj   r0   r0   r1   rh      s   z"QueryPowerBITool._result_too_large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   classmethodr2   r4   r   rV   r   rb   r   rT   boolrh   r0   r0   r0   r1   r      s`   
 
9
6

r   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dedee defddZ	
ddedee defddZd
S )InfoPowerBIToolz2Tool for getting metadata about a PowerBI Dataset.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"   Nr(   r5   r'   c                 C   s   | j |dS )z4Get the schema for tables in a comma-separated list., )r   get_table_infosplitr3   r(   r5   r0   r0   r1   rV      s   zInfoPowerBITool._runc                    s   | j |dI d H S )Nr}   )r   aget_table_infor   r   r0   r0   r1   rb      s   zInfoPowerBITool._arunro   rp   rq   rr   rs   r   rt   ru   r   r   r   r   r
   rx   r   r   rV   r   rb   r0   r0   r0   r1   r{      s0   
 
r{   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dee dee defddZ	
	
ddee dee defddZd
S )ListPowerBIToolzTool for getting tables names.list_tables_powerbir   zUInput is an empty string, output is a comma separated list of tables in the database.r   Tr   r   r"   Nr(   r5   r'   c                 C   s   d | j S zGet the names of the tables.r}   joinr   rO   r   r0   r0   r1   rV     s   zListPowerBITool._runc                    s   d | j S r   r   r   r0   r0   r1   rb     s   zListPowerBITool._arun)NNr   r0   r0   r0   r1   r      s4   
 

r   )!rs   loggingtimer   typingr   r   r   r   langchain_core.callbacksr   r   langchain_core.toolsr	   pydanticr
   r   r   &langchain_community.chat_models.openair   (langchain_community.tools.powerbi.promptr   r   r   %langchain_community.utilities.powerbir   r   	getLoggerrp   rK   r   r{   r   r0   r0   r0   r1   <module>   s    
 C 