o
    Ui=                     @   s   d Z ddlmZmZmZm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 ddlmZ dd	lmZ eeZG d
d dZdedededefddZdS )ze
Graph Enhanced Retrieval Service
Combines vector search with graph traversal for improved retrieval
    )ListDictAnyOptionalN)Session)settings)get_graph_query_service)get_graph_reranker)get_vector_store)get_embedding_factoryc                   @   sF  e Zd ZdZdededefddZ					
			d#dededede	e dede	e
e  dede
eeef  fddZdededede	e de
eeef  f
ddZde
e dede	e
e  de
eeef  fddZde
eeef  de
eeef  de
eeef  fddZded e
eeef  de	e de
eeef  fd!d"Zd	S )$GraphEnhancedRetrievalzZ
    Graph-enhanced retrieval service
    Combines vector recall with graph expansion
    dbknowledge_base_id	tenant_idc                 C   s:   || _ || _|| _t||| _t | _t | _t	 | _
d S )N)r   r   r   r
   vector_storer   embedding_factoryr   graph_query_servicer	   graph_reranker)selfr   r   r    r   Q/lsinfo/ai/hellotax_ai/base_platform/app/services/rag/graph_enhanced_retrieval.py__init__   s   zGraphEnhancedRetrieval.__init__   ffffff?N   Tqueryk	thresholdmodel_idexpand_depthrelation_typesenable_rerankreturnc              
   C   s   zV|  ||||}|std g W S ttdd |D }	tdt|	 d | |	||}
tdt|
 d | ||
}|rPt||krP| |||}|d| W S  t	yx } zt
d	|  |  ||||W  Y d}~S d}~ww )
a  
        Graph-enhanced retrieval

        Args:
            query: Query text
            k: Number of results to return
            threshold: Similarity threshold
            model_id: Vector model ID
            expand_depth: Graph expansion depth (1-2)
            relation_types: Relation types to follow
            enable_rerank: Enable reranking

        Returns:
            Retrieved and reranked results
        zNo vector results foundc                 S   s   g | ]}|d  qS )document_idr   ).0rr   r   r   
<listcomp>E   s    z3GraphEnhancedRetrieval.retrieve.<locals>.<listcomp>zVector recall returned z unique documentszGraph expansion added z neighbor documentsNz!Graph-enhanced retrieval failed: )_vector_recallloggerinfolistsetlen_graph_expansion_merge_results_rerank	Exceptionerror)r   r   r   r   r   r   r    r!   vector_resultsdoc_idsexpanded_docsall_resultser   r   r   retrieve!   s,   
zGraphEnhancedRetrieval.retrievec           
      C   s   | j j|| j|d}|sg S | jj||d |d}g }|D ]%\}}	||d |d |d |d |d |	d	|d
|ddd q|S )zVector recall from Milvus)textr   r      )query_embeddingr   r   idr#   titler8   chunk_indexvectorcategory_id
model_name)r?   r@   )r;   r#   r<   r8   r=   scoresourcemetadata)r   generate_embeddingr   r   similarity_searchappendget)
r   r   r   r   r   r:   resultsformatted_resultsdocrA   r   r   r   r'   ^   s6   
z%GraphEnhancedRetrieval._vector_recallr3   depthc                 C   s   t jsg S z9| jj|| j| jt|t j|dd}g }|D ]}||d |d |	dd|	ddd	|	d
di d q|W S  t
yZ } ztd|  g W  Y d}~S d}~ww )z&Expand neighbors using graph traversal   )document_idsr   kb_idrK   r    limitr;   r<   summary rA   g      ?graphrelation_typeunknown)r#   r<   r8   rA   rB   rS   rC   zGraph expansion failed: N)r   ENABLE_KNOWLEDGE_GRAPHr   expand_neighborsr   r   minGRAPH_EXPAND_DEPTHrF   rG   r0   r(   r1   )r   r3   rK   r    	neighborsformatted_neighborsneighborr6   r   r   r   r-      s8   






z'GraphEnhancedRetrieval._graph_expansionr2   graph_resultsc                 C   sb   i }|D ]
}|d }|||< q|D ]}|d }||vr|||< qt | }|jdd dd |S )z.Merge and deduplicate vector and graph resultsr#   c                 S      | d S NrA   r   xr   r   r   <lambda>       z7GraphEnhancedRetrieval._merge_results.<locals>.<lambda>Tkeyreverse)r*   valuessort)r   r2   r\   
result_mapresultdoc_idmerged_resultsr   r   r   r.      s   
z%GraphEnhancedRetrieval._merge_resultsrH   c              
   C   s   z| j j||| j| j| jd}|W S  tyM } z0td|  |D ]}|ddkr7t	|d d d|d< q#|j
dd	 d
d |W  Y d}~S d}~ww )z
        Rerank results based on vector similarity and graph features

        Args:
            query: Query text
            results: Results to rerank
            model_id: Vector model ID

        Returns:
            Reranked results
        )rH   r   r   rN   r   zGraph reranking failed: rB   rR   rA   g?g      ?c                 S   r]   r^   r   r_   r   r   r   ra      rb   z0GraphEnhancedRetrieval._rerank.<locals>.<lambda>Trc   N)r   rerankr   r   r   r0   r(   r1   rG   rW   rg   )r   r   rH   r   rerankedr6   ri   r   r   r   r/      s&   zGraphEnhancedRetrieval._rerank)r   r   Nr   NT)__name__
__module____qualname____doc__r   intr   strfloatr   r   boolr   r   r7   r'   r-   r.   r/   r   r   r   r   r      s|    
	
=
)

'
r   r   r   r   r"   c                 C   s   t | ||S )z-Get graph-enhanced retrieval service instance)r   )r   r   r   r   r   r   get_graph_enhanced_retrieval   s   rv   )rq   typingr   r   r   r   loggingsqlalchemy.ormr   
app.configr   app.services.graph.graph_queryr   !app.services.graph.graph_rerankerr	   )app.services.storage.vector_store_factoryr
   3app.services.llm.backends.embedding_backend_factoryr   	getLoggerrn   r(   r   rr   rv   r   r   r   r   <module>   s*    
 \