
    $*j3'                     z    d Z ddlmZmZmZmZ ddlmZ ddlm	Z	  G d de          Z
ddlmZ  ede
           d	S )
u   Anthropic Messages API transport.

Delegates to the existing adapter functions in agent/anthropic_adapter.py.
This transport owns format conversion and normalization — NOT client lifecycle.
    )AnyDictListOptional)ProviderTransport)NormalizedResponsec                   d   e Zd ZdZedefd            Zdeeee	f                  de	fdZ
deeee	f                  de	fdZ	 dd	edeeee	f                  deeeee	f                           deee	f         fd
Zde	defdZde	defdZde	deeeef                  fdZdddddddZdedefdZdS )AnthropicTransportu   Transport for api_mode='anthropic_messages'.

    Wraps the existing functions in anthropic_adapter.py behind the
    ProviderTransport ABC.  Each method delegates — no logic is duplicated.
    returnc                     dS )Nanthropic_messages )selfs    ?/home/ubuntu/.hermes/hermes-agent/agent/transports/anthropic.pyapi_modezAnthropicTransport.api_mode   s    ##    messagesc                 R    ddl m} |                    d          } |||          S )u   Convert OpenAI messages to Anthropic (system, messages) tuple.

        kwargs:
            base_url: Optional[str] — affects thinking signature handling.
        r   )convert_messages_to_anthropicbase_url)r   )agent.anthropic_adapterr   get)r   r   kwargsr   r   s        r   convert_messagesz#AnthropicTransport.convert_messages   s>     	JIIIII::j)),,XIIIIr   toolsc                 $    ddl m}  ||          S )z=Convert OpenAI tool schemas to Anthropic input_schema format.r   )convert_tools_to_anthropic)r   r   )r   r   r   s      r   convert_toolsz AnthropicTransport.convert_tools#   s%    FFFFFF))%000r   Nmodelc                    ddl m}  |||||                    dd          |                    d          |                    d          |                    dd          |                    d	d          |                    d
          |                    d          |                    dd          |                    dd                    S )a  Build Anthropic messages.create() kwargs.

        Calls convert_messages and convert_tools internally.

        params (all optional):
            max_tokens: int
            reasoning_config: dict | None
            tool_choice: str | None
            is_oauth: bool
            preserve_dots: bool
            context_length: int | None
            base_url: str | None
            fast_mode: bool
            drop_context_1m_beta: bool
        r   )build_anthropic_kwargs
max_tokensi @  reasoning_configtool_choiceis_oauthFpreserve_dotscontext_lengthr   	fast_modedrop_context_1m_beta)r   r   r   r"   r#   r$   r%   r&   r'   r   r(   r)   )r   r!   r   )r   r   r   r   paramsr!   s         r   build_kwargszAnthropicTransport.build_kwargs)   s    , 	CBBBBB%%zz,66#ZZ(:;;

=11ZZ
E22 **_e<<!::&677ZZ
++jje44!',BE!J!J
 
 
 	
r   responsec           
         ddl }ddlm}m} ddlm} |                    dd          }d}g }	g }
g }g }g }|j        D ]} ||          }d}t          |t                    r" ||          }||
                    |           |j        dk    r|	
                    |j                   m|j        d	v r{|j        d
k    r|

                    |j                   t          |t                    r|
                    |           t          |t                    r|
                    |           |j        dk    r|j        }|r^|                    |          rI|t!          |          d         }ddlm} |                    |          r|                    |          s|}|
                     ||j        ||                    |j                                       | j                            |j        d          }i }|r||d<   t3          d |D                       }t3          d |D                       }|r|r||d<   t5          |	rd                    |	          nd|pd||
rd                    |
          ndd|pd          S )zNormalize Anthropic response to NormalizedResponse.

        Parses content blocks (text, thinking, tool_use), maps stop_reason
        to OpenAI finish_reason, and collects reasoning_details in provider_data.
        r   N)_to_plain_data_sanitize_replay_block)ToolCallstrip_tool_prefixFmcp_textthinkingredacted_thinkingr5   tool_use)registry)idname	argumentsstopreasoning_detailsc              3      K   | ]Z}t          |t                    o@|                    d           dv o)|                    d          p|                    d          V  [dS )typer4   	signaturedataN
isinstancedictr   .0bs     r   	<genexpr>z8AnthropicTransport.normalize_response.<locals>.<genexpr>   s}       #
 #
  q$ 6f!BB6{##4quuV}}#
 #
 #
 #
 #
 #
r   c              3   r   K   | ]2}t          |t                    o|                    d           dk    V  3dS )r?   r7   NrB   rE   s     r   rH   z8AnthropicTransport.normalize_response.<locals>.<genexpr>   sT       
 
 q$?AEE&MMZ$?
 
 
 
 
 
r   anthropic_content_blocks
z

)content
tool_callsfinish_reason	reasoningusageprovider_data)jsonr   r.   r/   agent.transports.typesr0   r   rL   rC   rD   appendr?   r3   r5   r:   
startswithlentools.registryr8   	get_entryr9   dumpsinput_STOP_REASON_MAPstop_reasonanyr   join)r   r,   r   rR   r.   r/   r0   r1   _MCP_PREFIX
text_partsreasoning_partsr=   rM   ordered_blocksblock
block_dictclean_blockr:   stripped_tool_registryrN   rQ   _has_signed_thinking_has_tool_uses                           r   normalize_responsez%AnthropicTransport.normalize_responseP   s]    	RRRRRRRR333333"JJ':EBB

 % +	 +	E'..JK*d++ 7
 54Z@@*"))+666zV##!!%*----@@@:++#**5>::: k400 9%,,[9999
D11 9%,,Z888z))z$ ()E)E (#C$4$4$5$56H JIIIII&00:: ($2$<$<T$B$B('!!H 8!"&**U["9"9     -11(2FOO 	C1BM-.  # #
 #
 $	#
 #
 #
  
  
  
 
#
 
 
 
 
   	GM 	G8FM45!-7ADIIj)))T!)T'6EOfkk/2224'/4
 
 
 	
r   c                     |dS t          |dd          }t          |t                    sdS |st          |dd          dk    S dS )u[  Check Anthropic response structure is valid.

        An empty content list is legitimate when ``stop_reason == "end_turn"``
        — the model's canonical way of signalling "nothing more to add" after
        a tool turn that already delivered the user-facing text. Treating it
        as invalid falsely retries a completed response.
        NFrL   r\   end_turnT)getattrrC   list)r   r,   content_blockss      r   validate_responsez$AnthropicTransport.validate_response   s\     5 9d;;.$// 	5 	H8]D99ZGGtr   c                     t          |dd          }|dS t          |dd          pd}t          |dd          pd}|s|r||dS dS )z=Extract Anthropic cache_read and cache_creation token counts.rP   Ncache_read_input_tokensr   cache_creation_input_tokens)cached_tokenscreation_tokens)rm   )r   r,   rP   cachedwrittens        r   extract_cache_statsz&AnthropicTransport.extract_cache_stats   so    '400=4 91==B%!>BBGa 	IW 	I%+HHHtr   r<   rM   lengthcontent_filter)rl   r7   r"   stop_sequencerefusalmodel_context_window_exceeded
raw_reasonc                 8    | j                             |d          S )z2Map Anthropic stop_reason to OpenAI finish_reason.r<   )r[   r   )r   r~   s     r   map_finish_reasonz$AnthropicTransport.map_finish_reason   s    $((V<<<r   )N)__name__
__module____qualname____doc__propertystrr   r   r   r   r   r   r   r+   r   rj   boolrp   intrx   r[   r   r   r   r   r
   r
      s         $# $ $ $ X$	Jd38n)= 	JC 	J 	J 	J 	J14S#X#7 1C 1 1 1 1 15	%
 %
%
 tCH~&%
 T#s(^,-	%
 
c3h%
 %
 %
 %
Nh
3 h
=O h
 h
 h
 h
T# $    "	C 	HT#s(^4L 	 	 	 	  #)1 =C =C = = = = = =r   r
   )register_transportr   N)r   typingr   r   r   r   agent.transports.baser   rS   r   r
   agent.transportsr   r   r   r   <module>r      s     - , , , , , , , , , , , 3 3 3 3 3 3 5 5 5 5 5 5U= U= U= U= U=* U= U= U=r 0 / / / / /  '); < < < < <r   