o
    ưi2                    @   s  d dl Z d dlZd dlZd dlmZmZmZmZmZm	Z	m
Z
mZ d dlZd dlZd dlmZmZmZmZmZmZmZ d dlmZ d dlmZ d dlmZmZ d dlmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z- d dl.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z: d d	l;m<Z<m=Z= d d
l;m>Z? d dl;m@Z@mAZA d dlBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZK ddlLmMZMmNZNmOZO erd dlPmQZR eRZSneZSG dd deNeZTdeUdeVfddZWdS )    N)TYPE_CHECKINGAnyDictListOptionalTupleUnioncast)"ANTHROPIC_WEB_SEARCH_TOOL_MAX_USES!DEFAULT_ANTHROPIC_CHAT_MAX_TOKENS-DEFAULT_REASONING_EFFORT_HIGH_THINKING_BUDGET,DEFAULT_REASONING_EFFORT_LOW_THINKING_BUDGET/DEFAULT_REASONING_EFFORT_MEDIUM_THINKING_BUDGET0DEFAULT_REASONING_EFFORT_MINIMAL_THINKING_BUDGETRESPONSE_FORMAT_TOOL_NAME)map_finish_reasontype_to_response_format_param)
BaseConfigBaseLLMException)ANTHROPIC_BETA_HEADER_VALUESANTHROPIC_HOSTED_TOOLSAllAnthropicMessageValuesAllAnthropicToolsValuesAnthropicCodeExecutionToolAnthropicComputerToolAnthropicHostedToolsAnthropicInputSchemaAnthropicMcpServerToolAnthropicMessagesToolAnthropicMessagesToolChoiceAnthropicOutputSchemaAnthropicSystemMessageContentAnthropicThinkingParamAnthropicWebSearchToolAnthropicWebSearchUserLocation)REASONING_EFFORTAllMessageValuesChatCompletionCachedContent#ChatCompletionRedactedThinkingBlockChatCompletionSystemMessageChatCompletionThinkingBlockChatCompletionToolCallChunk#ChatCompletionToolCallFunctionChunkChatCompletionToolParam OpenAIChatCompletionFinishReasonOpenAIMcpServerToolOpenAIWebSearchOptions)CacheCreationTokenDetailsCompletionTokensDetailsWrapper)Message)PromptTokensDetailsWrapperServerToolUse)	ModelResponseUsageadd_dummy_tool)any_assistant_message_has_thinking_blocksget_max_tokenshas_tool_call_blocks5last_assistant_with_tool_calls_has_no_thinking_blockssupports_reasoningtoken_counter   )AnthropicErrorAnthropicModelInfoprocess_anthropic_headers)Loggingc                       s  e Zd ZU dZdZee ed< dZee	 ed< dZ
ee ed< dZee ed< dZee ed< dZee ed< dZee ed	< 							ddee dee	 dee dee dee dee d	ee d
dfddZed
ee fddZedddee f fddZeddee d
efddZedeeef ded
efddZeded
efddZdefddZedeeef d
eeef fddZd e eedf d
ee fd!d"Z!d
efd#d$Z"d%ee d&ee d
ee# fd'd(Z$d)e%d
e&ee' ee( f fd*d+Z)d)e*d
e(fd,d-Z+d.e,d
e&e,e' e,e( f fd/d0Z-d.ee, d
efd1d2Z.d.e,d
e&e,e,f fd3d4Z/d5e,d6e,d
e,fd7d8Z0d9ee ee,e f  d
ee,e  fd:d;Z1ed<ee e2ef  ded
ee3 fd=d>Z4d?ee d
ee fd@dAZ5d?ee d
ee6 fdBdCZ7d?ee dDedEed
ee8 fdFdGZ9d?e:d
e;fdHdIZ<edJe e,eeef  eeef f d
eeeef  fdKdLZ=dMedDededNed
ef
dOdPZ>	ddQee d
e8fdRdSZ?dTe,e@ d
e,eA fdUdVZBdTe,eC d.e,e e'ef  d
e,e e'ef  fdWdXZDdYedZed
dfd[d\ZEdYedJeFd
dfd]d^ZGdYedDed
efd_d`ZHdedTe,e@ dDedaedYed
efdbdcZIddee dee,e d
eeJ fdfdgZKdhed
e&eee,e  ee,e eLeMf   ee e,e ee,e  ee,e  ee,e  f fdidjZN		ddkedlee dhee dmee d
eOf
dndoZP			ddhedpeQjRdqeSddee dree dmee fdsdtZTdTe,e@ d
ee fdudvZU		ddedpeQjRdqeSdweVdxedTe,e@ dDedaedyedzee ddee d
eSfd{d|ZWedee,e d
eeJ fd}d~ZXdededYe eeQjYf d
eZfddZ[  Z\S )AnthropicConfigz
    Reference: https://docs.anthropic.com/claude/reference/messages_post

    to pass metadata to anthropic, it's {"user_id": "any-relevant-information"}
    N
max_tokensstop_sequencestemperaturetop_ptop_kmetadatasystemreturnc                 C   s>   t   }| D ]\}	}
|	dkr|
d urt| j|	|
 q	d S )Nself)localscopyitemssetattr	__class__)rN   rF   rG   rH   rI   rJ   rK   rL   Zlocals_keyvalue rV   a/home/app/Keep/.python/lib/python3.10/site-packages/litellm/llms/anthropic/chat/transformation.py__init__`   s   

zAnthropicConfig.__init__c                 C   s   dS )N	anthropicrV   rN   rV   rV   rW   custom_llm_providero   s   z#AnthropicConfig.custom_llm_providermodelr]   c                   s*   t   }|dd u r| ||d< |S )NrF   )super
get_configgetget_max_tokens_for_model)clsr]   configrS   rV   rW   r_   s   s   
zAnthropicConfig.get_configc                 C   s@   | du rt S zt| }|du rt W S |W S  ty   t  Y S w )z
        Get the max output tokens for a given model.
        Falls back to DEFAULT_ANTHROPIC_CHAT_MAX_TOKENS (configurable via env var) if model is not found.
        N)r   r;   	Exception)r]   rF   rV   rV   rW   ra   }   s   z(AnthropicConfig.get_max_tokens_for_modelanthropic_tool_contentindexc              	   C   sP   t | d dt| d t| d d|d}d| v r&ttttf | d |d< |S )a  
        Convert Anthropic tool_use format to OpenAI ChatCompletionToolCallChunk format.

        Args:
            anthropic_tool_content: Anthropic tool_use content block with format:
                {"type": "tool_use", "id": "...", "name": "...", "input": {...}}
            index: The index of this tool call

        Returns:
            ChatCompletionToolCallChunk in OpenAI format
        idfunctionnameinput)rj   	arguments)rh   typeri   rg   Zcaller)r,   r-   jsondumpsr	   r   strr   )rf   rg   	tool_callrV   rV   rW   !convert_tool_use_to_openai_format   s   
z1AnthropicConfig.convert_tool_use_to_openai_formatc                    s   |    t fdddD S )z3Check if the model is specifically Claude Opus 4.6.c                 3       | ]}| v V  qd S NrV   ).0vZmodel_lowerrV   rW   	<genexpr>   
    
z5AnthropicConfig._is_opus_4_6_model.<locals>.<genexpr>)opus-4-6Zopus_4_6opus-4.6zopus_4.6)loweranyr\   rV   rw   rW   _is_opus_4_6_model   s   z"AnthropicConfig._is_opus_4_6_modelc                 C   s@   g d}d|v st |st|| jdr|d |d |S )N)streamstoprH   rI   rF   max_completion_tokenstoolstool_choiceextra_headersparallel_tool_callsresponse_formatuserweb_search_optionsspeedcontext_managementcache_controlzclaude-3-7-sonnet)r]   r[   thinkingreasoning_effort)rE   _is_claude_4_6_modelr>   r[   append)rN   r]   paramsrV   rV   rW   get_supported_openai_params   s   

z+AnthropicConfig.get_supported_openai_paramsschemac           
   	   C   s  t | ts| S h d}g }dddddddd	d
}|D ]}|| v r,||| | |  qi }|rO| dd}dd| d }|rK|d | |d< n||d< |  D ]\}}	||v r\qS|dkred|v reqS|dkrzt |	trzdd |	 D ||< qS|dkrt |	trt|	||< qS|dkrt |	trdd |	 D ||< qS|dkrt |	t	rdd |	D ||< qS|dkrt |	t	rdd |	D ||< qS|dkrt |	t	rdd |	D ||< qS|	||< qS|ddkrd |vrd!|d < |S )"a  
        Filter out unsupported fields from JSON schema for Anthropic's output_format API.

        Anthropic's output_format doesn't support certain JSON schema properties:
        - maxItems/minItems: Not supported for array types
        - minimum/maximum: Not supported for numeric types
        - minLength/maxLength: Not supported for string types

        This mirrors the transformation done by the Anthropic Python SDK.
        See: https://platform.claude.com/docs/en/build-with-claude/structured-outputs#how-sdk-transformation-works

        The SDK approach:
        1. Remove unsupported constraints from schema
        2. Add constraint info to description (e.g., "Must be at least 100")
        3. Validate responses against original schema
        Args:
            schema: The JSON schema dictionary to filter

        Returns:
            A new dictionary with unsupported fields removed and descriptions updated

        Related issues:
        - https://github.com/BerriAI/litellm/issues/19444
        >   minimummaximum	minLength	maxLengthminItemsexclusiveMaximummaxItemsexclusiveMinimumzminimum number of items: {}zmaximum number of items: {}zminimum value: {}zmaximum value: {}zexclusive minimum value: {}zexclusive maximum value: {}zminimum length: {}zmaximum length: {})r   r   r   r   r   r   r   r   description zNote: , . 
propertiesc                 S      i | ]
\}}|t |qS rV   rE   filter_anthropic_output_schemaru   krv   rV   rV   rW   
<dictcomp>#      
zBAnthropicConfig.filter_anthropic_output_schema.<locals>.<dictcomp>rQ   $defsc                 S   r   rV   r   r   rV   rV   rW   r   *  r   ZanyOfc                 S      g | ]}t |qS rV   r   ru   itemrV   rV   rW   
<listcomp>/      zBAnthropicConfig.filter_anthropic_output_schema.<locals>.<listcomp>ZallOfc                 S   r   rV   r   r   rV   rV   rW   r   4  r   oneOfc                 S   r   rV   r   r   rV   rV   rW   r   9  r   rm   objectadditionalPropertiesF)

isinstancedictr   formatr`   joinrQ   rE   r   list)
r   Zunsupported_fieldsZconstraint_descriptionsZconstraint_labelsfieldresultZexisting_descZconstraint_noterT   rU   rV   rV   rW   r      sr   


z.AnthropicConfig.filter_anthropic_output_schemar   c                 C   s   t |ddS )Nz/$defs/{model})Zref_templater   )rN   r   rV   rV   rW   $get_json_schema_from_pydantic_objectG  s   z4AnthropicConfig.get_json_schema_from_pydantic_objectc                 C   s   ddiS )Nzanthropic-versionz
2023-06-01rV   rZ   rV   rV   rW   get_cache_control_headersN  s   z)AnthropicConfig.get_cache_control_headersr   parallel_tool_usec                 C   s  d }|dkrt dd}n^|dkrt dd}nT|dkr t dd}nJt|trjd|v rTd|vrT|d}|dkr<t dd}n.|dksD|dkrJt dd}n |dkrSt dd}n|di d}|d urjt d	d}||d< |d ur|dkru	 |S |d ur| |d
< |S t d| d}|S )Nautorm   requiredr}   nonerm   ri   rj   tooldisable_parallel_tool_use)rm   r   )r    r   r   r`   )rN   r   r   _tool_choice	tool_typeZ
_tool_namerV   rV   rW   _map_tool_choiceV  sF   




z AnthropicConfig._map_tool_choicer   c                    s6  d }d }d dksd dkrQd  ddi d}ttj   fdd| D }td.i |}td d	 |d
}d  d}|d urM||d< |}nd drdd vrbtdd d  d}	d d  d}
|	d u s||
d u rtdt	d d  d	d|	|
d}d d  d}|d ur||d< |}nt
fddtD r d	 di  d	}|d u st|tstd|}i } D ]\}}|dkr|d	kr|||< qtd.d |d|}nid dkrtd.i }n[d dkr| tt}nKd dkr3ddlm}  d	d}t|ts*td|}|d|d}n%d dkrXdd lm}  d	d!}t|tsPtd|}|d|d}|d u rk|d u rktd"d   d#d } di  d#d }|d ur| dd$}|d%vr|d ur||d#< n|d urt|trtd.i ||d#<  d&d } di  d&d }|d ur| dd$}|d'vr|d urt|tstd(||d&< n|d urt|tstd(||d&<  d)d } di  d)d }|d urK| dd$}|d'vrK|d ur.t|tr%td*d |D s)td+||d)< n|d urKt|trCtd,d |D sGtd+||d)<  d-d } di  d-d }|d ur| dd$}|dksu|d$krd	|v r|d urt|tr||d-< ||fS |d urt|tr||d-< ||fS )/Nrm   ri   Zcustom
parametersr   )rm   r   c                    s   i | ]\}}| v r||qS rV   rV   r   )_allowed_propertiesrV   rW   r     s    z4AnthropicConfig._map_tool_helper.<locals>.<dictcomp>rj   rj   input_schemar   Z	computer_z&Missing required parameter: parametersdisplay_width_pxdisplay_height_pxzAMissing required parameter: display_width_px or display_height_pxcomputer)rm   rj   r   r   Zdisplay_numberc                 3   s    | ]
} d   |V  qdS )rm   N)
startswith)ru   t)r   rV   rW   rx     s    z3AnthropicConfig._map_tool_helper.<locals>.<genexpr>z Missing required parameter: namerm   rj   urlZmcptool_search_tool_regex_20251119r   )AnthropicToolSearchToolRegexZtool_search_tool_regexz'Tool search tool must have a valid nametool_search_tool_bm25_20251119)AnthropicToolSearchToolBM25Ztool_search_tool_bm25zUnsupported tool type: r   r   r   r   defer_loading)r   r   Zcomputer_20241022Zcomputer_20250124zdefer_loading must be a booleanZallowed_callersc                 s       | ]}t |tV  qd S rt   r   rp   r   rV   rV   rW   rx   #      

z)allowed_callers must be a list of stringsc                 s   r   rt   r   r   rV   rV   rW   rx   )  r   Zinput_examplesrV   )r`   setr   __annotations__keysrQ   r   r   
ValueErrorr   r}   r   r   rp   r   r   _map_openai_mcp_server_toolr	   r0   litellm.types.llms.anthropicr   r   r   r(   boolr   all)rN   r   Zreturned_toolZ
mcp_server_input_schemaZinput_schema_filteredZinput_anthropic_schema_toolZ_descriptionZ_display_width_pxZ_display_height_pxZ_computer_toolZ_display_numberZfunction_name_objZfunction_nameZadditional_tool_paramsr   rv   r   Ztool_name_obj	tool_namer   Z_cache_controlZ_cache_control_functionr   Z_defer_loadingZ_defer_loading_functionZ_allowed_callersZ_allowed_callers_functionZ_input_examplesZ_input_examples_functionrV   )r   r   rW   _map_tool_helper  s(  



















z AnthropicConfig._map_tool_helperc           	      C   s   ddl m} |dd }d }|d ur||dd d}|di }d }|d ur7|dd }|d ur7|dd}td	|d
 |d d}|d urJ||d< |d urR||d< |S )Nr   )#AnthropicMcpServerToolConfigurationallowed_tools)r   headersAuthorizationzBearer r   r   Z
server_urlZserver_label)rm   r   rj   tool_configurationauthorization_token)r   r   r`   replacer   )	rN   r   r   r   r   r   r   Zbearer_tokenZinitial_toolrV   rV   rW   r   ?  s.   
z+AnthropicConfig._map_openai_mcp_server_toolr   c                 C   s`   g }g }|D ]%}d|v r| | q| |\}}|d ur"| | |d ur+| | q||fS )Nr   )r   r   )rN   r   anthropic_toolsmcp_serversr   Znew_toolZmcp_server_toolrV   rV   rW   
_map_tools^  s   

zAnthropicConfig._map_toolsc                 C   s0   |sdS |D ]}| dd}|dv r dS qdS )z9Check if tool search tools are present in the tools list.Frm   r   r   Tr`   )rN   r   r   r   rV   rV   rW   _detect_tool_search_toolso  s   z)AnthropicConfig._detect_tool_search_toolsc                 C   s<   g }g }|D ]}| ddr|| q|| q||fS )z
        Separate tools into deferred and non-deferred lists.

        Returns:
            Tuple of (non_deferred_tools, deferred_tools)
        r   F)r`   r   )rN   r   Znon_deferreddeferredr   rV   rV   rW   _separate_deferred_tools}  s   z(AnthropicConfig._separate_deferred_toolscontentdeferred_toolsc                 C   s   |s|S i }|D ]}| dp| di  d}|r|||< qg }|D ],}t|trJ| ddkrJ| d}|rD||v rD|||  q#|| q#|| q#|S )a7  
        Expand tool_reference blocks to full tool definitions.

        When Anthropic's tool search returns results, it includes tool_reference blocks
        that reference tools by name. This method expands those references to full
        tool definitions from the deferred_tools catalog.

        Args:
            content: Response content that may contain tool_reference blocks
            deferred_tools: List of deferred tools that can be referenced

        Returns:
            Content with tool_reference blocks expanded to full tool definitions
        rj   ri   rm   Ztool_referencer   )r`   r   r   r   )rN   r   r   Ztool_mapr   r   Zexpanded_contentr   rV   rV   rW   _expand_tool_references  s"   
z'AnthropicConfig._expand_tool_referencesr   c                 C   sx   d }t |tr| rtjdu r|S |g}|S t |tr:g }|D ]}| r,tjdu r,q || q t|dkr:|}|S )NTr   )r   rp   isspacelitellmdrop_paramsr   r   len)rN   r   Znew_stopnew_vrv   rV   rV   rW   _map_stop_sequences  s&   



z#AnthropicConfig._map_stop_sequencesr   c                 C   s   | d u s| dkr
d S t |rtddS | dkrtdtdS | dkr(tdtdS | dkr2tdtdS | d	kr<tdtdS td
|  )Nr   Zadaptiver   lowenabled)rm   Zbudget_tokensmediumhighminimalzUnmapped reasoning effort: )rE   r   r#   r   r   r   r   r   r   r]   rV   rV   rW   _map_reasoning_effort  s6   
z%AnthropicConfig._map_reasoning_effortrU   c                 C   s<   |d u rd S d }d|v r|d }|S d|v r|d d }|S )NZresponse_schemajson_schemar   rV   )rN   rU   r  rV   rV   rW   )_extract_json_schema_from_response_format  s   z9AnthropicConfig._extract_json_schema_from_response_formatc                 C   sl   |  |}|d u rd S dd l}ddlm} ||}|d|di }|r+||| | |}td|dS )Nr   )unpack_defsr   Zdefinitionsr  )rm   r   )r  rP   Z8litellm.litellm_core_utils.prompt_templates.common_utilsr  deepcopypopr   r!   )rN   rU   r  rP   r  ZdefsZfiltered_schemarV   rV   rW   .map_response_format_to_anthropic_output_format  s    


z>AnthropicConfig.map_response_format_to_anthropic_output_formatoptional_paramsis_thinking_enabledc                 C   sF   dg}|d u s|d |v rd S |  |}|d u rd S 	 | j|d}|S )Ntextrm   )r  )r  *_create_json_tool_call_for_response_format)rN   rU   r  r	  Zignore_response_format_typesr  r   rV   rV   rW   %map_response_format_to_anthropic_tool  s   z5AnthropicConfig.map_response_format_to_anthropic_toolc                 C   s   t t|}tddd}|d}|d ur@tdd}tj }|d}|d ur@| D ]\}}	||v r;|dkr;|	||< q+||d< |d}
|
d urOt|
 |d	< |S )
NZweb_search_20250305Z
web_searchr   user_locationZapproximater   rm   search_context_sizeZmax_uses)	r	   r1   r$   r`   r%   r   r   rQ   r
   )rN   rU   Zvalue_typedhosted_web_search_toolr  Zanthropic_user_locationZanthropic_user_location_keysZuser_location_approximaterT   Zuser_location_valuer  rV   rV   rW   map_web_search_tool:  s.   




z#AnthropicConfig.map_web_search_toolr   c                 C   s   t | trd| v r| S t | tr]g }| D ]B}t |tsq|d}|dkrVddi}|d}|durBt |ttfrBdt|d|d	< |D ]}|d
vrP|| ||< qD|| q|r]d|iS dS )a  
        OpenAI format: [{"type": "compaction", "compact_threshold": 200000}]
        Anthropic format: {
            "edits": [
                {
                    "type": "compact_20260112",
                    "trigger": {"type": "input_tokens", "value": 150000}
                }
            ]
        }

        Args:
            context_management: OpenAI or Anthropic context_management parameter

        Returns:
            Anthropic-formatted context_management dict, or None if invalid
        editsrm   
compactioncompact_20260112compact_thresholdNinput_tokens)rm   rU   trigger>   r  rm   )r   r   r   r`   intfloatr   )r   Zanthropic_editsentryZ
entry_typeZanthropic_editr  r   rV   rV   rW   *map_openai_context_management_to_anthropicY  s4   






z:AnthropicConfig.map_openai_context_management_to_anthropicnon_default_paramsr   c                    sj  | j |d}| D ]\}}|dkr&t|tr|ntdtt||d< q
|dkr=t|tr1|ntdtt||d< q
|dkrV| |\}}	| j||d}|	rU|	|d< q
|dks^|d	krt| j|	d|	d	d
}
|
d urs|
|d< q
|dkr|du r||d< q
|dkrt|t
st|tr| |}|d ur||d< q
|dkr||d< q
|dkr||d< q
|dkrt|trt fdddD r| |}|d ur||d< n| |||}|d u rq
|stdd}
|
|d< | j||gd}d|d< q
|dkr|d urt|t
rt|rd|i|d< q
|dkr||d< q
|dkrJt|t
rJtj| d|d< t rIddd d!d"d#}|	||}d$|i|d%< q
|d&krft|trf| tt|}| j||gd q
|d'krp||d'< q
|d(krt|ttfr| |}|d ur||d(< q
|d)krt|t
r||d)< q
|d*krt|tr||d*< q
| j||d+ |S ),N)r  rF      r   r   )r  r   r   r   r   )r   r   r   Tr   rG   rH   rI   r   c                 3   rs   rt   rV   )ru   Z	substringr\   rV   rW   rx     ry   z4AnthropicConfig.map_openai_params.<locals>.<genexpr>>   z
sonnet-4.6z
sonnet-4.5zopus-4-1zopus-4.5zopus-4.1zopus-4-5z
sonnet-4-6z
sonnet_4.6z
sonnet-4-5rz   Z
sonnet_4_6r{   output_formatr   rj   rm   	json_moder   user_idrK   r   r   r   r   r   r   max)r   r   r   r   r!  effortoutput_configr   r   r   r   r   )r  r  )r	  rQ   r   r  r!  roundr   Z_add_tools_to_optional_paramsr   r`   rp   r   r   r   r}   r  r  r   _valid_user_idrE   r  r   r  r	   r1   r  Z+update_optional_params_with_thinking_tokens)rN   r  r  r]   r   r	  paramrU   r   r   r   _valueZ_output_formatr   Z
effort_mapZmapped_effortr  Zanthropic_context_managementrV   r\   rW   map_openai_params  s   














z!AnthropicConfig.map_openai_paramsr  c                 C   sD   t dd}|du rd|d< i |d< n|tt | tt|d}|S )a3  
        Handles creating a tool call for getting responses in JSON format.

        Args:
            json_schema (Optional[dict]): The JSON schema the response should be in

        Returns:
            AnthropicMessagesTool: The tool call to send to Anthropic API to get responses in JSON format
        r   r   NTr   r   r   )r   updater	   r   r   )rN   r  r   r   rV   rV   rW   r  (  s   
z:AnthropicConfig._create_json_tool_call_for_response_formatmessagesc           
      C   sF  g }g }t |D ]\}}|d dkr|| tdi |}t|d trJ|d s*q|d dr2qtd|d d}d|v rD|d |d< || qt|d tr|d D ]8}|d}	|ddkrf|	sfqU|ddkru|	ru|	druqUt|d|	d}d|v r|d |d< || qUqt	|d	krt
|D ]}|| q|S )a  
        Translate system message to anthropic format.

        Removes system message from the original list and returns a new list of anthropic system message content.
        Filters out system messages containing x-anthropic-billing-header metadata.
        rolerL   r   zx-anthropic-billing-header:r
  )rm   r
  r   rm   r   NrV   )	enumerater   r*   r   rp   r   r"   r   r`   r   reversedr  )
rN   r*  Zsystem_prompt_indicesanthropic_system_message_listidxmessageZsystem_message_blockZ anthropic_system_message_content_contentZ
text_valuerV   rV   rW   translate_system_messageF  sd   	

z(AnthropicConfig.translate_system_messagec           
      C   s   d}|D ]"}| dd}|r&t|tr&|D ]}| dd}|dkr%d} nqq|rM|D ]}| dd}	|	rCt|	trC|	drC|  S q+|tddd	 |S )
z:if 'container_upload' in messages, add code_execution toolFr   Nrm   Zcontainer_uploadTZcode_executionZcode_execution_20250522r  )r`   r   r   rp   r   r   r   )
rN   r*  r   add_code_execution_toolr0  message_contentr   content_typer   r   rV   rV   rW   r3    s:   z'AnthropicConfig.add_code_execution_toolr   
beta_valuec                 C   sT   | d}|du r||d< dS dd |dD }||vr(| d| |d< dS dS )a  
        Ensure a beta header value is present in the anthropic-beta header.
        Merges with existing values instead of overriding them.

        Args:
            headers: Dictionary of headers to update
            beta_value: The beta header value to add
        zanthropic-betaNc                 S   s   g | ]}|  qS rV   )strip)ru   betarV   rV   rW   r     s    z7AnthropicConfig._ensure_beta_header.<locals>.<listcomp>,r   )r`   split)rN   r   r6  Zexisting_betaZexisting_valuesrV   rV   rW   _ensure_beta_header  s   
	z#AnthropicConfig._ensure_beta_headerc                 C   s   g }t |trd|v r|dg }n
t |tr|}ndS d}d}|D ]}|dd}|dks2|dkr5d}q"d}q"|rB| |tjj |rN| |tjj dS dS )	zQ
        Add appropriate beta headers based on context_management edits.
        r  NFrm   r   r  r  T)	r   r   r`   r   r;  r   ZCOMPACT_2026_01_12rU   CONTEXT_MANAGEMENT_2025_06_27)rN   r   r   r  Zhas_compactZ	has_otherZeditZ	edit_typerV   rV   rW   &_ensure_context_management_beta_header  s.   
z6AnthropicConfig._ensure_context_management_beta_headerc                 C   s   | dd}|r
|S | dg }|D ]3}| ddr-| dtjjr-| |tjj q| ddrE| dtjjrE| |tj	j q| ddurU| 
||d  | ddurd| |tjj | dd	krs| |tjj |S )
z,Update headers with optional anthropic beta.is_vertex_requestFr   rm   Nr   r  r   fast)r`   r   r   Z	WEB_FETCHrU   r;  r   ZWEB_FETCH_2025_09_10ZMEMORYr<  r=  ZSTRUCTURED_OUTPUT_2025_09_25ZFAST_MODE_2026_02_01)rN   r   r  r>  _toolsr   rV   rV   rW   +update_headers_with_optional_anthropic_beta  s@   z;AnthropicConfig.update_headers_with_optional_anthropic_betalitellm_paramsc              
   C   sl  	 ddl m} d|vr+|dur+t|r+tjr#| tdd\|d< }ntjdddd	|d
durM|durMt	|rMt
|sMtjrM|d
d tjd | j||d}| j|d}t|dkrd||d< z|||| jpldd}	W n ty }
 ztddt|
|dd}
~
ww ttttttf   |dpg }| j|	|d}t|dkr||d< tjj|d}| D ]\}}||vr|||< q|dd}|rt |t!rd|v r|d durt"|d rd|d i|d< |dd ||	d|}d|v r4|d}|r4t |t!r4|d}|r|dvrt#d| d|dkr0| $|s0t#d | ||d< |S )!z9
        Translate messages to anthropic format.
        r   )anthropic_messages_ptr   NrY   )r[   zAnthropic doesn't support tool calling without `tools=` param specified. Pass `tools=` param OR set `litellm.modify_params = True` // `litellm_settings::modify_params: True` to add dummy tool to the request.r   )r0  r]   llm_providerr   zDropping 'thinking' param because the last assistant message with tool_calls has no thinking_blocks. The model won't use extended thinking for this turn.)r   r  r*  rL   )r]   r*  rD  i  z{}
Received Messages={})status_coder0  )r*  r   r  r\   rK   r   r>  )r]   r*  r#  r"  )r   r   r   r!  zInvalid effort value: z0. Must be one of: 'high', 'medium', 'low', 'max'r!  z>effort='max' is only supported by Claude Opus 4.6. Got model: )%Z3litellm.litellm_core_utils.prompt_templates.factoryrC  r<   r   Zmodify_paramsr   r9   ZUnsupportedParamsErrorr`   r=   r:   r  Zverbose_loggerwarningrA  r2  r   r[   re   rA   r   rp   r	   r   r   r   r   r   r3  rE   r_   rQ   r   r   r%  r   r~   )rN   r]   r*  r  rB  r   rC  _r.  Zanthropic_messageser@  r   rc   r   rv   Z_litellm_metadatadatar#  r"  rV   rV   rW   transform_request  s   





z!AnthropicConfig.transform_requestr  
tool_callsc                 C   sj   d }|du r3t |dkr3d }d|d d v r)|d d d tkr)|d d d}|d ur3tj|d}|S )NTr  rj   r   ri   rl   )rL  )r   r   r`   rE   !_convert_tool_response_to_message)rN   r  rL  _messagejson_mode_content_strrV   rV   rW   !_transform_response_for_json_mode  s   z1AnthropicConfig._transform_response_for_json_modecompletion_responsec                    s  d}d }d }d }g }d }d }d }	t |d D ]\}
  d dkr'| d 7 }n d dks3 d dkr@tj |
d}|| n{ d dr~ d d	krNq d d
kr`|d u rZg }|  n[ d dkrr|d u rlg }|  nI|d u rxg }|  n= dd d ur|d u rg }|tt  n& d dkr|d u rg }|tt  n d dkr|	d u rg }	|	   dd ur|d u rg }| fdd d D  q|d urd}|D ]}tt	t
 |d}|d ur||7 }q||||||||	fS )Nr   r   rm   r
  Ztool_useserver_tool_use)rf   rg   Z_tool_resultZtool_search_tool_resultZweb_search_tool_resultZweb_fetch_tool_resultr   Zredacted_thinkingr  	citationsc                    s$   g | ]}i |d   ddiqS )Zsupported_textr
  r   r   )ru   Zcitationr   rV   rW   r     s    z<AnthropicConfig.extract_response_content.<locals>.<listcomp>)r,  rE   rr   r   endswithr`   r	   r+   r)   r   rp   )rN   rQ  text_contentrS  thinking_blocksreasoning_contentrL  web_search_resultstool_resultscompaction_blocksr/  rq   blockZthinking_contentrV   rT  rW   extract_response_content  s   

	z(AnthropicConfig.extract_response_contentusage_objectrX  r   c                 C   s2  | ddpd}| ddpd}|}d}d}	d }
d }d }d }d|v r,|d d ur,|d }d|v r>|d d ur>|d }||7 }d|v rP|d d urP|d }	||	7 }d|v r|d d urd|d v rq|d d d urqtt|d d }d	|d v r|d d	 d urtt|d d	 }|d u r|d urd}| d
g D ]}| ddkr| dd}d|v r|d7 }q|dkr|}d|v r|d d urt|d  d|d  dd}
t|	||
d}|rt|ddnd}t|dkr|nd|dkr|| n|d}|| }t||||||	||d us|d urt||dnd ||d
}|S )Nr  r   Zoutput_tokensinference_geocache_creation_input_tokenscache_read_input_tokensrR  web_search_requeststool_search_requestsr   rm   rj   r   Ztool_searchr  Zcache_creationephemeral_5m_input_tokensephemeral_1h_input_tokens)rd  re  )Zcached_tokensZcache_creation_tokenscache_creation_token_detailsT)r
  Zcount_response_tokens)reasoning_tokensZtext_tokens)rb  rc  )
prompt_tokenscompletion_tokenstotal_tokensprompt_tokens_detailsr`  ra  Zcompletion_tokens_detailsrR  r_  r   )	r`   r	   r  r2   r5   r?   r3   r8   r6   )rN   r^  rX  rQ  r   rh  ri  Z_usager`  ra  rf  rb  rc  r_  Ztool_search_countr   r   rk  rg  Zcompletion_token_detailsrj  usagerV   rV   rW   calculate_usage  s   	zAnthropicConfig.calculate_usageraw_responsemodel_responseprefix_promptc                 C   s  i }t t|j|d< d|v r!t|dd }tt|d |j|dd}	d }
d }d }g }| j|d\}	}
}}}}}}|d urI|	|sIt	j
sI||	 }	|d}|d}|
|d	}|d ur`||d< |d urh||d
< |d urp||d< |d urx||d< |d ur||d< t	j||	pd |||d}||_| j||d}|d urd|d< |}||jd _|d |jd< ttt|d |jd _| j|d |||d}t|d| tt |_|d |_||_|S )NZadditional_headerserrorr   r0  rF  r   r   )rQ  r   	container)rS  rW  rY  rZ  r[  )rL  r   provider_specific_fieldsrW  rX  )r  rL  r   Zstop_reasonr   r   original_responserl  )r^  rX  rQ  r   r]   )rC   r   r   getattrrA   rp   rF  r]  r   r   Zdisable_add_prefix_to_promptr`   r4   rt  rP  choicesr0  _hidden_paramsr	   r/   r   Zfinish_reasonrm  rR   r  timecreatedr]   )rN   rQ  rn  ro  r  rp  r   rx  response_headersrV  rS  rW  rX  rL  rY  rZ  r[  r   rs  rt  rN  Zjson_mode_messagerl  rV   rV   rW   transform_parsed_response  s   	





z)AnthropicConfig.transform_parsed_responsec                 C   sL   t |dkrdS |d }|d}|d dkr$|ddr$t|tr$|S dS )	z
        Get the prefix prompt from the messages.

        Check last message
        - if it's assistant message, with 'prefix': true, return the content

        E.g. :    {"role": "assistant", "content": "Argentina", "prefix": True}
        r   Nr   r+  Z	assistantprefixF)r   r`   r   rp   )rN   r*  r0  r4  rV   rV   rW   get_prefix_prompt  s   	

z!AnthropicConfig.get_prefix_promptlogging_objrequest_dataencodingapi_keyc              
   C   s   |j ||
|jd|id z| }W n! ty3 } zt|dd }tdt||j|j|dd }~ww | j	|d}|
d}| j||||||d}|S )	NZcomplete_input_dict)rk   r  ru  Zadditional_argsr   z7Unable to get json response - {}, Original Response: {}rr  rE  r   )rQ  rn  ro  r  rp  r   )Z	post_callr
  rn   re   rv  rA   r   rp   rF  r  r`   r|  )rN   r]   rn  ro  r  r  r*  r  rB  r  r  r  rQ  rI  r{  rp  r   rV   rV   rW   transform_response  s<   


z"AnthropicConfig.transform_responsec                 C   s   | d d  d}z2|dur9t|}t|tr-| d }dur-tjt|d}|W S tjt|d}|W S W dS  tjyK   tj|d Y S w )z
        In JSON mode, Anthropic API returns JSON schema as a tool call, we need to convert it to a message to follow the OpenAI format

        r   ri   rl   NvaluesrT  )	r`   rn   loadsr   r   r   r4   ro   JSONDecodeError)rL  rO  argsr  rN  rV   rV   rW   rM  ;  s$   	
z1AnthropicConfig._convert_tool_response_to_messageerror_messagerF  c                 C   s   t ||ttj|dS )N)rF  r0  r   )rA   r	   httpxHeaders)rN   r  rF  r   rV   rV   rW   get_error_classZ  s
   
zAnthropicConfig.get_error_class)NNNNNNNrt   )NN)NNN)]__name__
__module____qualname____doc__rF   r   r  r   rG   r   rH   rI   rJ   rK   r   rL   rp   rX   propertyr[   classmethodr_   staticmethodra   r   r   r,   rr   r   r~   r   r   r   r   r   r    r   r.   r   r   r   r   r0   r   r   r   r   r   r   r   r&   r#   r  r  r!   r  r   r  r1   r$   r  r  r(  r  r'   r"   r2  r   r3  r;  r   r=  rA  rK  LitellmMessagerP  r+   r)   r]  r8   rm  r  Responser7   r|  r  LoggingClassr  rM  r  r   r  __classcell__rV   rV   rd   rW   rE   Q   s<  
 	
	
!$q

)
 A


-

!



:
 

E
"
(
(
 





m
u
s"	

0rE   r   rM   c                 C   s,   d}d}t || rdS t || rdS dS )z
    Validate that user_id is not an email or phone number.
    Returns: bool: True if valid (not email or phone), False otherwise
    z0^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$z^\+?[\d\s\(\)-]{7,}$FT)rematch)r   Zemail_patternZphone_patternrV   rV   rW   r%  d  s   r%  )Xrn   r  ry  typingr   r   r   r   r   r   r   r	   r  r   Zlitellm.constantsr
   r   r   r   r   r   r   Z'litellm.litellm_core_utils.core_helpersr   Z litellm.llms.base_llm.base_utilsr   Z)litellm.llms.base_llm.chat.transformationr   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   Zlitellm.types.llms.openair&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   Zlitellm.types.utilsr2   r3   r4   r  r5   r6   Zlitellm.utilsr7   r8   r9   r:   r;   r<   r=   r>   r?   Zcommon_utilsrA   rB   rC   Z*litellm.litellm_core_utils.litellm_loggingrD   ZLiteLLMLoggingObjr  rE   rp   r   r%  rV   rV   rV   rW   <module>   sJ    ($	H8,              !