o
    }!gk;                     @   sr  d dl Z d dlZd dl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mZmZmZmZmZ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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l0m1Z1 dd Z2dZ3de4fddZ5d dee4 de4fddZ6G dd de'Z7G dd deZ8dS )!    N)ArgumentParser)iglob)Path)AnyCallableDictListOptionalUnioncast)SettingsSimpleDirectoryReaderVectorStoreIndex)BaseEmbedding)RESPONSE_TYPEResponseStreamingResponse)	BaseModelFieldfield_validator)CondenseQuestionChatEngine)IngestionPipeline)LLM)CustomQueryEngine)FnComponent)QueryPipeline)
BaseReader)CompactAndRefine)get_cache_dirc                  C   s2   zddl m}  | dddW S  ty   tdw )Nr   OpenAIzgpt-3.5-turboT)model	streamingz]`llama-index-llms-openai` package not found, please run `pip install llama-index-llms-openai`)llama_index.llms.openair    ImportErrorr    r%   Z/mnt/skqttb/ctump_chatbot/chatbot/lib/python3.10/site-packages/llama_index/cli/rag/base.py_try_load_openai_llm!   s   r'   zfiles_history.txtreturnc                   C   s   t tt d S )Nrag_cli)strr   r   r%   r%   r%   r&   default_ragcli_persist_dir0   s   r+   	query_strc                 C   s   | pdS )N r%   r,   r%   r%   r&   query_input4   s   r/   c                   @   sD   e Zd ZU eddZeed< dedefddZ	dedefdd	Z
d
S )QueryPipelineQueryEngineQuery Pipeline to use for Q&A.descriptionquery_pipeliner,   r(   c                 C   s   | j j|dS Nr.   )r4   runselfr,   r%   r%   r&   custom_query=   s   z%QueryPipelineQueryEngine.custom_queryc                    s   | j j|dI d H S r5   )r4   arunr7   r%   r%   r&   acustom_query@   s   z&QueryPipelineQueryEngine.acustom_queryN)__name__
__module____qualname__r   r4   r   __annotations__r*   r   r9   r;   r%   r%   r%   r&   r0   8   s   
 r0   c                   @   s  e Zd ZU dZeddZeed< edddZe	ed< ed	e
d
Zeed< eddd d
Zeed< edddZee ed< edddZee ed< edddZeeeef  ed< G dd dZeddddedeeef dee fddZeddddedeeef dee fdd Z						d3d!eee  d"ee d#e	de	d$e	d%e	d&eeef ddfd'd(Zd"eddfd)d*Zd4d+d,Ze d-e!e"ef d.ee#g d f  ddfd/d0Z$d4d1d2Z%dS )5RagCLIzW
    CLI tool for chatting with output of a IngestionPipeline via a QueryPipeline.
    z,Ingestion pipeline to run for RAG ingestion.r2   ingestion_pipeline:Whether to print out verbose information during execution.F)r3   defaultverbosez(Directory to persist ingestion pipeline.)r3   default_factorypersist_dirz.Language model to use for response generation.c                   C   s   t  S N)r'   r%   r%   r%   r&   <lambda>V   s    zRagCLI.<lambda>llmr1   Nr4   z Chat engine to use for chatting.chat_enginez5File extractor to use for extracting text from files.file_extractorc                   @   s   e Zd ZdZdS )zRagCLI.ConfigTN)r<   r=   r>   arbitrary_types_allowedr%   r%   r%   r&   Confige   s    rM   before)modevaluesr(   c                 C   s   |dur|S t t|d }|jdu rdS t t|d }ttddhd}t t|d }d}|jdur@|jD ]}t|t	r?|} nq4|t
_|t
_t|jjdd	}	td
|d}
t|d}|||	|
d |dd |jdddd |jdddd |S )zX
        If query_pipeline is not provided, create one from ingestion_pipeline.
        NrA   rD   outputr,   )fn
output_key
req_paramsrI      )similarity_top_kT)r"   rD   )rD   )query	retriever
summarizerrW   rX   rY   nodes)dest_key)r   r   vector_storeboolr   r/   r   transformations
isinstancer   r   rI   embed_modelr   from_vector_storeas_retrieverr   r   add_modulesadd_link)clsr4   rP   rA   rD   query_componentrI   r`   transformationrX   response_synthesizerr%   r%   r&   &query_pipeline_from_ingestion_pipelineh   sH   




z-RagCLI.query_pipeline_from_ingestion_pipelinec                 C   s|   |dur|S | ddu r| jd|d|d< tt|d }|du r#dS t|d}tt|d }tt|d }tj|||dS )zQ
        If chat_engine is not provided, create one from query_pipeline.
        Nr4   )r4   rP   )r4   rD   rI   )query_enginerI   rD   )	getri   r   r   r0   r]   r   r   from_defaults)re   rJ   rP   r4   rj   rD   rI   r%   r%   r&   chat_engine_from_query_pipeline   s   

z&RagCLI.chat_engine_from_query_pipelinefilesquestionchatclearcreate_llamakwargsc                    s  |r2t j| jr*td| j d}|  dkr!td dS t d| j  td| j  || _	t
t| j}	| j	rDtd| j |durg }
|D ]}|
t|d	d
 qLg }|
D ])}t j|}t j|rst|d	| jd}n	t|gd	| jd}||j|d q\|	j||dI dH  |	j| jd t| j dt d}|D ]}|t|d  qW d   n1 sw   Y  |rYtddu rtd nt| j dt }| std nwt|}dd |D }W d   n1 sw   Y  t|dkr	td nPt|dkrtd nD| }d|v r#td n6t j|s3td| d n&td| d  dd!d"d#d$d%d&d'd(d)d*d+d,d-t | g}t d.!| |durf| "|I dH  |rr| # I dH  dS dS )/z=
        Entrypoint for local document RAG CLI tool.
        z,Are you sure you want to delete data within z? [y/N] yzAborted.Nzrm -rf zSuccessfully cleared z!Saving/Loading from persist_dir: T)	recursive)	input_dirfilename_as_idrK   )input_filesrw   rK   )show_progress)ry   	documents)rF   /a
npxzI`npx` is not installed. Please install it by calling `npm install -g npx`zLNo data has been ingested, please specify `--files` to create llama dataset.c                 S   s   h | ]
}|  r|  qS r%   )strip).0liner%   r%   r&   	<setcomp>   s    z$RagCLI.handle_cli.<locals>.<setcomp>r      zMultiple files or folders were ingested, which is not supported by create-llama. Please call `llamaindex-cli rag --clear` to clear the cache first, then call `llamaindex-cli rag --files` again with a single folder or file*zGlob pattern is not supported by create-llama. Please call `llamaindex-cli rag --clear` to clear the cache first, then call `llamaindex-cli rag --files` again with a single folder or file.z	The path z does not exist. Please call `llamaindex-cli rag --clear` to clear the cache first, then call `llamaindex-cli rag --files` again with a single folder or file.z%Calling create-llama using data from z ...zcreate-llama@latestz
--frontendz
--templater"   z--frameworkfastapiz--uishadcnz--vector-dbnonez--enginecontextz--files  )$ospathexistsrF   inputr   lowerprintsystemrD   r   r   rA   extendr   abspathisdirr   rK   	load_datar:   persistopenRAG_HISTORY_FILE_NAMEwriter*   shutilwhichr   lenpopshlexquotejoinhandle_questionstart_chat_repl)r8   rn   ro   rp   rD   rq   rr   rs   responserA   expanded_filespatternrz   _filereaderffilehistory_file_pathstored_pathsr   command_argsr%   r%   r&   
handle_cli   s   



zRagCLI.handle_clic                    sj   | j d u r
tdtt| j }| j|_tt| j}||}t|t	r*|
  d S tt|}t| d S )Nquery_pipeline is not defined.)r4   
ValueErrorr   r   rD   r   rJ   rp   r_   r   print_response_streamr   r   )r8   ro   r4   rJ   r   r%   r%   r&   r   /  s   



zRagCLI.handle_questionc                    s,   | j du r
tdtt| j}|  dS )z;
        Start a REPL for chatting with the agent.
        Nr   )r4   r   r   r   rJ   streaming_chat_repl)r8   rJ   r%   r%   r&   r   =  s
   
zRagCLI.start_chat_replparserinstance_generatorc                    s    rE|j ddtddd |j ddtdd	d
 |j ddddd |j ddddd |j dddd |j ddddd |j fddd d S d S )Nz-qz
--questionzThe question you want to ask.F)typehelprequiredz-fz--files+zuThe name of the file(s) or directory you want to ask a question about,such as "file.pdf". Supports globs like "*.py".)r   nargsr   z-cz--chatz&If flag is present, opens a chat REPL.
store_true)r   actionz-vz	--verboserB   z--clearz'Clears out all currently embedded data.z--create-llamaz8Create a LlamaIndex application with your embedded data.)r   r   r   c                    s   t   jdi t| S )Nr%   )asyncior6   r   vars)argsr   r%   r&   rH   w  s    z(RagCLI.add_parser_args.<locals>.<lambda>)func)add_argumentr*   set_defaults)re   r   r   r%   r   r&   add_parser_argsF  sT   


zRagCLI.add_parser_argsc                    sR   t dd}|jdddd}|jddd	} | fd
d | }|| dS )z*
        Entrypoint for CLI tool.
        zLlamaIndex RAG Q&A tool.r2   commandscommandT)titledestr   ragz8Ask a question to a document / a directory of documents.)r   c                      s    S rG   r%   r%   r8   r%   r&   rH     s    zRagCLI.cli.<locals>.<lambda>N)r   add_subparsers
add_parserr   
parse_argsr   )r8   r   
subparsersllamarag_parserr   r%   r   r&   cli|  s   
z
RagCLI.cli)NNFFFF)r(   N)&r<   r=   r>   __doc__r   rA   r   r?   rD   r]   r+   rF   r*   rI   r   r4   r	   r   rJ   r   rK   r   r   rM   r   r   ri   rm   r   r   r   r   classmethodr
   r   r   r   r   r%   r%   r%   r&   r@   D   s   
 


0


	
}
	
5r@   rG   )9r   r   r   r   argparser   globr   pathlibr   typingr   r   r   r   r	   r
   r   llama_index.corer   r   r   %llama_index.core.base.embeddings.baser   %llama_index.core.base.response.schemar   r   r    llama_index.core.bridge.pydanticr   r   r   llama_index.core.chat_enginer   llama_index.core.ingestionr   llama_index.core.llmsr   llama_index.core.query_enginer   3llama_index.core.query_pipeline.components.functionr   %llama_index.core.query_pipeline.queryr   llama_index.core.readers.baser   &llama_index.core.response_synthesizersr   llama_index.core.utilsr   r'   r   r*   r+   r/   r0   r@   r%   r%   r%   r&   <module>   s6    $