
    j                     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    9/usr/local/lib/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} ddlm} |                    dd          }d}g }g }	g }
g }|j        D ]4}|j        dk    r|                    |j	                   )|j        d	k    rP|	                    |j
                    ||          }t          |t                    r|
                    |           |j        d
k    r|j        }|r^|                    |          rI|t          |          d         }ddlm} |                    |          r|                    |          s|}|                     ||j        ||                    |j                                       6| j                            |j        d          }i }|
r|
|d<   t1          |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)ToolCallstrip_tool_prefixFmcp_textthinkingtool_use)registry)idname	argumentsstopreasoning_details
z

)content
tool_callsfinish_reason	reasoningusageprovider_data)jsonr   r.   agent.transports.typesr/   r   r<   typeappendr2   r3   
isinstancedictr7   
startswithlentools.registryr5   	get_entryr6   dumpsinput_STOP_REASON_MAPstop_reasonr   join)r   r,   r   rB   r.   r/   r0   _MCP_PREFIX
text_partsreasoning_partsr:   r=   block
block_dictr7   stripped_tool_registryr>   rA   s                      r   normalize_responsez%AnthropicTransport.normalize_responseP   sY    	::::::333333"JJ':EBB

% 	 	EzV##!!%*----z))&&u~666+^E22
j$// 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-.!-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.
        NFr<   rO   end_turnT)getattrrF   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.r@   Ncache_read_input_tokensr   cache_creation_input_tokens)cached_tokenscreation_tokens)r[   )r   r,   r@   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   r9   r=   lengthcontent_filter)rZ   r4   r"   stop_sequencerefusalmodel_context_window_exceeded
raw_reasonc                 8    | j                             |d          S )z2Map Anthropic stop_reason to OpenAI finish_reason.r9   )rN   r   )r   rl   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   rX   boolr^   intrf   rN   rn   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=
3 =
=O =
 =
 =
 =
~# $    "	C 	HT#s(^4L 	 	 	 	  #)1 =C =C = = = = = =r   r
   )register_transportr   N)rr   typingr   r   r   r   agent.transports.baser   rC   r   r
   agent.transportsrw   r   r   r   <module>r{      s     - , , , , , , , , , , , 3 3 3 3 3 3 5 5 5 5 5 5j= j= j= j= j=* j= j= j=\ 0 / / / / /  '); < < < < <r   