diff --git a/litellm/cost_calculator.py b/litellm/cost_calculator.py index 17f626da070..04e399851e0 100644 --- a/litellm/cost_calculator.py +++ b/litellm/cost_calculator.py @@ -1914,7 +1914,7 @@ def completion_cost( model=search_model, custom_llm_provider=custom_llm_provider, number_of_queries=number_of_queries, - response=completion_response, + response=_ATTRIBUTE_VALUE.validate_python(completion_response), optional_params={ **(get_hidden_params(completion_response) or {}), **(optional_params or {}), diff --git a/litellm/llms/exa_ai/search/cost_calculator.py b/litellm/llms/exa_ai/search/cost_calculator.py index 5b8d6f96602..8477a913754 100644 --- a/litellm/llms/exa_ai/search/cost_calculator.py +++ b/litellm/llms/exa_ai/search/cost_calculator.py @@ -73,7 +73,9 @@ def exa_ai_price_fields(model: str, entry: object) -> frozenset[str]: if not isinstance(entry, Mapping): return frozenset() fields: Final = _ENTRY.validate_python(entry) - registered: Final = entry.registered_fields & _PRICE_FIELDS if isinstance(entry, AliasedCostEntry) else frozenset() + registered: Final[frozenset[str]] = ( + entry.registered_fields & _PRICE_FIELDS if isinstance(entry, AliasedCostEntry) else frozenset() + ) if registered: return registered source: Final = get_model_cost_map_source_info() @@ -108,11 +110,14 @@ def _non_negative_int(value: object) -> int | None: def exa_ai_requested_results(optional_params: Mapping[str, object]) -> int: - for key in ("max_results", "numResults"): - requested: Final = _non_negative_int(optional_params.get(key)) - if requested is not None: - return requested - return EXA_AI_INCLUDED_RESULTS + return next( + ( + requested + for key in ("max_results", "numResults") + if (requested := _non_negative_int(optional_params.get(key))) is not None + ), + EXA_AI_INCLUDED_RESULTS, + ) def _requests_summaries(optional_params: Mapping[str, object]) -> bool: diff --git a/litellm/llms/exa_ai/search/transformation.py b/litellm/llms/exa_ai/search/transformation.py index b8b76404bcc..5d2ff5816c8 100644 --- a/litellm/llms/exa_ai/search/transformation.py +++ b/litellm/llms/exa_ai/search/transformation.py @@ -4,7 +4,7 @@ Calls Exa AI's /search endpoint to search the web. Exa AI API Reference: https://docs.exa.ai/reference/search """ -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Iterable, Mapping from typing import Final import httpx diff --git a/litellm/search/cost_calculator.py b/litellm/search/cost_calculator.py index b5efe0a68c9..df2c527e638 100644 --- a/litellm/search/cost_calculator.py +++ b/litellm/search/cost_calculator.py @@ -104,6 +104,7 @@ def search_provider_cost_per_query( custom_llm_provider: Provider name (e.g., "exa_ai", "tavily") number_of_queries: Number of search queries performed (default: 1) optional_params: Optional parameters including max_results for tiered pricing + response: Search response carrying Exa's reported cost Returns: Tuple of (input_cost, output_cost) where output_cost is always 0.0 @@ -122,7 +123,7 @@ def search_provider_cost_per_query( pricing_model: Final = _pricing_model(model, custom_llm_provider, optional_params) params: Final = optional_params if optional_params is not None else EMPTY_OPTIONAL_PARAMS - exa_price_fields: Final = ( + exa_price_fields: Final[frozenset[str]] = ( exa_ai_price_fields( _generic_search_entry(pricing_model, custom_llm_provider), _live_entry(_generic_search_entry(pricing_model, custom_llm_provider)), diff --git a/litellm/utils.py b/litellm/utils.py index 0d3d1d19173..78b2c8e9557 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -3516,7 +3516,7 @@ def _replace_cost_map_entry( current.registered_fields if isinstance(current, AliasedCostEntry) else frozenset() ) supplied_fields: Final = frozenset(name for name, value in registration.items() if value is not None) - replaced_fields: Final = ( + replaced_fields: Final[frozenset[str]] = ( frozenset({"input_cost_per_query", "tiered_pricing"}) if merged.get("litellm_provider") == "exa_ai" and supplied_fields & {"input_cost_per_query", "tiered_pricing"} else frozenset()