
    Zǻi%                        d dl mZ d dlZd dlZd dlmZmZmZmZ d dl	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mZ d d	lmZ d d
lmZ d dlmZ d dlmZmZ d dl m!Z!  ejD                  e#      Z$ G d d      Z%y)    )annotationsN)AnyListOptionalUnion)ValidationError)RagInitializationErrorSearchValidationError)RagTemplate)RagInitModelRagResultModelRagSearchModel)LLMInterfaceLLMInterfaceV2)legacy_inputs_to_messages)MessageHistory)	Retriever)
LLMMessageRetrieverResult)prettifyc                      e Zd ZdZ e       f	 	 	 	 	 d	dZ	 	 	 	 	 	 d
	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 d	 	 	 	 	 ddZddZddZ	ddZ
y)GraphRAGa  Performs a GraphRAG search using a specific retriever
    and LLM.

    Example:

    .. code-block:: python

      import neo4j
      from neo4j_graphrag.retrievers import VectorRetriever
      from neo4j_graphrag.llm.openai_llm import OpenAILLM
      from neo4j_graphrag.generation import GraphRAG

      driver = neo4j.GraphDatabase.driver(URI, auth=AUTH)

      retriever = VectorRetriever(driver, "vector-index-name", custom_embedder)
      llm = OpenAILLM()
      graph_rag = GraphRAG(retriever, llm)
      graph_rag.search(query_text="Find me a book about Fremen")

    Args:
        retriever (Retriever): The retriever used to find relevant context to pass to the LLM.
        llm (LLMInterface, LLMInterfaceV2 or LangChain Chat Model): The LLM used to generate
            the answer.
        prompt_template (RagTemplate): The prompt template that will be formatted with context and
            user question and passed to the LLM.

    Raises:
        RagInitializationError: If validation of the input arguments fail.
    c                    	 t        |||      }|j                  | _        |j
                  | _        |j                  | _        y # t        $ r}t        |j                               d }~ww xY w)N)	retrieverllmprompt_template)r   r   r	   errorsr   r   r   )selfr   r   r   validated_dataes         `/opt/lhia/marcimex/agent/venv/lib/python3.12/site-packages/neo4j_graphrag/generation/graphrag.py__init__zGraphRAG.__init__K   sg    	5)# /N (11!%%-==	  	5(44	5s   A 	A+A&&A+Nc                v   |t        j                  dt               d}	 t        |||xs i ||      }t        |t              r|j                  }| j                  |j                  |      }	 | j                  j                  dd|	i|j                  }
t        |
j                         dk(  r||}nIdj#                  d |
j                   D              }| j$                  j'                  |||j(                  	      }t*        j-                  d
t/        |
             t*        j-                  d|       | j1                         r?t3        ||| j$                  j4                        }| j6                  j9                  |      }not        | j6                  t:              r3| j6                  j9                  ||| j$                  j4                        }n"t=        dt?        | j6                         d      |j@                  }d|i}|r|
|d<   tC        di |S # t        $ r}t        |j                               d}~ww xY w)au  
        .. warning::
            The default value of 'return_context' will change from 'False'
                to 'True' in a future version.


        This method performs a full RAG search:
            1. Retrieval: context retrieval
            2. Augmentation: prompt formatting
            3. Generation: answer generation with LLM


        Args:
            query_text (str): The user question.
            message_history (Optional[Union[List[LLMMessage], MessageHistory]]): A collection
                of previous messages, with each message having a specific role assigned.
            examples (str): Examples added to the LLM prompt.
            retriever_config (Optional[dict]): Parameters passed to the retriever.
                search method; e.g.: top_k
            return_context (bool): Whether to append the retriever result to the final result
                (default: False).
            response_fallback (Optional[str]): If not null, will return this message instead
                of calling the LLM if context comes back empty.

        Returns:
            RagResultModel: The LLM-generated answer.

        Nz]The default value of 'return_context' will change from 'False' to 'True' in a future version.F)
query_textexamplesretriever_configreturn_contextresponse_fallbackr$   r   
c              3  4   K   | ]  }|j                     y wN)content).0items     r!   	<genexpr>z"GraphRAG.search.<locals>.<genexpr>   s     PPs   )r$   contextr%   zRAG: retriever_result=%szRAG: prompt=%s)promptmessage_historysystem_instructioninput)r5   r2   r3   Type  of LLM is not supported.answerretriever_result )"warningswarnDeprecationWarningr   r   r
   r   
isinstancer   messages_build_queryr$   r   searchr&   lenitemsjoinr   formatr%   loggerdebugr   is_langchain_compatibler   system_instructionsr   invoker   
ValueErrortyper,   r   )r   r$   r2   r%   r&   r'   r(   r   r    queryr9   r8   r0   r1   r?   llm_responseresults                    r!   rA   zGraphRAG.search]   s'   J !MM2"
 #N		4+%!!1!7R-"3N o~6-66O!!.";";_M,ADNN,A,A -
-
 . ? ?-
 %%&!+0A0M&FiiP9I9O9OPPG))00%wAXAX 1 F LL3X>N5OPLL)62++-4!$3'+';';'O'O  $xx"  /   DHHl3#xx $3'+';';'O'O  /   !5dhh(88Q!RSS!))F"*F!3)9F%&'''Y  	4'
33	4s   H 	H8H33H8c                   d}|r| j                  |      }| j                         r4t        ||      }| j                  j	                  |      j
                  }ndt        | j                  t              r(| j                  j	                  ||      j
                  }n"t        dt        | j                         d      | j                  ||      S |S )	zGBuilds the final query text, incorporating message history if provided.zVYou are a summarization assistant. Summarize the given text in no more than 300 words.)r2   )r3   r4   )r5   r3   r6   r7   )summarycurrent_query)_chat_summary_promptrH   r   r   rJ   r,   r>   r   rK   rL   conversation_prompt)r   r$   r2   summary_system_messagesummarization_promptr?   rQ   s          r!   r@   zGraphRAG._build_query   s    B 	 #'#<#< / $= $  ++-4('= ((//" * '  DHHl3((//.'= *  ' 
 !5dhh(88Q!RSS++G:+VV    c                    t        | j                  t              ry	 ddlm} t        | j                  |      S # t
        $ r Y yw xY w)z/Checks if the LLM is compatible with LangChain.Tr   )BaseChatModelF)r>   r   r   langchain_core.language_modelsrY   ImportError)r   rY   s     r!   rH   z GraphRAG.is_langchain_compatible   s>    dhh/	Ddhh66 		s   9 	AAc                n    |D cg c]  }|d    d|d     }}dj                  |      }d| dS c c}w )Nrolez: r,   r)   z!
Summarize the message history:

)rD   )r   r2   messagemessage_listhistorys        r!   rS   zGraphRAG._chat_summary_prompt   sb    FU
;Bwvr')"4!56
 
 ))L) 		 
 		
s   2c                    d| d| dS )Nz
Message Summary:
z

Current Query:
r)   r:   )r   rQ   rR   s      r!   rT   zGraphRAG.conversation_prompt   s'    	 
   	rW   )r   r   r   z(Union[LLMInterface, LLMInterfaceV2, Any]r   r   ) Nrb   NNN)r$   strr2   z1Optional[Union[List[LLMMessage], MessageHistory]]r%   rc   r&   zOptional[dict[str, Any]]r'   zOptional[bool]r(   zOptional[str]returnr   r+   )r$   rc   r2   zOptional[List[LLMMessage]]rd   rc   )rd   bool)r2   zList[LLMMessage]rd   rc   )rQ   rc   rR   rc   rd   rc   )__name__
__module____qualname____doc__r   r"   rA   r@   rH   rS   rT   r:   rW   r!   r   r   ,   s    D (3}	>> 6> %	>( MQ59)-+/a(a( Ka( 	a(
 3a( 'a( )a( 
a(L 7; 4 
	B	rW   r   )&
__future__r   loggingr;   typingr   r   r   r   pydanticr   neo4j_graphrag.exceptionsr	   r
   !neo4j_graphrag.generation.promptsr   neo4j_graphrag.generation.typesr   r   r   neo4j_graphrag.llmr   r   neo4j_graphrag.llm.utilsr   neo4j_graphrag.message_historyr   neo4j_graphrag.retrievers.baser   neo4j_graphrag.typesr   r   neo4j_graphrag.utils.loggingr   	getLoggerrf   rF   r   r:   rW   r!   <module>rx      s]   " #   - - % : X X ; > 9 4 < 1 
		8	$T TrW   