o
    i?                     @   s   d Z ddlZddlZddlmZ ddlmZmZmZm	Z	 ddl
mZmZ ddlmZ ddlmZ ddl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mZ G dd de	ZG dd dee ZdS )z"Anthropic LLM adapter for Pipecat.    N)	dataclass)AnyDictList	TypedDict)	NOT_GIVENNotGiven)MessageParam)ToolUnionParam)logger)BaseLLMAdapter)FunctionSchema)ToolsSchema)
LLMContextLLMContextMessageLLMSpecificMessageLLMStandardMessagec                   @   s6   e Zd ZU dZeeB ed< ee ed< ee	 ed< dS )AnthropicLLMInvocationParamsz:Context-based parameters for invoking Anthropic's LLM API.systemmessagestoolsN)
__name__
__module____qualname____doc__strr   __annotations__r   r	   r
    r   r   _/home/ubuntu/.local/lib/python3.10/site-packages/pipecat/adapters/services/anthropic_adapter.pyr      s
   
 r   c                   @   s
  e Zd ZdZedefddZdedede	fddZ
dedeeeef  fd	d
ZeG dd dZdee defddZdedefddZdedefddZdedefddZdee dee fddZededeeef fddZdedeeeef  fddZd S )!AnthropicLLMAdapterzAdapter for converting tool schemas to Anthropic's function-calling format.

    This adapter handles the conversion of Pipecat's standard function schemas
    to the specific format required by Anthropic's Claude models for function calling.
    returnc                 C   s   dS )zFGet the identifier used in LLMSpecificMessage instances for Anthropic.	anthropicr   selfr   r   r   id_for_llm_specific_messages-   s   z0AnthropicLLMAdapter.id_for_llm_specific_messagescontextenable_prompt_cachingc                 C   s<   |  | |}|j|r| |jn|j| |jpg dS )aR  Get Anthropic-specific LLM invocation parameters from a universal LLM context.

        Args:
            context: The LLM context containing messages, tools, etc.
            enable_prompt_caching: Whether prompt caching should be enabled.

        Returns:
            Dictionary of parameters for invoking Anthropic's LLM API.
        )r   r   r   ) _from_universal_context_messagesget_messagesr   _with_cache_control_markersr   from_standard_toolsr   )r#   r%   r&   r   r   r   r   get_llm_invocation_params2   s   z-AnthropicLLMAdapter.get_llm_invocation_paramsc                 C   s   |  | |j}g }|D ]9}t|}d|v rAt|d trA|d D ]}|d dkr1d|d d< |d dkr@|dr@d|d< q#|| q|S )	aZ  Get messages from a universal LLM context in a format ready for logging about Anthropic.

        Removes or truncates sensitive data like image content for safe logging.

        Args:
            context: The LLM context containing messages.

        Returns:
            List of messages in a format ready for logging about Anthropic.
        contenttypeimagez...sourcedatathinking	signature)	r'   r(   r   copydeepcopy
isinstancelistgetappend)r#   r%   r   messages_for_loggingmessagemsgitemr   r   r   get_messages_for_loggingJ   s   
z,AnthropicLLMAdapter.get_messages_for_loggingc                   @   s*   e Zd ZU dZee ed< eeB ed< dS )z%AnthropicLLMAdapter.ConvertedMessageszLContainer for Anthropic-formatted messages converted from universal context.r   r   N)	r   r   r   r   r   r	   r   r   r   r   r   r   r   ConvertedMessagesf   s   
 r>   universal_context_messagesc           	   
      s  t }g }z fdd|D }W n ty) } ztd|  W Y d }~nd }~ww |rL|d d dkrLt|dkrAd|d d< n|d d	 }|d |D ]}|d dkrZd|d< qNd}|t|d k r|| }||d  }|d |d krt|d	 trd
|d	 dg|d	< t|d	 trd
|d	 dg|d	< |d	 |d	  ||d  n|d7 }|t|d k se|D ]+}t|d	 tr|d	 dkrd|d	< qt|d	 t	rt|d	 dkrd
ddg|d	< q j
||dS )Nc                       g | ]}  |qS r   )_from_universal_context_message).0mr"   r   r   
<listcomp>u       zHAnthropicLLMAdapter._from_universal_context_messages.<locals>.<listcomp>zError mapping messages: r   roler      userr,   textr-   rI    (empty))r   r   )r   	Exceptionr   errorlenpopr5   r   extendr6   r>   )	r#   r?   r   r   er:   icurrent_messagenext_messager   r"   r   r'   m   sL   

z4AnthropicLLMAdapter._from_universal_context_messagesr:   c                 C   s   t |tr
| |S | |S )N)r5   r    _from_anthropic_specific_message_from_standard_message)r#   r:   r   r   r   rA      s   


z3AnthropicLLMAdapter._from_universal_context_messagec                 C   s\   t |jtr(|jddkr(|jd }r(|jd }r(dd||dgdS t|jS )	a'  Convert LLMSpecificMessage to Anthropic format.

        Anthropic-specific messages may either be special thought messages that
        need to be handled in a special way, or messages already in Anthropic
        format.

        Args:
            message: Anthropic-specific message.
        r-   thoughtrI   r2   	assistantr1   )r-   r1   r2   rF   r,   )r5   r:   dictr7   r3   r4   )r#   r:   rI   r2   r   r   r   rV      s   
z4AnthropicLLMAdapter._from_anthropic_specific_messagec                 C   s  t |}|d dkrdd|d |d dgdS |d	rK|d	 }d
g d}|D ]}|d }t|d }d|d |d |d}|d | q)|S |d}t|tr]|dkr[d}|S t|tr|D ]r}	|	d dkrw|	d dkrwd|	d< |	d dkr|	d d 	dr|	d d }
|

dd 
dd }d|	d< d||

dd d|	d < |	d= qe|	d d 	d!rd|	d< d|	d d d"|	d < |	d= qe|	d d }
td#|
  qed$d% t|D }d&d% t|D }t|dkr|r|d }|d }||kr||}||| |S )'ae  Convert standard universal context message to Anthropic format.

        Handles conversion of text content, tool calls, and tool results.
        Empty text content is converted to "(empty)".

        Args:
            message: Message in standard universal context format.

        Returns:
            Message in Anthropic format.

        Examples:
            Input standard format::

                {
                    "role": "assistant",
                    "tool_calls": [
                        {
                            "id": "123",
                            "function": {"name": "search", "arguments": '{"q": "test"}'}
                        }
                    ]
                }

            Output Anthropic format::

                {
                    "role": "assistant",
                    "content": [
                        {
                            "type": "tool_use",
                            "id": "123",
                            "name": "search",
                            "input": {"q": "test"}
                        }
                    ]
                }
        rF   toolrH   tool_resulttool_call_idr,   )r-   tool_use_idr,   rZ   
tool_callsrY   function	argumentstool_useidname)r-   rd   re   inputrK   rL   r-   rI   	image_urlurlzdata::rG   ;r   r.   base64,)r-   
media_typer0   r/   http)r-   rh   zUnsupported 'image_url': c                 S       g | ]\}}|d  dkr|qS )r-   r.   r   rB   rS   r<   r   r   r   rD   7       z>AnthropicLLMAdapter._from_standard_message.<locals>.<listcomp>c                 S   ro   rJ   r   rp   r   r   r   rD   8  rq   )r3   r4   r7   jsonloadsr8   r5   r   r6   
startswithsplitr   warning	enumeraterO   rP   insert)r#   r:   tcret	tool_callra   rb   new_tool_user,   r<   rh   	mime_typeimage_indicestext_indicesimg_idxfirst_txt_idx
image_itemr   r   r   rW      sv   
'




,




z*AnthropicLLMAdapter._from_standard_messager   c              
   C   s   dt fdd}z7t|}g }tt|d ddD ]}|| d dkr0|| t|dkr0 nq|D ]}|||  q3|W S  tyZ } ztd	|  |W  Y d
}~S d
}~ww )zAdd cache control markers to messages for prompt caching.

        Args:
            messages: List of messages in Anthropic format.

        Returns:
            List of messages with cache control markers added.
        r:   c                 S   s:   t | d trd| d dg| d< ddi| d d d< d S )Nr,   rI   rJ   r-   	ephemeralcache_control)r5   r   )r:   r   r   r   add_cache_control_markerM  s   zQAnthropicLLMAdapter._with_cache_control_markers.<locals>.add_cache_control_markerrG   r   rF   rH      z#Error adding cache control marker: N)	r	   r3   r4   rangerO   r8   rM   r   rN   )r#   r   r   messages_with_markersuser_message_indicesrS   indexrR   r   r   r   r)   C  s$   


z/AnthropicLLMAdapter._with_cache_control_markersra   c                 C   s   | j | jd| j| jddS )zConvert a single function schema to Anthropic's format.

        Args:
            function: The function schema to convert.

        Returns:
            Dictionary containing the function definition in Anthropic's format.
        object)r-   
propertiesrequired)re   descriptioninput_schema)re   r   r   r   )ra   r   r   r   _to_anthropic_function_formatr  s   z1AnthropicLLMAdapter._to_anthropic_function_formattools_schemac                    s   |j } fdd|D S )zConvert function schemas to Anthropic's function-calling format.

        Args:
            tools_schema: The tools schema containing functions to convert.

        Returns:
            List of function definitions formatted for Anthropic's API.
        c                    r@   r   )r   )rB   funcr"   r   r   rD     rE   z@AnthropicLLMAdapter.to_provider_tools_format.<locals>.<listcomp>)standard_tools)r#   r   functions_schemar   r"   r   to_provider_tools_format  s   	z,AnthropicLLMAdapter.to_provider_tools_formatN)r   r   r   r   propertyr   r$   r   boolr   r+   r   r   r   r=   r   r>   r   r'   r	   rA   r   rV   r   rW   r)   staticmethodr   r   r   r   r   r   r   r   r   &   s4    

;#s/"r   ) r   r3   rr   dataclassesr   typingr   r   r   r   r!   r   r   anthropic.types.message_paramr	    anthropic.types.tool_union_paramr
   logurur   !pipecat.adapters.base_llm_adapterr   (pipecat.adapters.schemas.function_schemar   %pipecat.adapters.schemas.tools_schemar   *pipecat.processors.aggregators.llm_contextr   r   r   r   r   r   r   r   r   r   <module>   s   