From d0c82c7eba96b0adc714ecd9e6211b9fce5e9c2f Mon Sep 17 00:00:00 2001 From: Ishaan Jaffer Date: Tue, 20 Jan 2026 11:58:17 -0800 Subject: [PATCH] fix count_tokens_with_anthropic_api --- litellm/proxy/utils.py | 71 +----------------------------------------- 1 file changed, 1 insertion(+), 70 deletions(-) diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index fcb678ef02a..e0855333e26 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -131,7 +131,6 @@ else: unified_guardrail = UnifiedLLMGuardrails() -_anthropic_async_clients = {} def print_verbose(print_statement): """ @@ -961,8 +960,8 @@ class ProxyLogging: Returns: Updated data dictionary if guardrail passes, None if guardrail should be skipped """ - from litellm.types.guardrails import GuardrailEventHooks from litellm.integrations.prometheus import PrometheusLogger + from litellm.types.guardrails import GuardrailEventHooks # Determine the event type based on call type event_type = GuardrailEventHooks.pre_call @@ -4292,74 +4291,6 @@ def construct_database_url_from_env_vars() -> Optional[str]: return None -async def count_tokens_with_anthropic_api( - model_to_use: str, - messages: Optional[List[Dict[str, Any]]], - deployment: Optional[Dict[str, Any]] = None, -) -> Optional[Dict[str, Any]]: - """ - Helper function to count tokens using Anthropic API directly. - - Args: - model_to_use: The model name to use for token counting - messages: The messages to count tokens for - deployment: Optional deployment configuration containing API key - - Returns: - Optional dict with token count and tokenizer info, or None if failed - """ - if not messages: - return None - - try: - import os - - import anthropic - - # Get Anthropic API key from deployment config - anthropic_api_key = None - if deployment is not None: - anthropic_api_key = deployment.get("litellm_params", {}).get("api_key") - - # Fallback to environment variable - if not anthropic_api_key: - anthropic_api_key = os.getenv("ANTHROPIC_API_KEY") - - if anthropic_api_key and messages: - # Call Anthropic API directly for more accurate token counting - - # Use cached client if available to avoid socket exhaustion - if anthropic_api_key not in _anthropic_async_clients: - _anthropic_async_clients[anthropic_api_key] = anthropic.AsyncAnthropic(api_key=anthropic_api_key) - - client = _anthropic_async_clients[anthropic_api_key] - - # Call with explicit parameters to satisfy type checking - # Type ignore for now since messages come from generic dict input - response = await client.beta.messages.count_tokens( - model=model_to_use, - messages=messages, # type: ignore - betas=["token-counting-2024-11-01"], - ) - total_tokens = response.input_tokens - tokenizer_used = "anthropic_api" - - return { - "total_tokens": total_tokens, - "tokenizer_used": tokenizer_used, - } - - except ImportError: - verbose_proxy_logger.warning( - "Anthropic library not available, falling back to LiteLLM tokenizer" - ) - except Exception as e: - verbose_proxy_logger.warning( - f"Error calling Anthropic API: {e}, falling back to LiteLLM tokenizer" - ) - return None - - async def get_available_models_for_user( user_api_key_dict: "UserAPIKeyAuth", llm_router: Optional["Router"],