Ë
    tPêj_2  ã                   óæ  — U d 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dl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­ ddlmZ ddlmZmZmZ ddlmZ ddl m!Z!  e«       Z"ee#d<   de$ddfd„Z%e"jM                  ddg ee«      g¬«       ee«      fdedede'fd„«       Z(e"jM                  ddg ee«      g¬«       ee«      fdede'fd„«       Z)e"jM                  ddg¬ «      defd!„«       Z*y)"z2
Unified /v1/messages endpoint - (Anthropic Spec)
é    )ÚFinal)Ú	APIRouterÚDependsÚHTTPExceptionÚRequestÚResponse)ÚJSONResponseN)Úverbose_proxy_logger)ÚAnthropicExceptionMapping)ÚModifyResponseException)ÚAnthropicContextManagementError)Úblocked_response_usage)Ú*)Úuser_api_key_auth)ÚProxyBaseLLMRequestProcessingÚcreate_responseÚ#proxy_exception_from_http_exception)Ú_read_request_body)ÚTokenCountResponseÚrouterÚresponseÚreturnc                 ó  — | €yt        | t        «      r8| j                  d«      }t        |t        «      rd|v r|j                  dd«       yt	        | dd«      }t        |t        «      rd|v r|j                  dd«       yyy)u  Remove the OpenAI-flavored `usage.total_tokens` field that LiteLLM
    injects into Anthropic /v1/messages responses.

    The Anthropic /v1/messages spec only defines:
        input_tokens, output_tokens, cache_creation_input_tokens,
        cache_read_input_tokens, cache_creation.{ephemeral_5m,ephemeral_1h}
    The streaming SSE path (message_delta.usage) already does not include
    total_tokens; this brings the non-streaming path into the same shape.

    Handles both shapes returned by `base_process_llm_request`:
    - plain `dict` (most common â€” `AnthropicMessagesResponse` is a TypedDict
      and is `dict` at runtime)
    - Pydantic model whose `usage` attribute is dict-shaped (e.g. a
      BaseModel that holds raw Anthropic usage as a `dict[str, int]`)

    Streaming results (StreamingResponse, AsyncIterator, etc.) and Pydantic
    models with strongly-typed Usage sub-models are left untouched â€”
    those paths either have separate serialization handling or impose
    type constraints the helper does not try to subvert.
    NÚusageÚtotal_tokens)Ú
isinstanceÚdictÚgetÚpopÚgetattr)r   r   s     úp/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/anthropic_endpoints/endpoints.pyÚ+_strip_total_tokens_from_anthropic_responser"   !   s|   € ð* ÐØÜ�(œDÔ!Ø—‘˜WÓ%ˆÜ�eœTÔ" ~¸Ñ'>Ø�I‰I�n dÔ+Øä�H˜g tÓ,€EÜ�%œÔ >°UÑ#:Ø�	‰	�. $Õ'ð $;Ðó    z/v1/messagesz[beta] Anthropic `/v1/messages`)ÚtagsÚdependenciesÚfastapi_responseÚrequestÚuser_api_key_dictc              ƒ   ó°  ‡K  — ddl m}m}m}m}m}m}m}	m}
m	}m
} t        |¬«      ƒ d{  –—† }t        |¬«      }	 |j                  || |d||||dd|	||
|||¬«      ƒ d{  –—† }t        j                  rt!        |«       |S 7 ŒW7 Œ## t"        $ rä}|j$                  }|j'                  |||¬«      ƒ d{  –—†7   ddl}dd	lm} t/        |j0                  «      } |d
|j3                  «       › �ddd|j4                  dœg|j6                  d|¬«      Š|j9                  dd«      �F|d   du r?ˆfd„}t        j:                   |«       |||¬«      }t=        |di ¬«      ƒ d{  –—†7  cY d}~S ‰cY d}~S d}~wt>        $ rœ}|j@                  dk\  r'|j'                  |||jB                  ¬«      ƒ d{  –—†7   tE        jF                  |j@                  |j4                  |jH                  j9                  d«      ¬«      }tK        |j@                  |¬«      cY d}~S d}~wtL        $ �r4}|j'                  |||jB                  ¬«      ƒ d{  –—†7   tO        jP                  d|«       tS        |tT        «      r‚ |j9                  di «      xs i }|j9                  di «      xs i }|j9                  dd«      xs d}t        jV                  ||j9                  d d«      ||dtY        |d!d«      |tY        |d"d«      d¬#«	      }tS        |tZ        «      rt]        ||«      ‚|› }tU        tY        |d|«      tY        |d$d%«      tY        |d&d%«      tY        |d'd«      |¬(«      ‚d}~ww xY w­w))zÔ
    Use `{PROXY_BASE_URL}/anthropic/v1/messages` instead - [Docs](https://docs.litellm.ai/docs/pass_through/anthropic_completion).

    This was a BETA endpoint that calls 100+ LLMs in the anthropic format.
    r   )
Úgeneral_settingsÚ
llm_routerÚproxy_configÚproxy_logging_objÚuser_api_baseÚuser_max_tokensÚ
user_modelÚuser_request_timeoutÚuser_temperatureÚversion©r'   N)ÚdataÚanthropic_messages)r'   r&   r(   Ú
route_typer-   r+   r*   r,   Úselect_data_generatorÚmodelr0   r2   r1   r/   r.   r3   )r(   Úoriginal_exceptionÚrequest_data)ÚAnthropicMessagesResponseÚmsg_ÚmessageÚ	assistantÚtext)Útyper@   Úend_turn)ÚidrA   ÚroleÚcontentr9   Ústop_reasonr   ÚstreamTc                 ó   •K  — ‰ ­–— y ­w)N© )Ú_anthropic_responses   €r!   Ú_passthrough_stream_generatorz9anthropic_response.<locals>._passthrough_stream_generatorŸ   s   øè ø€ Ø)Ô)ùs   ƒ
)r   r(   r;   r-   ztext/event-stream)Ú	generatorÚ
media_typeÚheaderséô  zx-request-id)Ústatus_codeÚraw_messageÚ
request_id)rP   rE   zGlitellm.proxy.proxy_server.anthropic_response(): Exception occured - %sÚlitellm_metadataÚ
model_inforC   Ú Úlitellm_call_idÚallowed_model_regionÚtimeout)	r(   Úcall_idÚmodel_idr3   Úresponse_costÚmodel_regionr;   rX   Úlitellm_logging_objrA   ÚNoneÚparamrP   )r>   rA   r_   ÚcoderN   )/Úlitellm.proxy.proxy_serverr*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r   r   Úbase_process_llm_requestÚlitellmÚstrip_anthropic_total_tokensr"   r   r;   Úpost_call_failure_hookÚuuidÚlitellm.types.utilsr<   Ú_blocked_response_usageÚoriginal_responseÚuuid4r>   r9   r   Úasync_sse_data_generatorr   r   rP   r5   r   Útransform_to_anthropic_errorrN   r	   Ú	Exceptionr
   Ú	exceptionr   ÚProxyExceptionÚget_custom_headersr    r   r   )r&   r'   r(   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r5   Úbase_llm_response_processorÚresultÚeÚ_datarf   r<   Ú_usagerK   Úselected_data_generatorÚbodyrS   rT   rZ   rN   Ú	error_msgrJ   s                                @r!   Úanthropic_responsery   C   s|  øè ø€ ÷÷ ÷ ô +°7Ô;×;€DÜ)FÈDÔ)QÐðC
Ø9×RÑRØØ-Ø/Ø+Ø/Ø!Ø-Ø%Ø"&ØØ!Ø-Ø!5Ø+Ø'Øð! Só 
÷ 
ˆô8 ×/Ò/Ü7¸Ô?ØˆðC <øð
ùô> #ò .#à—~‘~ˆØ×6Ñ6Ø/Ø Øð 7ó 
÷ 	
ñ 	
ó 	åAô 0°×0CÑ0CÓDˆá%>Ø�d—j‘j“l�^Ð$ØØØ$¨a¯i©iÑ8Ð9Ø—'‘'Ø"Øô&
Ðð �8‰8�H˜dÓ#Ð/°D¸±NÀdÑ4Jô*ô .K×-cÑ-cÙ6Ó8Ø"3Ø"Ø"3ô	.Ð#ô )Ø1Ø.Øô÷ ð õ ð #Õ"ûÜ*ò EØ�=‰=˜CÒð $×:Ñ:Ø"3Ø#$Ø8×=Ñ=ð ;ó ÷ ñ ô
 0×LÑLØŸ™ØŸ	™	Ø—‘×*Ñ*¨>Ó:ô
ˆô
 ¨¯©¸tÔDÕDûÜó %
Ø×6Ñ6Ø/ÀAÐTo×TtÑTtð 7ó 
÷ 	
ñ 	
ô 	×&Ñ&Ð'pÐrsÔtä�aœÔ(Øð #'§(¡(Ð+=¸rÓ"BÒ"HÀbÐØ,×0Ñ0°¸rÓBÒHÀbˆ
Ø$Ÿ.™.¨¨rÓ2Ò8°bˆô 7×IÑIØ/Ø—H‘HÐ.°Ó3ØØØÜ Ð!2Ð4JÈBÓOØÜ˜A˜y¨$Ó/Ø $ô

ˆô �aœÔ'Ü5°a¸ÓAÐAà˜Sˆ	ÜÜ˜A˜y¨)Ó4Ü˜˜F FÓ+Ü˜!˜W fÓ-Ü˜˜M¨3Ó/Øô
ð 	
ûð?%
üs¹   ƒ(M«B¬M½$B Á!BÁ" B ÂMÂB Â	MÂ#E/Â3B6Â4B)E/ÅE ÅE/Å"MÅ#MÅ(E/Å)MÅ*MÅ/MÅ;0HÆ+F.Æ,A HÈMÈMÈMÈ!MÉ IÉDMÍMÍMz/v1/messages/count_tokensz([beta] Anthropic Messages Token Countingc              ƒ   ób  K  — ddl m} 	 t        | ¬«      ƒ d{  –—† }i |¥}|j                  d«      }|j                  dg «      }|st	        ddd	i¬
«      ‚|st	        dddi¬
«      ‚ddlm}  ||||j                  d«      |j                  d«      ¬«      } ||d¬«      ƒ d{  –—† }	i }
t        |	t        «      r|	j                  «       }
nt        |	t        «      r|	}
d|
j                  dd«      iS 7 ŒØ7 ŒO# t        $ r ‚ t        $ rp}|j                  r/|j                  j                  «       rt        |j                  «      nd}t        j                   ||j"                  ¬«      }t	        ||¬
«      ‚d}~wt$        $ r-}t'        j(                  d|«       t	        ddd|› �i¬
«      ‚d}~ww xY w­w)aŠ  
    Count tokens for Anthropic Messages API format.
    
    This endpoint follows the Anthropic Messages API token counting specification.
    It accepts the same parameters as the /v1/messages endpoint but returns
    token counts instead of generating a response.
    
    Example usage:
    ```
    curl -X POST "http://localhost:4000/v1/messages/count_tokens?beta=true"       -H "Content-Type: application/json"       -H "Authorization: Bearer your-key"       -d '{
        "model": "claude-3-sonnet-20240229",
        "messages": [{"role": "user", "content": "Hello Claude!"}]
      }'
    ```
    
    Returns: {"input_tokens": <number>}
    r   )Útoken_counterr4   Nr9   Úmessagesi�  Úerrorzmodel parameter is required)rP   Údetailzmessages parameter is required)ÚTokenCountRequestÚtoolsÚsystem)r9   r|   r€   r�   T)r'   Úcall_endpointÚinput_tokensr   rO   )rP   rQ   zIlitellm.proxy.anthropic_endpoints.count_tokens(): Exception occurred - %szInternal server error: )ra   r{   r   r   r   Úlitellm.proxy._typesr   r   r   Ú
model_dumpr   ro   r`   ÚisdigitÚintr   rl   r>   rm   r
   rn   )r'   r(   Úinternal_token_counterr;   r5   Ú
model_namer|   r   Útoken_requestÚtoken_responseÚ_token_response_dictrs   rP   r~   s                 r!   Úcount_tokensr�   ç   s»  è ø€ õ: Sð4^Ü$6¸wÔ$G×GˆØ,˜|Ð,ˆð !ŸH™H WÓ-ˆ
ØŸ(™( :¨rÓ2ˆáÜ¨C¸ÐB_Ð8`ÔaÐaáÜ¨C¸ÐBbÐ8cÔdÐdõ 	;á0ØØØ—(‘(˜7Ó#Ø—8‘8˜HÓ%ô	 
ˆñ '=Ø!Øô'
÷ !
ˆð &(ÐÜ�nÔ&8Ô9Ø#1×#<Ñ#<Ó#>Ñ Ü˜¬Ô-Ø#1Ð ð Ð 4× 8Ñ 8¸ÈÓ KÐLÐLðG Høð0!
ùô ò ØÜò 	
Ø,-¯FªF°q·v±v·~±~Ô7GœS §¡œ[ÈSˆÜ1×NÑNØ#ØŸ	™	ô
ˆô Ø#Øô
ð 	
ûô ò ^Ü×&Ñ&Ð'rÐtuÔvÜ¨°WÐ@WÐXYÐWZÐ>[Ð4\Ô]Ð]ûð^üsY   ‚F/ŠC6 ™C2šB
C6 Â$C4Â%AC6 Ã1F/Ã2C6 Ã4C6 Ã6F,ÄA+E3Å3F,Å?(F'Æ'F,Æ,F/z/api/event_logging/batchz[beta] Anthropic Event Logging)r$   c              ƒ   ó   K  — ddiS ­w)zæ
    Stubbed endpoint for Anthropic event logging batch requests.

    This endpoint accepts event logging requests but does nothing with them.
    It exists to prevent 404 errors from Claude Code clients that send telemetry.
    ÚstatusÚokrI   r4   s    r!   Úevent_logging_batchr‘   =  s   è ø€ ð �dÐÐùs   ‚)+Ú__doc__Útypingr   Úfastapir   r   r   r   r   Úfastapi.responsesr	   rc   Úlitellm._loggingr
   Ú&litellm.anthropic_interface.exceptionsr   Ú%litellm.integrations.custom_guardrailr   ÚClitellm.llms.anthropic.experimental_pass_through.context_managementr   Ú1litellm.llms.base_llm.guardrail_translation.utilsr   rh   r„   Ú$litellm.proxy.auth.user_api_key_authr   Ú'litellm.proxy.common_request_processingr   r   r   Ú-litellm.proxy.common_utils.http_parsing_utilsr   rg   r   r   Ú__annotations__ÚAnyr"   ÚpostÚUserAPIKeyAuthry   r�   r‘   rI   r#   r!   ú<module>r¢      sY  ðòõ ç HÕ HÝ *ã Ý 1Ý LÝ Iõõô #Ý B÷ñ õ
 MÝ 2á“€ˆÓ ð(¸#ð (À$ó (ðD ‡�ØØ
+Ð	,ÙÐ+Ó,Ð-ð ó ñ )0Ð0AÓ(Bñ\
Øð\
àð\
ð &ò\
óð
\
ð~ ‡�ØØ
4Ð	5ÙÐ+Ó,Ð-ð ó ñ )0Ð0AÓ(BñN^ØðN^à%òN^óð
N^ðb ‡�ØØ
*Ð	+ð ó ð	Øò	ó	ñ	r#   