
    :i$                     v    S r SSKJrJrJrJr  SSKrSSKrSSKJ	r	  \R                  " \5      r " S S\	5      rg)u]   
Claude (Anthropic) 提供商实现

Claude API 格式与 OpenAI 略有不同，需要适配
    )DictListAny	GeneratorN   )BaseAIProviderc                      \ rS rSrSr\S\4S j5       r\S\4S j5       rS\4S jr	S\4S jr
S\\   4S jrS	 rS
\\\\4      S\4S jrS\\   S\\   4S jr   SS
\\\\4      S\\   S\S\S\\\4   4
S jjr   SS
\\\\4      S\\   S\S\S\\\\4   SS4   4
S jjrS\\\4   4S jrS
\\\\4      S\S\S\S\\\4   4
S jrSrg)ClaudeProvider   u   Anthropic Claude API 提供商returnc                     g)Nclaude selfs    X   /Users/yu22x/Desktop/ddd_副本5/ctf/app/services/ai_driver/providers/claude_provider.pyprovider_typeClaudeProvider.provider_type   s        c                     g)NzClaude (Anthropic)r   r   s    r   provider_nameClaudeProvider.provider_name   s    #r   c                     g)Nzhttps://api.anthropic.com/v1r   r   s    r   get_default_base_url#ClaudeProvider.get_default_base_url   s    -r   c                     g)Nclaude-3-5-sonnet-20241022r   r   s    r   get_default_model ClaudeProvider.get_default_model   s    +r   c                 
    / SQ$ )N)r   zclaude-3-opus-20240229zclaude-3-sonnet-20240229zclaude-3-haiku-20240307r   r   s    r   get_available_models#ClaudeProvider.get_available_models"   s    
 	
r   c                     SSK Jn  SnU R                  (       a?  U R                  U R                  5       :w  a!  U R                  nU R	                  SSU 35        U" U R
                  UU R                  S9$ ! [         a    [        S5      ef = f)u   获取 Anthropic 客户端r   )	AnthropicNinfou   使用自定义 Base URL: )api_keybase_urltimeoutu.   请安装 anthropic 库: pip install anthropic)	anthropicr$   r'   r   _logr&   r(   ImportError)r   r$   custom_base_urls      r   _get_clientClaudeProvider._get_client*   s    	P+ #O}}$2K2K2M!M"&--		&$>>O"PQ( 
  	PNOO	Ps   A3A6 6Bmessagesc           	      @   Sn/ nU H  nUR                  SS5      nUR                  SS5      nUS:X  a  UnM1  US:X  a  UR                  SUS.5        MM  US	:X  a+  UR                  SS
UR                  SS5      US./S.5        M~  UR                  SUS.5        M     X#4$ )u   格式化消息为 Claude 格式

Claude 需要将 system 消息单独提取出来

Returns:
    (system_prompt, messages_list)
Nroleusercontent system	assistant)r1   r3   tooltool_resulttool_call_id)typetool_use_idr3   getappend)r   r/   system_promptformatted_messagesmsgr1   r3   s          r   _format_messagesClaudeProvider._format_messages>   s     C7766*Dggi,Gx '$"))'&+  "))" -'*ww~r'B#*!  +  #))"&+ - 6 00r   toolsc           	          / nU Hq  nUR                  S5      S:X  d  M  UR                  S0 5      nUR                  UR                  SS5      UR                  SS5      UR                  S0 5      S.5        Ms     U$ )u&   格式化工具定义为 Claude 格式r:   functionnamer4   description
parameters)rG   rH   input_schemar<   )r   rD   claude_toolsr7   funcs        r   _format_toolsClaudeProvider._format_toolsf   sw    Dxx:-xx
B/## HHVR0#'88M2#>$(HH\2$>%   r   Ntemperature
max_tokensc                    U R                  5       nU R                  U5      u  pxU R                  UU=(       d    SUS.n	U(       a  XyS'   U(       a  U R                  U5      U	S'    U R	                  SSU R                   35        UR
                  R                  " S
0 U	D6n
U R                  U
5      $ ! [         a$  nU R	                  SS[        U5       35        e S	nAff = f)u   执行聊天补全   )modelr/   rP   rO   r5   rD   r%   u   发送请求到 erroru   API 调用失败: Nr   )
r-   rB   rS   rM   r*   r/   create_parse_response	Exceptionstr)r   r/   rD   rO   rP   kwargsclientr?   r@   request_paramsresponsees               r   chatClaudeProvider.chats   s     !!# -1,A,A(,K) ZZ*$,&	
 '48$&*&8&8&?N7#	IIf 0=>--??H''11 	IIg!3CF8<=	s   %AB1 1
C;CCc           	   +   &  #    U R                  5       nU R                  U5      u  pxU R                  UU=(       d    SUSS.n	U(       a  XyS'   U(       a  U R                  U5      U	S'    U R	                  SSU R                   35        UR
                  R                  " S0 U	D6 n
Sn/ nU
 GH  nUR                  S	:X  ap  [        UR                  S
5      (       a6  XR                  R                  -  nSUR                  R                  US.v   Me  [        UR                  S5      (       a  M  M  UR                  S:X  a^  UR                  R                  S:X  aB  UR                  UR                  R                  SUR                  R                  SS.S.5        M  M  UR                  S:X  d  GM  SSUU(       a  UOSS.v   GM     SSS5        g! , (       d  f       g= f! [         a$  nU R	                  SS[!        U5       35        e SnAff = f7f)u   流式聊天补全rR   T)rS   r/   rP   rO   streamr5   rD   r%   u   开始流式请求到 r4   content_block_deltatextr3   )r:   r3   accumulatedpartial_jsoncontent_block_starttool_userF   rG   	argumentsidr:   rF   message_stopfinishstopN)r:   finish_reasonr3   
tool_callsrT   u   流式 API 调用失败: r   )r-   rB   rS   rM   r*   r/   ra   r:   hasattrdeltarc   content_blockr>   rk   rG   rW   rX   )r   r/   rD   rO   rP   rY   rZ   r?   r@   r[   ra   collected_contentcollected_tool_callseventr]   s                  r   chat_streamClaudeProvider.chat_stream   s     !!#,0,A,A(,K) ZZ*$,&
 '48$&*&8&8&?N7#)	IIf 6tzzlCD''9.9V$&!')$#Ezz%::"5;;77-1A1AA-(1+0;;+;+;/@# 
 %U[[.AA  B '<< ..33zA077&+&9&9&<&<(2,1,?,?,D,D13-"9  B ~5$,-3'8BV*>\`	 3 $	 :99H  	IIg!:3q6(CD	sU   A%H(;G  #DG/GG  H
GG  HG   
H*H		HHc           
         SUR                   SSS.nUR                   H  nUR                  S:X  a  US==   UR                  -  ss'   M,  UR                  S:X  d  M>  US   c  / US'   US   R	                  UR
                  SUR                  [        UR                  [        5      (       a   [        R                  " UR                  5      OUR                  S	.S
.5        M     UR                  (       a\  UR                  R                  UR                  R                  UR                  R                  UR                  R                  -   S.US'   U$ )u   解析 Claude 响应r4   N)r3   ro   rp   usagerc   r3   rg   rp   rF   rh   rj   )prompt_tokenscompletion_tokenstotal_tokensrz   )stop_reasonr3   r:   rc   r>   rk   rG   
isinstanceinputdictjsondumpsrz   input_tokensoutput_tokens)r   r\   resultblocks       r   rV   ClaudeProvider._parse_response   s    %11	
 %%EzzV#y!UZZ/!z),'/+-F<(|$++((& %

@J5;;X\@]@]TZZ%<chcncn!-  &  >>!)!<!<%-^^%A%A ( ; ;hnn>Z>Z ZF7O r   r9   	tool_namer8   c                 V    USUUUS./-   nU R                   " U4SU R                  0UD6$ )u'   继续对话，传入工具执行结果r7   )r1   r9   rG   r3   rD   )r^   _tools)r   r/   r9   r   r8   rY   messages_with_results          r   continue_with_tool_result(ClaudeProvider.continue_with_tool_result  sE      (("	,
 +   yy-KT[[KFKKr   r   )Ngffffff?N)__name__
__module____qualname____firstlineno____doc__propertyrX   r   r   r   r   r   r!   r-   r   tuplerB   rM   floatintr   r^   r   rw   rV   r   __static_attributes__r   r   r   r
   r
      s   (s   $s $ $.c .,3 ,
d3i 
P(&1d38n)= &1% &1P4: $t*   ! #tCH~&# Dz# 	#
 # 
c3h#P ! DtCH~&D DzD 	D
 D 
4S>4-	.DL!4S> !FLtCH~&L L 	L
 L 
c3hLr   r
   )r   typingr   r   r   r   loggingr   baser   	getLoggerr   loggerr
   r   r   r   <module>r      s;    . -    			8	$AL^ ALr   