
    Xj                     
   d dl Z d dlZd dlZd dlmZmZmZmZm	Z	m
Z
mZ d dlmZ d dlmZ d dlmZ  eej                            ej                            e          d          d          5 Z ej        e          Zddd           n# 1 swxY w Y   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% d dl&m'Z' d dl(m)Z) d dl*m+Z+ d dl,m-Z-m.Z.m/Z/m0Z0 d dl1m2Z2m3Z3m4Z4 d dl5m6Z6 d dl7m8Z8  ee9          Z: edg          Z; G d de          Z< G d de          Z=de>de?fdZ@de?fdZAde?dz  de?dz  fdZBd ZCd!e?d"eDe>         dz  de?fd#ZEd$e?deFfd%ZGd$e?de?fd&ZHd'e?de?fd(ZId)e?de?dz  fd*ZJd)e?deKe?e?f         dz  fd+ZLd)e?de?dz  fd,ZMd-e?de>dz  fd.ZNd/eDe?         d0eOde?fd1ZPd-e?de>dz  fd2ZQ	 dXd-e?d$e?dz  deKe?e>dz  f         fd3ZRe;S                    d4ejT        5          d d6d ee           e e$d                    fd7eOd8eOd9eOd:ed;ed<e0fd=            ZUe;S                    d>ejT        5          dd6d ee           e e$d                    fd7eOd?e?d@eOd9eOd:ed;ed<e0fdA            ZVe;S                    dBeDe3         C          d dD ee           e e$d                    fd8eOd9eOd;ed<e0fdE            ZWe;S                    dFe3C           ee           e e$d                    fd7eOd:ed;ed<e0fdG            ZXe;Y                    dBe3ejZ        H           ee           e e!d                    fdIe2d:ed;ed<e0fdJ            Z[e;\                    dFe3C           ee           e e%d                    fd7eOdIe4d:ed;ed<e0f
dK            Z]e;^                    dFejT        5           ee           e e"d                    fd7eOd:ed;ed<e0fdL            Z_e;Y                    dMejT        5           ee           e e%d                    fd7eOd:ed;ed<e0fdN            Z`e;a                    dOejT        5           ee           e e%d                    fd7eOdPe?d:ed;ed<e0f
dQ            Zbe;Y                    dRe=C           ee           e e#d                    fd7eOdSe<d:ed;ed<e0f
dT            Zce;d                    dU           ee          fdVe	d7eOd;efdW            ZedS )Y    N)	APIRouterDependsHTTPExceptionRequest	WebSocketWebSocketDisconnectstatus)StreamingResponse)
get_logger)Sessionzdefault_quick_actions.jsonzutf-8)encoding)	BaseModel)crud)get_db)require_createrequire_deleterequire_executerequire_readrequire_update)ExternalServiceError)get_translator)SessionLocal)AgentChatMessageModelUser)AgentCreateAgentResponseAgentUpdate)conversation_manager)get_chat_factoryagents)tagsc                   <    e Zd ZU eed<   dZedz  ed<   dZeed<   dS )ChatRequestmessageNconversation_idFstream)__name__
__module____qualname__str__annotations__r'   r(   bool     </lsinfo/ai/hellotax_ai/base_platform/app/api/v1/ai/agents.pyr%   r%   .   s?         LLL"&OS4Z&&&FDr0   r%   c                       e Zd ZU eed<   dZedz  ed<   g Zee         dz  ed<   dZ	edz  ed<   dZ
edz  ed<   dZedz  ed<   dZ	edz  ed<   dZ
edz  ed<   dZedz  ed<   dS )	ChatResponseresponseNr'   sourcestextformat
table_datametadata)r)   r*   r+   r,   r-   r'   r5   listdictr7   r8   r9   r/   r0   r1   r3   r3   4   s         MMM"&OS4Z&&&!#GT$Z$###FC$J"Jt""" HdTk   FC$J"Jt""" HdTk     r0   r3   payloadreturnc                 6    dt          j        | d           dS )Nzdata: F)ensure_ascii

)jsondumps)r<   s    r1   
_sse_eventrC   @   s"    ADJwU;;;AAAAr0   c                      dS )Nu  【财税智能助手行为准则】

一、敏感话题处理规则
当用户问题涉及以下内容时，请回复"此问题无法回复"：
- 政治敏感话题
- 国家安全
- 暴力与犯罪
- 色情低俗
- 身份歧视
- 群体攻击

二、地域性边界（Local Context）
税法虽有国家大法，但各地的"税收优惠政策"、"核定征收标准"、"社保缴纳基数"差异极大。
- 当用户问"小微企业现在要交多少税"等问题时，约束你**不要盲目直接给数字**
- 必须先反问："请问您的企业注册在哪个省份/城市？属于哪种行业？"
- 收集足够的地域信息后再提供针对性建议

三、数据脱敏与隐私边界（Data Security）
财务数据是企业的最高机密。
- 当看到敏感格式数据（如公司具体名称、张三、某某科技有限公司等）时，进行拦截并提示用户
- 建议用户将"张三"、"某某科技有限公司"等替换为"客户A"、"企业B"后再提供咨询
- 不要要求用户提供具体的财务机密数据

四、政策引用要求
凡涉及税率、税收优惠、扣除标准的回答，**必须**尽可能引用具体的政策依据（如：《财政部 税务总局公告202X年第X号》）。
- 严禁对政策进行过度解读
- 如遇政策模糊地带，需明确指出"该问题在实操中存在争议，需与主管税务机关'单笔单批'沟通"

五、领域与合规红线
- **仅限财税与商业合规领域**。对非本领域问题坚决拒绝，话术："作为企业财税专家，我仅专注于财务合规、税务筹划及审计相关事务，无法为您解答[无关领域]的问题。"
- **拒绝违法操作**。对于"买卖发票"、"隐匿收入"等诉求，直接拒绝并严肃提示相关刑法风险（如虚开增值税专用发票罪）。

六、回答风格要求
1. 先直接给出简短结论，再用自然语言补充说明，避免机械列出 1、2、3 点
2. 优先自然表达，避免大段模板化标题或生硬分段
3. 仅在强调关键词时使用少量 Markdown 粗体，不要堆砌 ** 或连续标题
4. 除非用户明确要求详细解释，否则回答保持简洁、清晰、可直接阅读
5. 不要机械追加"参考依据""参考来源"等固定小节；来源会在独立引用区域展示
6. 如果资料不足，直接说明不确定点，不要编造内容
7. 如果用户要求"表格/对比/对照"，请用 Markdown 表格输出（包含表头和分隔行），不能仅仅输出表格，其他输出也是必要的。

七、法条时效性处理（当前时间点用户问到再回答，没有问不要主动提时间准确）
检索结果中若包含同一法条在不同时间的不同处理方式，你必须且只能输出发布时间最新的实操指导，并向用户注明该实操的具体年份来源。

八、强制免责声明
**所有输出必须以以下内容结尾：**

AI生成的财税建议仅供参考，不作为最终法律、税务处理依据，重大财税决策请咨询专业税务师。r/   r/   r0   r1   !_build_response_style_instructionrE   D   s     Y0  Y0r0   base_promptc                    ddl m } |                                }d|j         d|j         d|j         d|j         d|j         d}|g}| r;|                                 r'|                    |                                            |                    t                                 d                    |                                          }|pd S )	Nr   )datetimeu   系统当前真实时间是：u   年u   月ui   日。当用户提到"今年"、"当前"、"最近"、"现在"等时间词时，你必须且只能基于 u(   月 的时间点进行计算和推理。r@   )	rH   nowyearmonthdaystripappendrE   join)rF   rH   rI   time_injectionprompt_partscombined_prompts         r1   _compose_system_promptrS   H   s   !!!!!!
,,..C Dch  D  D39  D  DQTQX  D  D  DG  DL  D  D  QT  QZ  D  D  DN"#L 1{((** 1K--//0009;;<<<kk,//5577O"d"r0   u   

AI生成的财税建议仅供参考，不作为最终法律、税务处理依据。重大财税决策请咨询专业税务师response_textrag_sourcesc                 "    d| v r| S | t           z   S )Nu#   AI生成的财税建议仅供参考)
DISCLAIMER)rT   rU   s     r1   _append_rag_reference_blockrX   Z   s    ,==:%%r0   user_messagec                 n    | pd                                 g d}t          fd|D                       S )N )u   表格u   对比u   对照u   比较u   区别u   差异u	   一览表u	   汇总表compare
comparisonversusvstablec              3       K   | ]}|v V  	d S Nr/   ).0keywordnormalized_messages     r1   	<genexpr>z$_is_table_request.<locals>.<genexpr>q   s)      KKw,,KKKKKKr0   )lowerany)rY   table_keywordsre   s     @r1   _is_table_requestrj   `   sP    &,"3355  N KKKKNKKKKKKr0   c                 R    t          |           s| S |                                  dS )Nu   

请直接使用 Markdown 表格回答，必须包含：
1. 表头行
2. 分隔行（例如 | --- | --- |）
3. 至少 2 行对比内容
除非用户明确要求，否则不要改成普通段落或项目列表。若需要补充说明，请放在表格后面，用一句话简短补充。)rj   rM   )rY   s    r1    _rewrite_user_message_for_formatrl   t   s?    \**   ""  K  K  K  Kr0   valuec                 \   dd l }| pd                                }|                    dd|          }|                    dd|          }|                                                    d                              d                                          }|                    dd|          }|S )	Nr   r[   z^\s*(?:#+\s*)?u   ^\s*(?:[-*•]|\d+[.)、])\s**_z\s+ )rerM   sub)rm   rr   cleaneds      r1   _normalize_comparison_textru   z   s    III{!!##Gff'W55Gff7WEEGmmoo##C((..s3399;;GffVS'**GNr0   linec                    dd l }t          |                               d                                          }|rt	          |          dk    rd S |                    d|          rd S |                    d|          rd S |S )Nr      ：:      [。；，,.!?？！]u   [:：])rr   ru   rstriprM   lensearch)rv   rr   	candidates      r1   _parse_heading_candidater      s    III*40077??EEGGI I++t	yy()44 t	yy9%% tr0   c                 <   dd l }t          |           }|                    d|          }|sd S |                    d                                          }|                    d                                          }|r|sd S |                    d|          rd S ||fS )Nr   u!   ^([^:：]{1,20})\s*[:：]\s*(.+)$      rz   )rr   ru   matchgrouprM   r}   )rv   rr   r~   r   labelrm   s         r1   _parse_label_valuer      s    III*400IHH:IFFE tKKNN  ""EKKNN  ""E  t	yy(%00 t5>r0   c                    dd l }| pd                                }|                    d|          sd S t          |          }|                    d|          r|                    d          sd S |                    d                                          }|rt          |          dk    rd S |                    d|          rd S |S )	Nr   r[   u   ^\s*(?:\d+[.)、]|[-*•])\s+u
   [:：].+\S):u   ：rx   ry   rz   )rr   rM   r   ru   r}   endswithr{   r|   )rv   rr   strippedr~   s       r1   _parse_dimension_headingr      s    III
!!##H886AA t*844I	yy	** I4F4F|4T4T t  ((..00I I++t	yy()44 tr0   r6   c                    g }g }d }i }|                                  D ]}|                                }|st          |          }|r1|r*t          |          dk    r|                    ||f           |}i }[|s^t          |          }|sp|\  }	}
|	|vr|                    |	           |
||	<   |r*t          |          dk    r|                    ||f           t          |          dk     st          |          dk     rd S g }|D ]Q\  }|gfd|D             z   }t          d |dd          D                       dk    r|                    |           Rt          |          dk     rd S dg||dS )Nr   c                 <    g | ]}                     |d           S )r[   )get)rc   entityvaluess     r1   
<listcomp>z6_detect_dimension_comparison_table.<locals>.<listcomp>   s'    OOOVZZ33OOOr0   c              3      K   | ]}|d V  	dS )r   Nr/   )rc   cells     r1   rf   z5_detect_dimension_comparison_table.<locals>.<genexpr>   s'      --T-q------r0   r   	   对比项headersrows)
splitlinesrM   r   r|   rN   r   sum)r6   entity_orderrow_entriescurrent_dimensioncurrent_valuesraw_liner   dimension_headinglabel_valuer   rm   r   	dimensionrowr   s                 @r1   "_detect_dimension_comparison_tabler      s   LKNOO%% & &>>## 	4X>> 	  HS%8%8A%=%=""$5~#FGGG 1N  	(22 	"u$$&&& %u @S00A55-~>???
<1K 0 01 4 4tD(  	6kOOOO,OOOO--SW-----22KK
4yy1}}t#3l3TBBBr0   linesstart_indexc                     t          |dz   t          |                     D ]"}| |                                         }|r|c S #dS )Nr   r[   )ranger|   rM   )r   r   idxr~   s       r1   _next_nonempty_liner      sX    [1_c%jj11  #J$$&&	 		2r0   c                 4   dd l }|                                 }g }d }t          |          D ];\  }}|                                }|st	          |          }t          ||          }	|                    d          }
t          |                    d|	                    }|r8t          |          s)|
s|r%|r|d         r|
                    |           |g d}|st          |          }|r|d         
                    |           |                    d|          rGt          |          }|r6|d         
                    dt          |d                   dz    |f           =|r|d         r|
                    |           t          |          dk     rd S d	gd
 |D             z   }g }t                      }|D ]>}|d         D ]3\  }|vr*|                               |
                               4?t          |          dk     rd S g }|D ]gg }d}|D ]@}t          fd|d         D             d          }|r|dz  }|
                    |           A|dk    r|
                    g|           ht          |          dk     rd S ||dS )Nr   )#z**__u   ^\s*(?:[-*•]|\d+[.)、])\s+items)titler   u   要点r   r   r   c                     g | ]
}|d          S )r   r/   )rc   sections     r1   r   z4_detect_section_comparison_table.<locals>.<listcomp>	  s    HHHGww/HHHr0   c              3   .   K   | ]\  }}|k    |V  d S rb   r/   )rc   item_key
item_valuekeys      r1   rf   z3_detect_section_comparison_table.<locals>.<genexpr>  s-      \\ 4*HX[OOOOOO\\r0   r[   r   )rr   r   	enumeraterM   r   r   
startswithr.   r   r   rN   ru   r|   setaddnext)r6   rr   r   sectionscurrent_sectionr   r   r   heading	next_lineexplicit_headingnext_is_list_itemr   bullet_textr   row_keys	seen_keysr   rp   r   r   present_countrm   r   s                          @r1    _detect_section_comparison_tabler      sY   IIIOOEHO"5))  X>>## 	*844's33	#../@AA *Li!X!XYY	'11	 "	 &7	
  1?7#; 1000(/"==O 	(22 	G$++K888886AA 	4X>>K (//Ac/'":;;a?AA;O    )?73 )(((
8}}qtmHHxHHHHGHI % %g& 	% 	%FC)##c"""$$$	% 8}}qtD ( ( 	! 	!G\\\\8H\\\^` E  #"MM%    AKKv'''
4yy1}}t---r0   c           	         dd l }|                     d          }d}d}t          |          D ]X\  }}|                                }|sd|v r8|dk    r|}|                    d|          s|                    d|          r|} nY|dk    rB|dk    r;||dz   k    r1||                                         }d |                    d          D             }	g }
t          |dz   t          |                    D ]}||                                         }|rd|vr nld	 |                    d          D             }|rJt          |          t          |	          k    r*|
                    |d t          |	                              |	rD|
rBt          	                    d
t          |	           dt          |
           d           d|	|
dfS t          |pd          rkt          |           pt          |           }|rKt          	                    dt          |d                    dt          |d                    d           d|fS d}|                    || |j                  rdS dS )Nr   
|z^\s*\|[\s:-]+\|\s*$z^\s*\|[\s:-]+\|[\s:-]+\|r   c                     g | ]=}|                                 |                                                      d           >S ro   rM   )rc   hs     r1   r   z+_detect_response_format.<locals>.<listcomp>;  s9    UUUA17799U17799??3''UUUr0   c                     g | ]=}|                                 |                                                      d           >S r   r   )rc   cs     r1   r   z+_detect_response_format.<locals>.<listcomp>A  s9    PPPaaggiiPQWWYY__S))PPPr0   zDetected table format: z
 columns, z rowsr`   r   r[   z$Detected comparison fallback table: r   r   z^\d+\.\s+.+$)markdownN)r6   N)rr   splitr   rM   r   r   r|   rN   loggerinforj   r   r   r}   	MULTILINE)r6   rY   rr   r   table_startseparator_lineirv   header_liner   r   cellscomparison_tablelist_patterns                 r1   _detect_response_formatr   %  s    IIIJJtEKNU##  4zz|| 	$;;b  xx2D99 RXX0$> >  "#b^r11~WX7X7XK(..00UU1B1B31G1GUUU~)3u::66 	3 	3A8>>##D 3d??PP4::c??PPPE 3Us7||33E.CLL.1222 	At 	AKKZ#g,,ZZ#d))ZZZ[[[$??@@+,, /=
 
 4-d33 	  	/KK Hs;KI;V7W7W  H  Hcfgwx~g  dA  dA  H  H  H   -..$L	yytR\22 "!!>r0   z/{agent_id}/conversations)status_codery   agent_idskiplimitrequestdbcurrent_userc           	         t          |          }|                    t                                        t          j        | k                                              }|s$t          d|                    d                    ddlm	}m
}	 |                    t          j        |	                    t          j                                      d          |	                    t          j                                      d          |	                    t          j                                      d                                        t          j        | k                                  t          j                                       |d                                        |                              |                                          }
g }|
D ]u}|                    |j        |j        r|j                                        nd |j        t9          |j                  d	k    r|j        d d	         d
z   n|j        d           v|t9          |          ||dS )N  agent.agent_not_foundr   detailr   )descfunclast_message_timemessage_countlast_messaged   z...)r'   r   r   r   )conversationstotalr   r   )r   queryr   filteridfirstr   t
sqlalchemyr   r   r   r'   max
updated_atr   countcontentr   group_byorder_byoffsetr   allrN   r   	isoformatr   r|   r   )r   r   r   r   r   r   r   db_agentr   r   r   resultconvs                r1   get_agent_conversationsr  V  s    	wAxx%%eh(&:;;AACCH RACC8O4P4PQQQQ%%%%%%%% 	'HH[+,,223FGGJJ{~&&,,_==HH[())//??		
 	
 
$0	1	1	+-	.	.	$$*++	,	,		u	  F 
 
#'#7:>:PZD*44666VZ!%!3 4,--33 %dsd+e33* 	
 	
 	
 	
 $c&kk4RWXXXr0   z4/{agent_id}/conversations/{conversation_id}/messagesr'   beforec           
      D   t          |          }|                    t                                        t          j        | k                                              }|s$t          d|                    d                    |                    t                                        t          j	        | k    t          j
        |k              }	|r#|	                    t          j        |k               }	|	                    t          j                                                                      |                                          }
t                               d|  d| d| d|            t                               dt%          |
           d	           |
                                 g }|
D ]K}|                    |j        |j        |j        |j        pg |j                                        d
d           L||t%          |          t%          |          |k    dS )Nr   r   r   u   查询对话消息: agent_id=, conversation_id=z	, before=z, limit=u   找到 u
    条消息read)r   roler   r5   	timestampr	   )r'   messagesr   has_more)r   r   r   r   r   r   r   r   r   r   r'   r   
created_atr   r   r   r   r   r|   reverserN   r  r   r5   r   )r   r'   r  r   r   r   r   r   r   r   r	  r   msgs                r1   get_conversation_messagesr    s    	wAxx%%eh(&:;;AACCH RACC8O4P4PQQQQHH[!!(((+*E*X E  6[^f455~~k499;;<<BB5IIMMOOH
KKuuuOuu^duunsuu   KK3#h--333444F 

 

f;;," ^5577  		
 		
 		
 		
 +VKK5(	  r0   /)response_modelr   c                 L    t           j                            || ||          }|S )N)r   r   r   )r   agent	get_multi)r   r   r   r   r"   s        r1   
get_agentsr    s'     Z!!"4u<!XXFMr0   z/{agent_id}c                     t          |          }t          j                            || |          }|s$t	          d|                    d                    |S )Nr   r   r   r   r   )r   r   r  r   r   r   )r   r   r   r   r   r  s         r1   	get_agentr    sX     	wAJNN2(NFFE RACC8O4P4PQQQQLr0   )r  r   r  c           
      l   t          |          }	 | j        rx|                    t                                        t          j        | j        k                                              }|s$t          d|                    d                    | j	        st          | _	        t          j                            || |j        |j                  }|S # t          $ rW}|                                 t          t"          j        |                    dt'          |                              |d }~ww xY w)N  agent.model_not_foundr   )obj_in
created_by	tenant_idzagent.create_failederror)r   model_idr   r   r   r   r   r   r   quick_actionsDEFAULT_QUICK_ACTIONSr   r  creater  	Exceptionrollbackr	   HTTP_500_INTERNAL_SERVER_ERRORr,   )r  r   r   r   r   db_modelr   es           r1   create_agentr)    s(    	wA> 	Zxx--eh%..HIIOOQQH Z#ACC@W<X<XYYYY" 	8"7E:$$uLDZ % 
 
    
=33,CFF3;;
 
 
 	s   C C 
D3AD..D3c           
         t          |          }t          j                            || |          }|s$t	          d|                    d                    	 |j        rx|                    t                    	                    t          j
        |j        k                                              }|s$t	          d|                    d                    t          j                            |||          }|S # t          $ rW}|                                 t	          t          j        |                    dt#          |          	                    |d }~ww xY w)
Nr  r   r   r   r  r  )db_objr  zagent.update_failedr  )r   r   r  r   r   r   r   r   r   r   r   r   updater$  r%  r	   r&  r,   )	r   r  r   r   r   r   r   r'  r(  s	            r1   update_agentr-    sG    	wAz~~bXL~IIH RACC8O4P4PQQQQ> 	Zxx--eh%..HIIOOQQH Z#ACC@W<X<XYYYY:$$R$GG   
=33,CFF3;;
 
 
 	s   B"C< <
EAEEc           
         t          |          }	 t          j                            ||           }|s$t	          d|                    d                    d|                    d          dS # t          $ r  t          $ rW}|                                 t	          t          j	        |                    dt          |          	                    |d }~ww xY w)
N)r   r   r   r   Tzagent.agent_deleted)successr&   zagent.delete_failedr  )r   r   r  deleter   r   r$  r%  r	   r&  r,   )r   r   r   r   r   deleted_agentr(  s          r1   delete_agentr2    s     	wA
))"):: 	VC<S8T8TUUUUACC0E,F,FGGG      
=33,CFF3;;
 
 
 	s   AA0 0CACCz/{agent_id}/togglec           
         t          |          }|                    t                                        t          j        | k                                              }|s$t          d|                    d                    |j        dk    r4|j	        |j	        k    r$t          d|                    d                    	 |j
         |_
        |                                 |                    |           d|j
        dS # t          $ rW}|                                 t          t          j        |                    d	t#          |          
                    |d }~ww xY w)Nr   r   r   platform_admin  agent.access_deniedT)r/  runningzagent.toggle_failedr  )r   r   r   r   r   r   r   r   r  r  r7  commitrefreshr$  r%  r	   r&  r,   )r   r   r   r   r   r   r(  s          r1   toggle_agentr:    sU    	wAxx%%eh(&:;;AACCH RACC8O4P4PQQQQ,,,!777C<Q8R8RSSSS
'//
		


8H,<===   
=33,CFF3;;
 
 
 	s   ?D 
E$AEE$z/{agent_id}/statusr	   c           
      f   t          |          }|dvr$t          d|                    d                    	 t          j                            || |          }|s$t          d|                    d                    |j        dk    r4|j        |j        k    r$t          d	|                    d
                    d|j        dS # t          $ r  t          $ rR}|
                                 t          |j        |                    dt          |                              |d }~ww xY w)N)onlineoffliner  zagent.invalid_statusr   )r   r	   r   r   r4  r5  r6  T)r/  r	   zagent.update_status_failedr  )r   r   r   r   r  update_statusr  r  r	   r$  r%  r&  r,   )r   r	   r   r   r   r   r   r(  s           r1   update_agent_statusr?  4  sT    	wA***ACC8N4O4OPPPP:++B&+QQ 	VC<S8T8TUUUU 000!\%;;;#ACC@U<V<VWWWW8?;;;      
=3333q663BB
 
 
 	s   BC
 
D0AD++D0z/{agent_id}/chatchat_requestc                 0   !"#$%&K   t          |          }|j        }t                              d|j         d|j         d           |                    t                                        t          j         k                                              }|s$t          d|
                    d                    |j        dk    rBt                              d  d	           t          d
|
                    d                    |j        sBt                              d  d           t          d
|
                    d                    t                              d  d|j                    	 ddlm} |j        }	t#          |	          }
d }g & |||          }t%                      }t                              d|j                    |                    t&                                        t&          j        |j        k                                              }|sGt                              d|j         d           t          d
|
                    d                    |j        }|s$t          d
|
                    d                    |j        s+t          d
|
                    d|j                            |j        dk    r?|                                s+t          d
|
                    d|j                            |j        $$s1t5          j                    $t                              d$            nt                              d$            |                    |j        |          #dd l}|                                }ddlm} |j        }	t#          |	          }
d }g & |||          }|                    |	          r|                                }t                              d           	 |                     |	ddd|j!        |j"        #|j#        p|j$        d !	  	         d {V }|d"         }|d#         &|                                |z
  }t          %                    tM          |d$          |d%         &                              d'           nN# tN          $ r'}t                              d(|            Y d }~n"d }~ww xY wt                              d)           g %tQ          |)                    |j*        pd*tW          |          +                    }|r%,                    d,|d-           t5          j-        $d./          }%.                    |           |r%,                    d,|d-           %,                    d0|
d-           t5          j/        $d0|	           ta           |$d0|	1          }|1                    |           |2                                 t          %                    |j$        |j3        2                              d3           t                              d4|j$         d5|j3                    |j3        r|j4        pd6"|j5        pd7! !"#$%&fd8}|                                |z
  }t          %                    tM          |d$          9                              d:           tm           |            d;d<d=d>d?@          S t                              dA           #7                    %|j4        pd6|j5        pd7B           d {V }#8                    |          }ts          |&          }#:                    |          }t                              dC|            t5          j/        $dD|           ta           d $dD|&pg E          }|1                    |           |;                                 ty          |          \  }} t{          |$&|| F          S # t          $ r  t|          $ r[}t                              dGt          |                      t          t          j@        dHt          |                     d d }~wtN          $ r}t                              dIt          |           A                    d J                     t          t          jB        |
                    dKt          |          L                    |d }~ww xY w)MNzUser z (ID: z) initiated chatr   r   r   r<  u
   ❌ Agent z is offliner  zagent.agent_offlinez has no model configuredzagent.model_not_configuredu
   ✅ Agent z validation passed, model_id: r   get_agent_rag_serviceu2   🟢 Using provider-based chat routing, model_id: zModel z not found in databaser  zagent.provider_not_foundzagent.provider_not_configured)providernonezCreated new conversation: zUsing existing conversation: zRAG retrieval started   333333?hybridT	r   top_k	thresholdmoder  	user_rolechat_client
chat_modeluse_rerankercontext_textr5   r   retrieved_count)elapsed	doc_countzRAG retrieval completedzFKnowledge base retrieval failed, continuing with normal conversation: zSkipping RAG retrievalr[   has_contextsystemr  r   
   max_messagesuserr   user_idr'   r  r   )modelr(   zCalling chat APIzCalling chat API - Model: z
, Stream: ffffff?   c            	       	K   g } t          dd          W V  	 ddlm}m} t	          ||z            rq                              2 3 d {V }|                     |           t          d|d          W V  26 d                    |           	t          	          	nY	                    d	
           d {V }
                    |          	t          	          	t          d	d          W V  t          j        d	           t          	          \  }}t          d	||d          W V  
	fd}t          j         |                       d S # t           $ rk}t"                              dt'          |                               d                     t          dt'          |          d          W V  Y d }~d S d }~ww xY w)Nstarttyper'   r5   r   LocalAssetChatClientOpenAICompatibleChatClientr	  temperature
max_tokensdeltare  r   r[   Fr	  rj  rk  r(   	assistantdonere  r'   r4   r5   r7   r8   c                    K   t                      } 	 t          d dpg           }|                     |           |                                  |                     |           t
                              d d d|j                    n4# t          $ r'}t
          	                    d|            Y d }~nd }~ww xY w| 
                                 d S # | 
                                 w xY w)Nro  r   r^  r'   r  r   r5   u0   ✅ 助手回复已保存到数据库: agent_id=r  z, message_id=z(Failed to save assistant message to DB: )r   r   r   r8  r9  r   r   r   r$  r  close)	stream_dbassistant_chat_messager(  r   r'   rU   rT   s      r1   
save_to_dbz8chat_with_agent.<locals>.chat_stream.<locals>.save_to_db  sT     $0NN	.5@)1(,0?%0(5(3(9r6 6 62 &MM*@AAA%,,...%--.DEEE"KK !iS[  !i  !io~  !i  !i  Nd  Ng  !i  !i     ) Y Y Y"LL)WTU)W)WXXXXXXXXY &OO-----IOO----s0   A=B C 
CB=8C =CC C1zChat streaming failed: T	exceptionr  re  r  )rC   .app.services.llm.backends.chat_backend_factoryrg  rh  
isinstanceasync_stream_completionrN   rO   rX   chat_completionextract_response_textr    add_messager   asynciocreate_taskr$  r   r  r,   opt)response_chunksrg  rh  
text_chunkapi_responseformat_typer8   rw  r(  rT   r   agent_max_tokensagent_temperaturerN  r'   r	  rU   s            @r1   chat_streamz$chat_with_agent.<locals>.chat_stream  s     "$ $U`aa     @I       
 "+/IL`/`aa V0;0S0S%-(9'7 1T 1 1 W W W W W W W*
 ,22:>>>",g*-U-U"V"VVVVVV1 )+(@(@(CMS^(_(_-8-H-H%-(9'7#(	 .I . . ( ( ( ( ( ( )4(I(I,(W(W(CMS^(_(_('m)T)TUUUUUU(4_kS`aaa.Em.T.T+K$$*/>(5'2&1*4 	 	 	 	 	 	. . . . . . . ., '

55555  I I ILL!C3q66!C!C!G!GRV!G!W!WXXX$gA%G%GHHHHHHHHHHHHIs%   3E* BDE* *
G4A GG)rS  zReturning StreamingResponseztext/event-streamzno-cachez
keep-aliveno)zCache-Control
ConnectionzX-Accel-Buffering)
media_typer   u$   📞 Starting NON-STREAMING responseri  zToken usage: ro  rs  )r4   r'   r5   r7   r8   zExternal service error: u   对话失败: zChat failed: rx  zagent.chat_failedr  )Cr   r   r   r   namer   r   r   r   r   r   r	   warningr   app.services.agent.rag_servicerC  r&   rl   r!   r   r  rD  
configured	auth_typeget_api_keyr'   r    create_conversation
get_clienttimeshould_retrievedebugretrieve_contextr  r  remote_model_idcodebindroundr$  rS   enhance_system_promptsystem_promptr.   rN   get_messagesextendr  r   r   flushr(   rj  rk  r
   r~  r  rX   get_usage_infor8  r   r3   r   r,   HTTP_502_BAD_GATEWAYr  r&  )'r   r@  r   r   r   r   current_user_idr   rC  rY   formatted_user_messagerag_contextrag_servicechat_factoryr_  rD  r  request_start_time	rag_start
rag_resultrag_elapsedr(  enhanced_prompthistory_messagesuser_chat_messager  elapsed_before_streamr  rT   
usage_inforv  r  r8   r  r  rN  r'   r	  rU   s'   `                                @@@@@@r1   chat_with_agentr  Q  s"
      	wA"oO
KKR)RRRRRSSSxx%%eh(&:;;AACCH RACC8O4P4PQQQQ(""9H999:::ACC8M4N4NOOOO WFHFFFGGGACC8T4U4UVVVV
KKXXXXXEVXXYYYZHHHHHH#+!A,!O!O++B99'))\IZ\\]]]&&ux83D'DEEKKMM 	VLLK("3KKKLLLC<S8T8TUUUU> 	YC<V8W8WXXXX" 	,KV^Vc(d(d    ''1E1E1G1G',KV^Vc(d(d    '6 	K2FHHOKKF_FFGGGGKKIIIJJJ"--eh;;!YY[[HHHHHH#+!A,!O!O++B99&&|44 	3		ILL0111#.#?#?&!!*4*/ +$4B
!% $@ 
$ 
$ 
 
 
 
 
 

 )8(3"iikkI5E+q$9$9ZPaEbccii  kD  E  E  E  E   `]^``       
 LL12220--&,"${:K:K .  
 

  	LOOX/JJKKK/<_[]^^^())) 	HOOX+FFGGG4JKKLLL(&,OOO'#+ 
 
 
 	 !!!



%*\-@AAGGHZ[[[\\\|GZ\\]]] U	 ( 4 ;'2:dEI EI EI EI EI EI EI EI EI EI EIN %)IIKK2D$D!KK&;Q ? ?K@@FFGdeee$.%/".)-     	:;;;(88 ,3*2d 9 
 
 
 
 
 
 
 

 $99,GG3M;OO //==
0J00111(+}UUU!,+!%2"
 "
 "
 	%&&&
		"9-"H"HZ"+!
 
 
 	
     q q q8A88999(CLe]`ab]c]cLeLeffflpp   -SVV--11D1AABBB=33*#a&&399
 
 
 	sZ   :J` B$R: 9` :
S+S&!` &S++H` D` d1AbdA<ddz/{agent_id}/chat/ws	websocketc                   K   |                                   d {V  t                              d|            	 |                                  d {V }|                    d          }|                    d          }|                    d          }|sg|                     ddd           d {V  |                                  d {V  	 	 |                                  d {V  d S # t          $ r Y d S w xY wdd	lm	} 	  |||          }nu# t          $ rh |                     dd
d           d {V  |                                  d {V  Y 	 |                                  d {V  d S # t          $ r Y d S w xY ww xY w|
                    t                                        t          j        |k                                              }	|	sg|                     ddd           d {V  |                                  d {V  	 	 |                                  d {V  d S # t          $ r Y d S w xY w|	j        dk    rg|                     ddd           d {V  |                                  d {V  	 	 |                                  d {V  d S # t          $ r Y d S w xY w|	j        sg|                     ddd           d {V  |                                  d {V  	 	 |                                  d {V  d S # t          $ r Y d S w xY w|	j        pg }
|
D ]M}|                    d          |k    r0|                    d          r|pt%          j                    }|                    t+          ||j        |d|                     |                    t+          ||j        |d|d                              |                                 |                     d|d         d           d {V  |                     d||d         g d           d {V  |                                  d {V   	 |                                  d {V  d S # t          $ r Y d S w xY wOddlm}  |||	          }t3                      }|
                    t4                                        t4          j        |	j        k                                              }|sg|                     ddd           d {V  |                                  d {V  	 	 |                                  d {V  d S # t          $ r Y d S w xY w|                    |j        |          }|st%          j                    }t9          |          }d }g }|                    |          r	 |                    |ddd|j        |j         ||j!        p|j"        d	  	         d {V }|d         }|d          }n4# t          $ r'}t          #                    d!|            Y d }~nd }~ww xY wg }tI          |%                    |	j&        pd"tO          |          #                    }|r|(                    d$|d%           t%          j)        |d&'          }|*                    |           |r|(                    d$|d%           |(                    d|d%           t%          j+        |d|           t+          ||j        |d|          }|                    |           |,                                 |                     d(||d)           d {V  g }dd*l-m.}m/} ta          |||z            rc|1                    ||	j2        pd+|	j3        pd,-          2 3 d {V }|(                    |           |                     d.|d           d {V  ;6 nu|4                    ||	j2        pd+|	j3        pd,d/0           d {V }|5                    |          } |                     d.| d           d {V  |(                    |            d"6                    |          } to          | |          } t%          j+        |d|            t+          |d |d| |pg 1          }!|                    |!           |                                 tq          | |          \  }"}#|                     d|| ||"|#d2           d {V  n# tr          $ r  t                              d3|            Y nt          $ r}t          #                    d4tu          |           ;                    d5                     	 |                     dtu          |          d           d {V  n# t          $ r Y nw xY wY d }~nd }~ww xY w	 |                                  d {V  d S # t          $ r Y d S w xY w# 	 |                                  d {V  w # t          $ r Y w w xY wxY w)6Nz+WebSocket connection established for agent r&   r'   tokenr  zMessage is requiredrz  r   )get_current_user_from_tokenzAuthentication failedzAgent not foundr<  zAgent is offlinezModel not configuredpromptreplyr\  r]  ro  r   rm  rp  )re  r'   r4   r5   rB  zModel not foundrF  rG  rH  TrI  rQ  r5   zRAG retrieval failed: r[   rU  rW  rX  rY  rZ  rc  rd  rf  r`  ra  ri  rl  Frn  rs  rq  z!WebSocket disconnected for agent zWebSocket error: rx  )<acceptr   r   receive_jsonr   	send_jsonrt  r$  app.api.depsr  r   r   r   r   r   r	   r   r!  r    r  r   r   r8  r  rC  r!   r   r  rl   r  r  r  r  r  r  r  rS   r  r  r.   rN   r  r  r  r  r{  rg  rh  r|  r}  rj  rk  r~  r  rO   rX   r   r   r,   r  )$r  r   r   datarY   r'   r  r  r   r   r!  qaconv_idrC  r  r  r_  rN  r  r  rU   r  r(  r	  r  r  r  r  rg  rh  r  r  rT   rv  r  r8   s$                                       r1   chat_websocketr  C  s     





KKHhHHIIIv++--------xx	**((#455!! 	%%wAV&W&WXXXXXXXXX//#########V	//########### 	 	 	DD	Y 	=<<<<<	66ubAALL 	 	 	%%wAX&Y&YZZZZZZZZZ//#########F	//########### 	 	 	DD	Q	 88E??))%(h*>??EEGG 	%%wAR&S&STTTTTTTTT//#########|	//########### 	 	 	DD	 ?h&&%%wAS&T&TUUUUUUUUU//#########t	//########### 	 	 	DD	w   	%%wAW&X&XYYYYYYYYY//#########l	//########### 	 	 	DD	o !.4"  	  	Bvvh<//BFF7OO/)W-A-U-W-W!) ,(/# ,     !) ,(/( "7     		))9G*U*UVVVVVVVVV)) &+2$&wK#%	           oo'''''''''h	//########### 	 	 	DD	k 	IHHHHH++B99'))&&ux83D'DEEKKMM 	%%wAR&S&STTTTTTTTT//#########V	//########### 	 	 	DD	Y #--eh;; 	I2FHHO!A,!O!O&&|44 	;;#.#?#?&!!*4*/ +$4B
!% $@ 
$ 
$ 
 
 
 
 
 

 )8(3 ; ; ;9a99::::::::;0--&,"${:K:K .  
 

  	LOOX/JJKKK/<_[]^^^())) 	HOOX+FFGGG4JKKLLL(&,OOO' O+ 
 
 
 	 !!!



!![YY
 
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	

 k#=@T#TUU 	2$/$G$G!$07C#.6$ %H % % T T T T T T Tj
  &&z222))7z*R*RSSSSSSSSSS% % "-!<!<!$07C#.6$	 "= " "      L (==lKKM%%w=&Q&QRRRRRRRRR""=111003M;OO(+}UUU!,+!%2"
 "
 "
 	%&&&
		"9-"V"VZ!!#2)&%( 	
 	
 		
 		
 		
 		
 		
 		
 		
 		
  D D DBBBCCCCC   1Q11555EEFFF	%%wQ&H&HIIIIIIIIII 	 	 	D			//########### 	 	 	DD		//########## 	 	 	D	s  Bc7 C, ,
C:9C:=c7 D c7 AFc7 E1 1
E?>E?FB
c7 H+ +
H98H9<Ac7 J 
J+*J+.?c7 /L 
LLD*c7 Q# #
Q10Q14B.c7 $U   
UUAc7 *A
W5 4c7 5
X&?X!c7 !X&&E.c7 _Ec7 6g 7'f.g  	f.)>f)(+ff)
f!f) f!!f)$g )f..g 2g 
ggh!g<;h<
h	hh		hrb   )fr  rA   os_osfastapir   r   r   r   r   r   r	   fastapi.responsesr
   common_loggingr   sqlalchemy.ormr   openpathrO   dirname__file___floadr"  pydanticr   appr   r  r   app.api.permissionsr   r   r   r   r   app.core.exceptionsr   app.core.i18nr   app.db.sessionr   
app.modelsr   r   r   r   app.schemasr   r   r   'app.services.agent.conversation_managerr    r{  r!   r)   r   routerr%   r3   r;   r,   rC   rE   rS   rW   r:   rX   r.   rj   rl   ru   r   tupler   r   r   intr   r   r   r   HTTP_200_OKr  r  r  r  postHTTP_201_CREATEDr)  putr-  r0  r2  r:  patchr?  r  r  r  r/   r0   r1   <module>r     sN                          0 / / / / / % % % % % % " " " " " "	THMM#(""8,,.JKKV]   *%DIbMM* * * * * * * * * * * * * * *
                                5 4 4 4 4 4 ( ( ( ( ( ( ' ' ' ' ' ' 6 6 6 6 6 6 6 6 6 6 6 6 ? ? ? ? ? ? ? ? ? ? H H H H H H K K K K K K	H			
	#	#	#    )   	! 	! 	! 	! 	!9 	! 	! 	!B B B B B BY03 Y0 Y0 Y0 Y0
#d
 
#sTz 
# 
# 
# 
# H 
&s &ddAR &WZ & & & &LC LD L L L L(K3 K3 K K K Kc c    
3 
3: 
 
 
 
S U38_t%;     3 3:    "$CS $CTD[ $C $C $C $CNtCy s s    @.3 @.4$; @. @. @. @.H +/. .
. 4Z.
3t. . . .b 'V5GHH '&// h!7!788,Y ,Y,Y
,Y ,Y 	,Y
 	,Y ,Y ,Y ,Y IH,Y^ BPVPbcc '&// h!7!788) ))) ) 	)
 ) 	) ) ) ) dc)X C] 344'&// h!7!788	 
 	 	   54 M-88 '&// h!7!788	
 


 	
 	
 
 
 98
 SF<STT '&// !9!9::	  	 	   UT4 M-88
 '&// !9!9::   		
    984 }&*<== '&// !9!9::	  	 	   >=, !v/ABB '&// !9!9::	  	 	   CB4 "0BCC
 '&// !9!9::   		
    DC8 ==
 '&// !:!:;;n nnn n 		n
 n n n >=nb '((LSGTZOO y yI y y' y y y )(y y ys   /BBB