o
    ưiZ                  	   @   s  d Z ddlmZmZmZmZ ddlZddlZddlm	Z	 ddl
mZmZ ddlmZ ddlmZmZmZmZmZ ddlmZ d	ee d
efddZdee ded
efddZdedee d
eeee f fddZG dd deZG dd deZdeej ef d
efddZ!dS )z6
This file contains common utils for anthropic calls.
    )DictListOptionalUnionN)get_file_ids_from_messages)BaseLLMModelInfoBaseTokenCounter)BaseLLMException)ANTHROPIC_HOSTED_TOOLSANTHROPIC_OAUTH_BETA_HEADERANTHROPIC_OAUTH_TOKEN_PREFIXAllAnthropicToolsValuesAnthropicMcpServerTool)AllMessageValuesvaluereturnc                 C   s,   | du rdS |  dr| dd } |  tS )zACheck if a value contains an Anthropic OAuth token (sk-ant-oat*).NFBearer    )
startswithr   )r    r   Z/home/app/Keep/.python/lib/python3.10/site-packages/litellm/llms/anthropic/common_utils.pyis_anthropic_oauth_key   s
   

r   existingnew_betac                 C   s4   | s|S dd |  dD }|| dt|S )zNMerge a new beta value into an existing comma-separated anthropic-beta header.c                 S   s   h | ]
}|  r|  qS r   )strip).0br   r   r   	<setcomp>&   s    z&_merge_beta_headers.<locals>.<setcomp>,)splitaddjoinsorted)r   r   betasr   r   r   _merge_beta_headers"   s
   
r$   headersapi_keyc                 C   s   |  dd}|r.|dt r.|dd}| dd t|  dt| d< d| d< | |fS |rP|trP| dd d| | d< t|  dt| d< d| d< | |fS )	aQ  
    Handle Anthropic OAuth token detection and header setup.

    If an OAuth token is detected in the Authorization header, extracts it
    and sets the required OAuth headers.

    Args:
        headers: Request headers dict
        api_key: Current API key (may be None)

    Returns:
        Tuple of (updated headers, api_key)
    authorization r   	x-api-keyNanthropic-betatrue)anthropic-dangerous-direct-browser-access)getr   r   replacepopr$   r   )r%   r&   auth_headerr   r   r   !optionally_handle_anthropic_oauth+   s"   

r1   c                       s0   e Zd Z	ddedeej f fddZ  ZS )AnthropicErrorNstatus_coder%   c                    s   t  j|||d d S )N)r3   messager%   )super__init__)selfr3   r4   r%   	__class__r   r   r6   Q   s   zAnthropicError.__init__N)	__name__
__module____qualname__intr   httpxHeadersr6   __classcell__r   r   r8   r   r2   P   s    r2   c                #   @   s  e Zd Zdee defddZdee defddZdeee	  defdd	Z
d
eee  dee fddZd
eee  defddZdee defddZd
ee defddZd
ee defddZd
ee defddZededefddZ	dLdee dee defddZd
ee defddZdee defd d!Zd"ee deee  fd#d$Zd%edefd&d'Z			(	(	(dMdedee d)ee d*ed+ed,edee fd-d.Z			(	(	(	(	(	(	(	(	(	(		(	(dNd/ed0ee d)ee d*ed1ed+ed,ed2ed3ed4ed5ed6ed7ed8eee  d9ed:edef"d;d<Z		dOd=ededee ded>ed/ee d?ee defd@dAZedLd?ee dee fdBdCZedLd/ee dee fdDdEZ edLdee dee fdFdGZ!	dOd/ee d?ee dee fdHdIZ"dee# fdJdKZ$dS )PAnthropicModelInfomessagesr   c                 C   sZ   |D ](}| dddur dS | d}|dur*t|tr*|D ]
}d|v r)  dS qqdS )z
        Return if {"cache_control": ..} in message content block

        Used to check if anthropic prompt caching headers need to be set.
        Zcache_controlNTcontentF)r-   
isinstancelist)r7   rC   r4   Z_message_contentrD   r   r   r   is_cache_control_set[   s   
z'AnthropicModelInfo.is_cache_control_setc                 C   s   t |}t|dkS )z`
        Return if {"source": {"type": "file", "file_id": ..}} in message content block
        r   )r   len)r7   rC   Zfile_idsr   r   r   is_file_id_usedl   s   z"AnthropicModelInfo.is_file_id_usedmcp_serversc                 C   s   |d u rdS |r
dS dS )NFTr   )r7   rJ   r   r   r   is_mcp_server_useds   s
   z%AnthropicModelInfo.is_mcp_server_usedtoolsc                 C   s<   |du rdS |D ]}d|v r|d  dr|d   S qdS )zKReturns the computer tool version if used, e.g. 'computer_20250124' or NoneNtypeZ	computer_)r   r7   rL   toolr   r   r   is_computer_tool_used|   s   z(AnthropicModelInfo.is_computer_tool_usedc                 C   s:   |du rdS |D ]}d|v r|d  tjjr dS qdS )z'Returns True if web_search tool is usedNFrM   T)r   r
   Z
WEB_SEARCHr   rN   r   r   r   is_web_search_tool_used   s   z*AnthropicModelInfo.is_web_search_tool_usedc                 C   sZ   |D ](}d|v r*|d dur*t |d tr*|d D ]}d|v r)|d dkr)  dS qqdS )z=
        Set to true if media passed into messages.

        rD   NrM   textTF)rE   rF   )r7   rC   r4   rD   r   r   r   is_pdf_used   s   zAnthropicModelInfo.is_pdf_usedc                 C   s0   |sdS |D ]}| dd}|dv r dS qdS )zK
        Check if tool search tools are present in the tools list.
        FrM   r(   )Ztool_search_tool_regex_20251119Ztool_search_tool_bm25_20251119Tr-   r7   rL   rO   Z	tool_typer   r   r   is_tool_search_used   s   z&AnthropicModelInfo.is_tool_search_usedc                 C   s|   |sdS |D ]5}| dd}|rt|trd|v r dS | di }t|tr;| dd}|r;t|tr;d|v r; dS qdS )z
        Check if programmatic tool calling is being used (tools with allowed_callers field).

        Returns True if any tool has allowed_callers containing 'code_execution_20250825'.
        Fallowed_callersNcode_execution_20250825Tfunction)r-   rE   rF   dict)r7   rL   rO   rW   rY   Zfunction_allowed_callersr   r   r   !is_programmatic_tool_calling_used   s"   
z4AnthropicModelInfo.is_programmatic_tool_calling_usedc                 C   s   |sdS |D ]9}| dd}|rt|trt|dkr dS | di }t|tr?| dd}|r?t|tr?t|dkr? dS qdS )z
        Check if input_examples is being used in any tools.

        Returns True if any tool has input_examples field.
        Finput_examplesNr   TrY   )r-   rE   rF   rH   rZ   )r7   rL   rO   r\   rY   Zfunction_input_examplesr   r   r   is_input_examples_used   s*   
z)AnthropicModelInfo.is_input_examples_usedmodelc                    s   |    t fdddD S )zBCheck if the model is a Claude 4.6 model (Opus 4.6 or Sonnet 4.6).c                 3   s    | ]}| v V  qd S r:   r   )r   vZmodel_lowerr   r   	<genexpr>   s
    
z:AnthropicModelInfo._is_claude_4_6_model.<locals>.<genexpr>)zopus-4-6Zopus_4_6zopus-4.6zopus_4.6z
sonnet-4-6Z
sonnet_4_6z
sonnet-4.6z
sonnet_4.6)loweranyr^   r   r`   r   _is_claude_4_6_model   s   z'AnthropicModelInfo._is_claude_4_6_modelNoptional_paramsc                 C   s   |sdS |r|  |rdS |r)d| v sd| v r)|d}|r)t|tr)dS |d}|rCt|trC|d}|rCt|trCdS dS )u*  
        Check if effort parameter is being used and requires a beta header.

        Returns True if effort-related parameters are present and
        the model requires the effort beta header. Claude 4.6 models
        use output_config as a stable API feature — no beta header needed.
        Fzopus-4-5Zopus_4_5reasoning_effortToutput_configeffort)re   rb   r-   rE   strrZ   )r7   rf   r^   rg   rh   ri   r   r   r   is_effort_used   s   



z!AnthropicModelInfo.is_effort_usedc                 C   s0   |sdS |D ]}| dd}|dkr dS qdS )z
        Check if code execution tool is being used.

        Returns True if any tool has type "code_execution_20250825".
        FrM   r(   rX   TrT   rU   r   r   r   is_code_execution_tool_used  s   z.AnthropicModelInfo.is_code_execution_tool_usedc                 C   sL   |sdS | d}|r$t|tr$| d}|r$t|tr$t|dkr$dS dS )z
        Check if container with skills is being used.

        Returns True if optional_params contains container with skills.
        F	containerskillsr   T)r-   rE   rZ   rF   rH   )r7   rf   rm   rn   r   r   r   is_container_with_skills_used+  s   

z0AnthropicModelInfo.is_container_with_skills_usedanthropic_beta_headerc                 C   s   |d u rd S | dS )Nr   )r   )r7   rp   r   r   r    _get_user_anthropic_beta_headers;  s   
z3AnthropicModelInfo._get_user_anthropic_beta_headerscomputer_tool_versionc                 C   s   ddd}| |dS )a  
        Get the appropriate beta header for a given computer tool version.

        Args:
            computer_tool_version: The computer tool version (e.g., 'computer_20250124', 'computer_20241022')

        Returns:
            The corresponding beta header string
        zcomputer-use-2025-01-24zcomputer-use-2024-10-22)Zcomputer_20250124Zcomputer_20241022rT   )r7   rr   Zcomputer_tool_beta_mappingr   r   r   get_computer_tool_beta_headerB  s   z0AnthropicModelInfo.get_computer_tool_beta_headerFcomputer_tool_usedprompt_caching_setfile_id_usedmcp_server_usedc                 C   st   ddl m} g }| ||}	|	r|| |r!| |}
||
 |r-|d |d |r4|d tt|S )z
        Get list of common beta headers based on the features that are active.

        Returns:
            List of beta header strings
        r   ANTHROPIC_EFFORT_BETA_HEADERfiles-api-2025-04-14code-execution-2025-05-22mcp-client-2025-04-04)litellm.types.llms.anthropicry   rk   appendrs   rF   set)r7   r^   rf   rt   ru   rv   rw   ry   r#   effort_usedbeta_headerr   r   r   get_anthropic_beta_listT  s   





z*AnthropicModelInfo.get_anthropic_beta_listr&   anthropic_versionpdf_usedweb_search_tool_usedtool_search_usedprogrammatic_tool_calling_usedinput_examples_usedr   is_vertex_requestuser_anthropic_beta_headerscode_execution_tool_usedcontainer_with_skills_usedc                 C   s@  t  }|r| |}|| |r|d |d |r"|d |	s(|
s(|r3ddlm} || |r@ddlm} || |rG|d |rN|d |oT|t}|pXd	d
d
d}|rpd| |d< d|d< |t n||d< |d ur}|	| |du r|rddlm
} |jj|d< |S t|dkrd||d< |S )Nrz   r{   r|   r   )!ANTHROPIC_TOOL_SEARCH_BETA_HEADERrx   zcode-execution-2025-08-25zskills-2025-10-02
2023-06-01zapplication/json)anthropic-versionacceptzcontent-typer   r'   r+   r,   r)   T)ANTHROPIC_BETA_HEADER_VALUESr*   r   )r   rs   r    r}   r   ry   r   r   r   updater   ZWEB_SEARCH_2025_03_05r   rH   r!   )r7   r&   r   rt   ru   r   rv   rw   r   r   r   r   r   r   r   r   r   r#   r   r   ry   Z	_is_oauthr%   r   r   r   r   get_anthropic_headers  sT   









z(AnthropicModelInfo.get_anthropic_headersr%   litellm_paramsapi_basec                 C   s  t ||d\}}|d u rtjdd|d|d}| j|d}	| j|d}
| j|dd	}| j|d}| j|d}| j	|d}| j
|d}| j|d}| j|d}| j||d
}| j|d}| j|d}| j|dd}| j|
|	|||||dd||||||||d}i ||}|S )N)r%   r&   zMissing Anthropic API Key - A call is being made to anthropic but no key is set either in the environment variables or via params. Please set `ANTHROPIC_API_KEY` in your environment varsZ	anthropic)r4   llm_providerr^   rL   )rC   )rL   rJ   )rJ   )rf   r^   )rf   r*   )rp   r   F)rt   ru   r   r&   rv   r   r   r   rw   r   r   r   r   r   r   )r1   litellmAuthenticationErrorr-   rG   rP   rK   rS   rI   rQ   rV   r[   r]   rk   rl   ro   rq   r   )r7   r%   r^   rC   rf   r   r&   r   rL   ru   rt   rw   r   rv   r   r   r   r   r   r   r   r   Zanthropic_headersr   r   r   validate_environment  sd   


z'AnthropicModelInfo.validate_environmentc                 C   s   ddl m} | p|dpdS )Nr   get_secret_strZANTHROPIC_API_BASEzhttps://api.anthropic.comZlitellm.secret_managers.mainr   )r   r   r   r   r   get_api_base  s   zAnthropicModelInfo.get_api_basec                 C   s   ddl m} | p|dS )Nr   r   ZANTHROPIC_API_KEYr   )r&   r   r   r   r   get_api_key  s   zAnthropicModelInfo.get_api_keyc                 C   s   | r|  ddS d S )N
anthropic/r(   )r.   rd   r   r   r   get_base_model$  s   z!AnthropicModelInfo.get_base_modelc           	      C   s   t |}t |}|d u s|d u rtdtjj| d|ddd}z|  W n tj	y>   t
d|j d|j w | d }g }|D ]}|d	 }d
| }|| qI|S )NzANTHROPIC_API_BASE or ANTHROPIC_API_KEY is not set. Please set the environment variable, to query Anthropic's `/models` endpoint.z
/v1/modelsr   )r)   r   )urlr%   z4Failed to fetch models from Anthropic. Status code: z, Response: dataidr   )rB   r   r   
ValueErrorr   Zmodule_level_clientr-   raise_for_statusr?   ZHTTPStatusError	Exceptionr3   rR   jsonr~   )	r7   r&   r   responsemodelsZlitellm_model_namesr^   Zstripped_model_nameZlitellm_model_namer   r   r   
get_models(  s0   

zAnthropicModelInfo.get_modelsc                 C   s   ddl m} | S )z
        Factory method to create an Anthropic token counter.

        Returns:
            AnthropicTokenCounter instance for this provider.
        r   )AnthropicTokenCounter)Z1litellm.llms.anthropic.count_tokens.token_counterr   )r7   r   r   r   r   get_token_counterF  s   z$AnthropicModelInfo.get_token_counterr:   )NNFFF)NNFFFFFFFFFFNFF)NN)%r;   r<   r=   r   r   boolrG   rI   r   r   rK   r   rj   rP   rQ   rS   rV   r[   r]   staticmethodre   rZ   rk   rl   ro   rq   rs   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rB   Z   s    

	



 
 


/	


Z	
A	
rB   c                 C   sv   i }d| v r| d |d< d| v r| d |d< d| v r | d |d< d| v r*| d |d< d	d
 |   D }i ||}|S )Nz"anthropic-ratelimit-requests-limitzx-ratelimit-limit-requestsz&anthropic-ratelimit-requests-remainingzx-ratelimit-remaining-requestsz anthropic-ratelimit-tokens-limitzx-ratelimit-limit-tokensz$anthropic-ratelimit-tokens-remainingzx-ratelimit-remaining-tokensc                 S   s   i | ]\}}d  d||qS )z{}-{}r   )format)r   kr_   r   r   r   
<dictcomp>g  s    z-process_anthropic_headers.<locals>.<dictcomp>)items)r%   Zopenai_headersZllm_response_headersZadditional_headersr   r   r   process_anthropic_headersT  s,   r   )"__doc__typingr   r   r   r   r?   r   Z8litellm.litellm_core_utils.prompt_templates.common_utilsr   Z litellm.llms.base_llm.base_utilsr   r   Z)litellm.llms.base_llm.chat.transformationr	   r}   r
   r   r   r   r   Zlitellm.types.llms.openair   rj   r   r   r$   rZ   tupler1   r2   rB   r@   r   r   r   r   r   <module>   s0    		
%
    }