
    Xj;                        d dl mZ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 d dlmZmZ d dl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 d dlmZ d dlmZ  ee           Z! edg          Z" G d de          Z# G d de          Z$ G d de          Z%e"&                    d           ee           e ed                    fde'de#dedede
defd            Z(e")                    de$           ee           e ed                    fde'dede
defd             Z*e")                    d!          d"d#d$ ee           e ed                    fde'ded%e'd&e'd'e+d$z  de
defd(            Z,e")                    d)          d"d$d* ee           e ed                    fde'd+e'ded%e'd,e+d$z  d&e'de
defd-            Z-e")                    d.           ee           e ed                    fde'd+e'dede
def
d/            Z.e"&                    d0           ee           e ed                    fde'd1e%dede
def
d2            Z/d$S )3    )	APIRouterBackgroundTasksDependsHTTPExceptionRequest)	BaseModelField)Session)get_db)require_readrequire_write)settings)get_translator)KnowledgeBaseKnowledgeDocumentUser)get_graph_builder)get_graph_query_service)neo4j_client)
get_loggerzknowledge-graph)tagsc                   j    e Zd ZU  edd          Zeed<    edd          Zee	         dz  ed<   dS )GraphBuildRequestFu!   是否重建整个知识库图谱defaultdescriptionrebuildNu    指定文档ID列表（可选）document_ids)
__name__
__module____qualname__r	   r   bool__annotations__r   listint     B/lsinfo/ai/hellotax_ai/base_platform/app/api/v1/knowledge/graph.pyr   r      s[         E%5XYYYGTYYY%*U4Eg%h%h%hL$s)d"hhhhhr'   r   c                   ~    e Zd ZU eed<   eed<   eed<   eed<   eed<   eed<   eed<   eed<   eed	<   eed
<   eed<   dS )GraphStatsResponsekb_idgraph_statustotal_nodestotal_relationshipstotal_documentscompleted_documentstotal_entities	documentsentitiesr   
categoriesN)r   r    r!   r%   r#   strr&   r'   r(   r*   r*      s         JJJNNNMMM
IIIOOOOOr'   r*   c                       e Zd ZU  edd          Zeed<    edd          Zedz  ed<    ed	d
dd          Ze	ed<   dS )EntitySearchRequest.u   搜索关键词)r   queryNu   实体类型过滤r   entity_type      d   u   返回结果数量)r   geler   limit)
r   r    r!   r	   r8   r5   r#   r9   r?   r%   r&   r'   r(   r7   r7   '   sz         s(9:::E3:::#eD>RSSSKtSSSraC=QRRRE3RRRRRr'   r7   z/{base_id}/graph/buildknowledge_basesbase_idbuild_requestbackground_tasksrequestdbcurrent_userc                 l   t          |          }t          j        st          dd          |                    t
                                        t
          j        | k                                              }|s$t          d|	                    d                    	 t                      }|j        r|                    t                                        t          j                            d |j        D                                                                 }	d |	D             }
|                    |j        | |j        |
           d	d
t)          |
           d| t)          |
          dS |j        rF|                    t                                        t          j                            |j                                                            }	g }|	D ]}|                    |j        |j        |j        |j        |j        | |j        d |j        D             |j        |j        |j                  }|                    |           |d         rd|_        |d         |_         d|_        |!                                 d|tE          d |D                       tE          d |D                       dS t          dd          # tF          $ rU}tH          %                    |          &                    d           t          ddtO          |                     d d }~ww xY w)N  zLKnowledge graph is not enabled. Set ENABLE_KNOWLEDGE_GRAPH=true in settings.status_codedetail  knowledge_base.not_foundc                     g | ]	}|j         
S r&   id.0cats     r(   
<listcomp>z)build_knowledge_graph.<locals>.<listcomp>D   s    :[:[:[c36:[:[:[r'   c           	      p    g | ]3}|j         |j        |j        |j        |j        d  |j        D             d4S )c                     g | ]	}|j         
S r&   rO   rR   tags     r(   rT   z4build_knowledge_graph.<locals>.<listcomp>.<listcomp>N   s    ;;;3;;;r'   )rP   titlecontentsummarycategory_idtag_ids)rP   rY   rZ   r[   r\   r   )rR   docs     r(   rT   z)build_knowledge_graph.<locals>.<listcomp>G   s]     
 
 
  & Y"{"{#&?;;#(;;; 
 
 
r'   )r+   	tenant_idr2   startedzGraph rebuild started for z
 documents)statusmessager+   document_countc                     g | ]	}|j         
S r&   rO   rW   s     r(   rT   z)build_knowledge_graph.<locals>.<listcomp>n   s    888SV888r'   )document_idrY   rZ   r[   r_   r+   r\   r]   
doc_number
doc_statussupersedes_doc_idssuccess	completedentity_countfailedc              3   *   K   | ]}|d          
dV  dS ri   r;   Nr&   rR   rs     r(   	<genexpr>z(build_knowledge_graph.<locals>.<genexpr>}   s+      $H$H11Y<$HQ$H$H$H$H$H$Hr'   c              3   *   K   | ]}|d          
dV  dS rn   r&   ro   s     r(   rq   z(build_knowledge_graph.<locals>.<genexpr>~   s+      #K#K!a	l#KA#K#K#K#K#K#Kr'   )ra   resultssuccess_countfailed_countz@Either 'rebuild' must be true or 'document_ids' must be provided	exceptionzGraph build failed  zGraph build failed: )(r   r   ENABLE_KNOWLEDGE_GRAPHr   r8   r   filterrP   firsttr   r   r   r\   in_r4   alladd_taskrebuild_knowledge_base_graphr_   lenr   build_document_graphrY   rZ   r[   r   rf   rg   rh   appendr,   rk   commitsum	Exceptionloggeropterrorr5   )rA   rB   rC   rD   rE   rF   r|   kbgraph_builderr2   doc_listrs   r^   resultes                  r(   build_knowledge_graphr   -   sp    	wA* 
a
 
 
 	
 
-	 	 	'	'(8G(C	D	D	J	J	L	LB UACC8R4S4STTTTH_)++  C	*++)599:[:[R]:[:[:[\\]] 

 
 %
 
 
H %%:&0"	 &    $QHQQQ "%h--	   ' &	*++),001KLLMM 
 G  0 0&;; #)KK*4! #88sx888"~"~'*'= <   v&&&)$ 0'2C$'-n'=C$$'/C$$IIKKK%"!$$H$H$H$H$H!H!H ##K#Kw#K#K#K K K	    Y     _ _ _

Q
%%&:;;;4S3q664S4STTTZ^^_s'   !CK 5EK K 
L3AL..L3z/{base_id}/graph/stats)response_modelc                 $   t          |          }t          j        st          dd          |                    t
                                        t
          j        | k                                              }|s$t          d|	                    d                    t          t          dd          	 |j        |j        nd}t          j        || 	          }t                              || 	                              d
           |                    t                                         t           j                            d |j        D                       t           j        dk                                              }| |j        pd|j        ||                    dd          |                    dd          |                    dd          |                    dd          |                    dd          |                    dd          |                    dd          d}	|	S # t0          $ rU}
t                              |
                              d           t          ddt7          |
                     d d }
~
ww xY w)NrH   Knowledge graph is not enabledrI   rL   rM   i  uF   知识图谱服务不可用，请检查 Neo4j 服务是否正常运行r   )r_   r+   zNeo4j stats retrievedc                     g | ]	}|j         
S r&   rO   rQ   s     r(   rT   z#get_graph_stats.<locals>.<listcomp>   s    2S2S2Sc362S2S2Sr'   rj   	not_builtr3   r.   r-   r2   r   r4   )r+   r,   r/   r0   r1   r.   r-   r2   r3   r   r4   rv   zFailed to get graph statsrx   zFailed to get graph stats: )r   r   ry   r   r8   r   rz   rP   r{   r|   r   r_   	get_statsr   binddebugr   r\   r}   r4   r,   count	doc_countgetr   r   r   r5   )rA   rD   rE   rF   r|   r   query_tenant_idstatscompleted_docsr   r   s              r(   get_graph_statsr      sv    	wA* V4TUUUU	-	 	 	'	'(8G(C	D	D	J	J	L	LB UACC8R4S4STTTT$l
 
 
 	
f4@4J4V,00\]&PPPoW==CCD[\\\HH&''V!-112S2SR]2S2S2STT!.+=  UWW 	 O:{!|#1#ii
A66#(99-BA#F#F 99]A66;22		*a00IIfa(())L!44
 
  f f f

Q
%%&ABBB4ZRUVWRXRX4Z4Z[[[aeefs   9E6H0 0
J:AJ

Jz/{base_id}/graph/datar;   r<   Ndepthr?   r9   c           	         t          |          }t          j        st          dd          |                    t
                                        t
          j        | k                                              }|s$t          d|	                    d                    	 t                       |j        |j        nd}	d}
t          j        |
|	| |d|		          }t                              |	| t!          |          
                              d           i }g }t%                      }|D ]}|                    d          }|                    d          }|                    d          }|r|                    d          }|r||vr}||                    d          p|                    dd          |j        rt+          |j                  d         nd|                    dd          |                    dd          d||<   |r|r|                    d          }|r||vr}||                    d          p|                    dd          |j        rt+          |j                  d         nd|                    dd          |                    dd          d||<   |rn|rlt-          t/          ||g                    |j        fz   }||vrA|                    |           |                    |||j        t7          |          d           t                              t!          |          t!          |                                        d           t+          |                                          |t!          |          t!          |          dS # t:          $ rU}t                              |                              d           t          ddtA          |                     d d }~ww xY w) NrH   r   rI   rL   rM   r   aM  
        MATCH (n)
        WHERE n.tenant_id = $tenant_id AND n.kb_id = $kb_id
        WITH n LIMIT $limit
        OPTIONAL MATCH (n)-[r]-(m)
        WHERE m.tenant_id = $tenant_id AND m.kb_id = $kb_id AND id(n) < id(m)
        RETURN
            n as source_node,
            r as relationship,
            m as target_node
        )r_   r+   r?   )
parametersr_   )r_   r+   record_countz Neo4j graph data query completedsource_noderelationshiptarget_noderP   namerY    Unknownr[   salienceg      ?)rP   r   typer   r   )sourcetargetr   
properties)
node_count	rel_countzGraph data processed)nodesrelationshipsr-   r.   rv   zFailed to get graph datarx   zFailed to get graph data: )!r   r   ry   r   r8   r   rz   rP   r{   r|   r   r_   r   execute_queryr   r   r   r   setr   labelsr$   tuplesortedr   addr   dictvaluesr   r   r   r5   )rA   rD   r   r?   r9   rE   rF   r|   r   r   r8   rs   
nodes_dictr   relationship_setrecordr   r   r   node_id	target_idrel_keyr   s                          r(   get_graph_datar      sC    	wA* V4TUUUU	-	 	 	'	'(8G(C	D	D	J	J	L	LB UACC8R4S4STTTT>e!!!4@4J4V,00\] j,%4wQVWW%
 
 

 	oW3w<<XX^^.	
 	
 	
 
55 #	 #	F **]33K!::n55L **]33K 	%//$// wj88% + 7 7 W;??7TV;W;W?J?Q `[%7 8 8 ; ;W`'2y"'E'E$/OOJ$D$D+ +Jw'  | 'OOD11	 *!<!<' + 7 7 W;??7TV;W;W?J?Q `[%7 8 8 ; ;W`'2y"'E'E$/OOJ$D$D- -Jy)  y #FGY+?$@$@AA\EVDXXG&666(,,W555%,,*1*3(4(9.2<.@.@	    	s:#m:L:LMMSS"	
 	
 	
 *++--..*z??#&}#5#5	
 
 	
  e e e

Q
%%&@AAA4YQTUVQWQW4Y4YZZZ`ddes   !L N" "
P,AO<<Pz-/{base_id}/documents/{doc_id}/graph/neighborsr:   doc_idrelation_typesc                    t          |          }t          j        st          dd          |                    t
                                        t
          j        | k                                              }	|	s$t          d|	                    d                    |                    t                                        t          j        |k                                              }
|
s$t          d|	                    d                    	 t                      }|r|                    d          nd }|                    |g|j        | |||          }||t          |          d	S # t           $ rU}t"                              |
                              d           t          ddt)          |                     d d }~ww xY w)NrH   r   rI   rL   rM   document.not_found,)r   r_   r+   r   r   r?   )re   	neighborstotalrv   z Failed to get document neighborsrx   zFailed to get neighbors: )r   r   ry   r   r8   r   rz   rP   r{   r|   r   r   splitexpand_neighborsr_   r   r   r   r   r   r5   )rA   r   rD   r   r   r?   rE   rF   r|   r   r^   graph_query_service	rel_typesr   r   s                  r(   get_document_neighborsr     s    	wA* V4TUUUU	-	 	 	'	'(8G(C	D	D	J	J	L	LB UACC8R4S4STTTT
(($
%
%
,
,->-AV-K
L
L
R
R
T
TC OACC8L4M4MNNNNd5771?IN((---T	'88 ",$ 9 
 
	  &IIWWW d d d

Q
%%&HIII4XPSTUPVPV4X4XYYY_ccds   AE/ /
G9AG		Gz,/{base_id}/documents/{doc_id}/graph/entitiesc                 h   t          |          }t          j        st          dd          |                    t
                                        t
          j        | k                                              }|s$t          d|	                    d                    |                    t                                        t          j        |k                                              }|s$t          d|	                    d                    	 t                      }|                    ||j        |           }	||	t          |	          dS # t          $ rU}
t                               |
	                              d
           t          ddt'          |
                     d d }
~
ww xY w)NrH   r   rI   rL   rM   r   )re   r_   r+   )re   r3   r   rv   zFailed to get document entitiesrx   zFailed to get entities: )r   r   ry   r   r8   r   rz   rP   r{   r|   r   r   get_document_entitiesr_   r   r   r   r   r   r5   )rA   r   rD   rE   rF   r|   r   r^   r   r3   r   s              r(   r   r   0  s    	wA* V4TUUUU	-	 	 	'	'(8G(C	D	D	J	J	L	LB UACC8R4S4STTTT
(($
%
%
,
,->-AV-K
L
L
R
R
T
TC OACC8L4M4MNNNNc577&<<,*@ = 
 
  &8c(mmTTT c c c

Q
%%&GHHH4WsSTvv4W4WXXX^bbcs   =E 
F1AF,,F1z /{base_id}/graph/search/entitiessearch_requestc                    t          |          }t          j        st          dd          |                    t
                                        t
          j        | k                                              }|s$t          d|	                    d                    	 t                      }|                    |j        |j        | |j        |j                  }|j        |t          |          dS # t           $ rU}	t"                              |	                              d	           t          d
dt)          |	                     d d }	~	ww xY w)NrH   r   rI   rL   rM   )
query_textr_   r+   r9   r?   )r8   r3   r   rv   zEntity search failedi  zEntity search failed: )r   r   ry   r   r8   r   rz   rP   r{   r|   r   search_entitiesr_   r9   r?   r   r   r   r   r   r5   )
rA   r   rD   rE   rF   r|   r   r   r3   r   s
             r(   r   r   L  s\    	wA* V4TUUUU	-	 	 	'	'(8G(C	D	D	J	J	L	LB UACC8R4S4STTTTa577&66%+",&2 & 7 
 
 (-8cRZmm\\\ a a a

Q
%%&<===4USQRVV4U4UVVV\``as   !AC5 5
E?AEE)0fastapir   r   r   r   r   pydanticr   r	   sqlalchemy.ormr
   app.api.depsr   app.api.permissionsr   r   
app.configr   app.core.i18nr   
app.modelsr   r   r    app.services.graph.graph_builderr   app.services.graph.graph_queryr   app.services.graph.neo4j_clientr   common_loggingr   r   r   routerr   r*   r7   postr%   r   r   r   r5   r   r   r   r   r&   r'   r(   <module>r      s   O O O O O O O O O O O O O O % % % % % % % % " " " " " "       ; ; ; ; ; ; ; ;       ( ( ( ( ( ( = = = = = = = = = = > > > > > > B B B B B B 8 8 8 8 8 8 % % % % % %	H			*+	,	,	,i i i i i	 i i i
       S S S S S) S S S %&& '&// /@!A!ABBY_ Y_Y_$Y_ &Y_ 	Y_
 	Y_ Y_ Y_ Y_ '&Y_x $5GHH '&// .?!@!@AA	,f ,f,f,f 	,f 	,f ,f ,f IH,f^ #$$ "'&// .?!@!@AAMe MeMeMe Me 	Me
 tMe 	Me Me Me Me %$Me` ;<<
 !%'&// .?!@!@AA!d !d!d!d !d 	!d
 $J!d !d 	!d !d !d !d =<!dH :;;
 '&// .?!@!@AAc ccc c 		c
 c c c <;c6 /00
 '&// .?!@!@AAa aa'a a 		a
 a a a 10a a ar'   