o
    g^/                     @   s   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mZ d dl	m
Z
 d dlmZ d dlmZ ejd d d	lmZmZ d d
lmZ e  e ZG dd dZedkrhedddZe Zee dS dS )    N)datetime)load_dotenv)AgentExecutorcreate_tool_calling_agent)ChatPromptTemplate)tool)
ChatOpenAI.)OPENAI_MODEL_4OOPENAI_MODEL_MINI)PerplexityResearchc                	   @   s   e Zd ZdZeededdZeede	ddZ
edZdZdZd	Zi Z	
d!dedefddZdd Zdd ZdedefddZeed"dedefddZeed"dededefddZeed"dedefddZeed"dedefdd Zd
S )#
Researcherzresearcher classOPENAI_API_KEYg?)api_keymodeltemperatureg      ?PERPLEXITY_KEY   i     Nparent_questionpersonac                 C   sD   || _ |r|nd| _|| _|r|  nd| _ttds dt_dS dS )zinitialize the class Nresearch_text_combined)initial_questionprimary_researchpersona_inputbuild_personapersona_extendedhasattrthread_local_datar   )selfr   r   r    r!   :/var/www/html/XCapMarket/utils/researcher/researcher_v2.py__init__*   s   

zResearcher.__init__c                 C   s4   t ddd| j dfdg}|| jB }|i jS )N)systemz]You are a skillful LLM user and understand how to create personas to the best of your abilityhumanzBuild a persona for z1. This should include a system prompt for an LLM.)r$   z!Only return the persona as string)r   from_messagesr   llm4oinvokecontent)r    promptchainr!   r!   r"   r   7   s   
zResearcher.build_personac                 C   s   | j rdd| j  fgng }|ddddddd	d
ddddt d fdd| j dfdg7 }| j| j| j| jg}t	|| j
t|d}t||dd}|i d }| | jtj}t jd| j d| 7  _tjS )Nr$   zYour persona is: )r$   zfYou have access to tools which allow you to search the web, verify research, and fill out the research)r$   zGYou should use the tools and your own knowledge to answer the question.)r$   zDFor complex questions, you should use the create research plan tool.)r$   zJIf you use the web search tool, then you must use the verify research tool)r$   zMIf the research is not complete, then you must use the fill out research tool)r$   z/Make sure to return the citations when provided)r$   zB*** Before you provide an answer, you must verify the research ***)r%   zQYou are not allowed to exit the chain without providing the research and answers.)r$   zJWhen you pass in the persona, you should make it at least 100 tokens long.)r$   zWhen you use the web search tool, make your questions as specific as you can. Get the most relevant information and up to date information.zToday's date is: z%Y-%m-%dr%   z)The question you are going to answer is: z/. You must use the tools to answer the question)r$   z{agent_scratchpad})toolsllmr*   T)agentr,   verboseoutputz

 # Final Output for:  
 )r   r   nowstrftimer   
web_searchverify_researchfill_out_researchcreate_research_planr   llm4r   r&   r   r(   summarize_researchr   r   )r    messagesr,   r.   agent_executorresearchr!   r!   r"   conduct_researchH   sP   /zResearcher.conduct_researchr   r<   c                 C   sB   ddg}| d | d t|}|tjB }|||djS )Create a research plan.

        Args:
            question (str): The question to create a research plan for.
            persona (str, optional): The persona to use. Defaults to None.

        Returns:
            str: The research plan.
        )r$   z\You are going to be provided with a question and associated research to answer the question.)r$   zhYou need to understand the research and then answer how the question can be answered using the research.)r%   z9The question you are trying to answer: {initial_question})r%   z+The research you have access to: {research}r   r<   appendr   r&   r   r'   r(   r)   )r    r   r<   r:   r*   r+   r!   r!   r"   r9      s   



zResearcher.summarize_researchquestionc              
   C   s   z8t  }dg}|r|d|f |d| f ||}||}ttds)dt_t jd|  d| 7  _|W S  tyO } zt| W Y d}~d	S d}~ww )
a5  Search the web for information.

        Args:
            question (str): The question to search for.
            persona (str, optional): The persona to use. Defaults to None.

        Returns:
            answer (dict): The answer to the question.
                answer: str, citations: list(url)
        )r$   z!You are a helpful research agent.r$   r%   r   r   z

 # r1   Nz?This search was unsuccessful, you can try a different question.)	r   rA   ask_perplexitypretty_printr   r   r   	Exceptionprint)rB   r   perplexity_researchr:   responseresponse_prettyer!   r!   r"   r4      s&   


zResearcher.web_searchc                 C   sh   g d}|r| d|f | dd|  f | dd| f t|}|tjB }|| |djS )as  Verify the research.

        Args:
            initial_question (str): The question to verify the research for.
            research (str): The research to verify.
            persona (str, optional): The persona to use. Defaults to None.

        Returns:
            str: The verification of the research. True or False and if False, an explanation as to why.
        ))r$   zJYou are going to be tasked with verifying a piece of research is complete.)r$   z?Your goal is to determine if the research answers the question.)r$   zGYou will respond with True or False and if False, you will explain why.)r$   ziIf you think the question can be answered more completely, then you should respond False and explain why.r$   r%   z#The question you are answering is: z#The research you are verifying is: r?   r@   )r   r<   r   r:   r*   r+   r!   r!   r"   r5      s   

zResearcher.verify_researchlacking_researchc                 C   sR   g d}|r| d|f | dd|  f t|}|tjB }|d| ijS )a#  fill out the research

        This tool takes in the research that is currently lacking and fills it out with
        additional information. The tool should respond with a list of questions that
        can be asked to an LLM with sufficient information to get the correct answer.
        ))r$   zPYou will be provided with what the research is missing and you will fill it out.)r$   zaYou should respond in such a way that another LLM can use the information to answer the question.r$   z{You will respond with a list of questions that can be asked to an LLM with sufficient information to get the correct answerr$   r%   z;The current research is missing the following information: rK   r@   )rK   r   r:   r*   r+   r!   r!   r"   r6      s   	

zResearcher.fill_out_researchc                 C   s^   g d}|r| d|f | dd|  f t|}|tjB }|d| ij}d| dS )r>   ))r$   zhYou are going to be provided with a question and you will create a research plan to answer the question.)r$   zSYou should respond with a step by step plan to comprehensively answer the question.rL   r$   r%   zThe question is: rB   zThe research plan is: zG. YOu are now ready to use the web research tool to answer the questionr@   )rB   r   r:   r*   r+   chain_outputr!   r!   r"   r7   "  s   

zResearcher.create_research_plan)NNN)N)__name__
__module____qualname____doc__r   osgetenvr   r'   r
   r8   perplexity_keymax_number_of_questionssummary_token_limitmax_follow_up_levellinks_researchedstrr#   r   r=   r9   staticmethodr   r4   r5   r6   r7   r!   r!   r!   r"   r      sD    

L*!r   __main__z=What is the TAM for the Contract Lifecycle Management market?zIndustry analyst)r   r   )rR   sys	threadingr   dotenvr   langchain.agentsr   r   langchain.promptsr   langchain.toolsr   langchain_openair   pathrA   configs.configr
   r   utils.researcher.perplexityr   localr   r   rN   rr=   resultsrF   r!   r!   r!   r"   <module>   s2      1