
    Zi&                         U d Z ddlZddlmZmZmZmZmZ ddlm	Z	 ddl
mZ e	 G d d             Ze	 G d d	             Z G d
 d      Zdaee   ed<   defdZy)u   LLM 客户端 - DeepSeek 集成    N)AsyncGeneratorOptionalDictAnyList)	dataclass)get_settingsc                   D    e Zd ZU dZeed<   eed<   eeef   ed<   eed<   y)LLMResponseu
   LLM 响应contentmodelusagecostN)	__name__
__module____qualname____doc__str__annotations__r   intfloat     @/home/jang/Projects/ai-researcher/src/integrations/llm_client.pyr   r      s"    LJS>
Kr   r   c                   :    e Zd ZU dZeed<   eeef   ed<   eed<   y)	LLMChoiceu
   LLM 选择indexmessagefinish_reasonN)r   r   r   r   r   r   r   r   r   r   r   r   r      s    J#s(^r   r   c                       e Zd ZdZd Z	 	 	 ddeeeef      dede	e
   dedef
d	Z	 	 ddeeeef      dede	e
   deedf   fd
Z	 ddede	e   deeef   fdZ	 ddedeeef   de	e   defdZy)DeepSeekClientu   DeepSeek LLM 客户端c                     t               }t        |dd      | _        t        |dd      | _        t        |dd      | _        t        | j                        | _        y )NDEEPSEEK_API_KEY DEEPSEEK_BASE_URLzhttps://api.deepseek.com/v1DEEPSEEK_MODELzdeepseek-chat)r	   getattrapi_keybase_urlr   boolenabled)selfsettingss     r   __init__zDeepSeekClient.__init__   sM    >x);R@*=?\]X'7I
DLL)r   Nmessagestemperature
max_tokensstreamreturnc                   K   | j                   st        d      | j                   d}d| j                   dd}| j                  |||d}|r||d<   t        j                         4 d{   }|j                  |||d	
       d{   }	|	j                          |	j                         }
ddd      d{    
j                  di       }|j                  dd      }|j                  dd      }|dz  |dz  z   }t        |
d   d   d   d   |
j                  d| j                        ||      S 7 7 7 ~# 1 d{  7  sw Y   xY ww)u5  
        发送聊天完成请求

        Args:
            messages: 消息列表，格式 [{"role": "user", "content": "..."}]
            temperature: 采样温度
            max_tokens: 最大生成token数
            stream: 是否流式返回

        Returns:
            LLMResponse 对象
        DeepSeek API key not configured/chat/completionsBearer application/jsonAuthorizationzContent-Typer   r/   r0   r2   r1   N      N@headersjsontimeoutr   prompt_tokensr   completion_tokensgư>g>choicesr   r   r   )r   r   r   r   )r+   
ValueErrorr)   r(   r   httpxAsyncClientpostraise_for_statusr?   getr   )r,   r/   r0   r1   r2   urlr>   payloadclientresponsedatar   rA   rB   r   s                  r   chat_completionzDeepSeekClient.chat_completion#   sb    & ||>??01&t||n5.

 ZZ &	
 $.GL!$$& 	# 	#&#[[gGUY[ZZH%%'==?D	# 	# "%		/15!II&91=(+<x+GGOA&y1)<((7DJJ/	
 	
	#Z	# 	# 	# 	#s[   A)E+D3,E/D9D5	$D9-E8D79A;E5D97E9E?E EEc                
  K   | j                   st        d      | j                   d}d| j                   dd}| j                  ||dd}|r||d<   t        j                         4 d	{   }|j                  d
|||d      4 d	{   }|j                          |j                         2 3 d	{   }	|	j                  d      s|	dd	 }
|
dk(  r n;dd	l}	 |j                  |
      }|d   d   j                  di       }d|v r|d    bd	d	d	      d	{    d	d	d	      d	{    y	7 7 7 # |j                  t        f$ r Y w xY w6 D7 8# 1 d	{  7  sw Y   HxY w7 ?# 1 d	{  7  sw Y   y	xY ww)u   
        流式聊天完成

        Args:
            messages: 消息列表
            temperature: 采样温度
            max_tokens: 最大生成token数

        Yields:
            生成的文本片段
        r5   r6   r7   r8   r9   Tr;   r1   NPOSTr<   r=   zdata:    z[DONE]r   rC   deltar   )r+   rD   r)   r(   r   rE   rF   r2   rH   aiter_lines
startswithr?   loadsrI   JSONDecodeErrorKeyError)r,   r/   r0   r1   rJ   r>   rK   rL   rM   linerN   r?   chunkrS   s                 r   chat_completion_streamz%DeepSeekClient.chat_completion_streamZ   s    " ||>??01&t||n5.

 ZZ &	
 $.GL!$$& 	% 	%&}}W7D %  % %))+"*"6"6"8 % %$x0#ABx8+!#%$(JJt$4E$))$4Q$7$;$;GR$HE(E1&+I&6 6% %	% 	% 	%%% !% 4 4h? %$% #9	% % % %	% 	% 	% 	%s   A)F+D2,F/E.
D4E.!E/E3D6
4E7E
E5D8EE.EE.!F,E,-F4E.6E8E	EE	EE.E)	E E)	%E.,F.F 4E75F <Fquerycontextc                 d  K   ddddd| d|xs i  dg}| j                  |d       d	{   }|j                  }d
d	l}d
d	l}	 |j	                  d||j
                        }|r!|j                  |j                               }	|	S 	 dg dgd|v xs d|v ddS 7 k# |j                  $ r Y $w xY ww)u   
        分析用户查询意图

        Args:
            query: 用户查询
            context: 上下文信息

        Returns:
            分析结果：intent, entities, required_skills, confidence
        systemub  你是一个企业智能助手，负责分析用户的查询意图。
请分析以下查询，返回JSON格式的结果：
{
    "intent": "查询意图（query_employee/query_department/analyze_data/other）",
    "entities": ["提取的实体"],
    "required_skills": ["需要的技能"],
    "needs_reasoning": true/false,
    "confidence": 0.0-1.0
}roler   useru	   查询：   
上下文：g333333?r0   Nr   z\{.*\}other
data_queryu   分析u   建议g      ?)intententitiesrequired_skillsneeds_reasoning
confidence)	rO   r   r?   researchDOTALLrV   grouprW   )
r,   r\   r]   r/   rM   r   r?   rl   
json_matchresults
             r   analyze_queryzDeepSeekClient.analyze_query   s     " ! &ug^GMr?K
& --hC-HH"" 		9gryyAJJ$4$4$67   ,~'50EH4E
 	
! I ## 		s3   +B0BB0?B B0B-*B0,B--B0rN   c           	         K   ddddd| d| d|xs i  dg}| j                  |d	       d
{   }|j                  S 7 w)u   
        基于查询和数据生成回复

        Args:
            query: 原始查询
            data: 查询到的数据
            context: 上下文信息

        Returns:
            生成的回复文本
        r_   u   你是一个专业的企业智能助手。请基于提供的数据回答用户的问题。
要求：
1. 回答简洁明了
2. 如果是数据分析，给出关键洞察
3. 标注数据来源
4. 如果涉及推断，明确标注[基于数据推断]r`   rb   u	   问题：u
   
数据：rc   ffffff?rd   N)rO   r   )r,   r\   rN   r]   r/   rM   s         r   generate_responsez DeepSeekClient.generate_response   sm     & !< &ug[nW]XZO\
  --hC-HH Is   .AAA)rt   NF)rt   N)N)r   r   r   r   r.   r   r   r   r   r   r   r*   r   rO   r   r[   r   rr   ru   r   r   r   r!   r!      s    * !$(5
tCH~&5
 5
 SM	5

 5
 
5
t !$(	3%tCH~&3% 3% SM	3%
 
T		"3%p #'8
8
 $8
 
c3h	8
| #'	" "  38n"  $	" 
 
" r   r!   _llm_clientr3   c                  .    t         
t               a t         S )u&   获取全局 LLM 客户端（单例）)rv   r!   r   r   r   get_llm_clientrx      s     $&r   )r   rE   typingr   r   r   r   r   dataclassesr   
src.configr	   r   r   r!   rv   r   rx   r   r   r   <module>r|      ss    %  < < ! #      R  R l )-Xn% , r   