mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-06 07:48:06 +00:00
feat(exa): reuse provider list-price fallback
Adapted the fallback estimator and Exa catalog entries from #46525. Follow-up refinements by Kes and Mateo retain native count precedence, summary charges, Lite pricing, and compatibility tiers. Source commits:d0a37501fc,d150fb91db,8185114b5b,78acd12678,f691d27d5f,43c59c2cd7,96a2b14005Co-authored-by: kesku <admin@kesku.me> Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
This commit is contained in:
parent
f7c34a3331
commit
e9727d2738
3 changed files with 134 additions and 0 deletions
|
|
@ -59,3 +59,49 @@ def exa_ai_price_set(entry: object) -> bool:
|
|||
fields: Final = _ENTRY.validate_python(entry)
|
||||
tiers: Final = fields.get("tiered_pricing")
|
||||
return fields.get("input_cost_per_query") is not None or (tiers is not None and not _legacy_tiers(tiers))
|
||||
|
||||
|
||||
EXA_AI_INCLUDED_RESULTS: Final = 10
|
||||
EXA_AI_ADDITIONAL_RESULT_COST: Final = 0.001
|
||||
EXA_AI_SUMMARY_COST_PER_PAGE: Final = 0.001
|
||||
EXA_AI_TYPES_WITHOUT_SUMMARIES: Final = frozenset({"lite"})
|
||||
_CONTENTS: Final = TypeAdapter(Mapping[str, object])
|
||||
|
||||
|
||||
def _non_negative_int(value: object) -> int | None:
|
||||
if isinstance(value, bool) or not isinstance(value, int) or value < 0:
|
||||
return None
|
||||
return value
|
||||
|
||||
|
||||
def _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
|
||||
|
||||
|
||||
def _requests_summaries(optional_params: Mapping[str, object]) -> bool:
|
||||
if optional_params.get("type") in EXA_AI_TYPES_WITHOUT_SUMMARIES:
|
||||
return False
|
||||
contents: Final = optional_params.get("contents")
|
||||
return isinstance(contents, Mapping) and _CONTENTS.validate_python(contents).get("summary") not in (None, False)
|
||||
|
||||
|
||||
def exa_ai_list_price(base_price: float, optional_params: Mapping[str, object]) -> float:
|
||||
"""
|
||||
List price of one Exa /search request, for responses that carry no `costDollars.total`.
|
||||
|
||||
Multi-query searches are joined into a single request, so this prices one request:
|
||||
the search type's base price, a per-result charge above the results that price includes,
|
||||
and a per-page charge for each requested result when summaries are requested on a type that offers them.
|
||||
"""
|
||||
results: Final = _requested_results(optional_params)
|
||||
additional_results: Final = max(results - EXA_AI_INCLUDED_RESULTS, 0)
|
||||
summarized_pages: Final = results if _requests_summaries(optional_params) else 0
|
||||
return (
|
||||
base_price
|
||||
+ additional_results * EXA_AI_ADDITIONAL_RESULT_COST
|
||||
+ summarized_pages * EXA_AI_SUMMARY_COST_PER_PAGE
|
||||
)
|
||||
|
|
|
|||
|
|
@ -24315,7 +24315,11 @@
|
|||
"output_vector_size": 2560
|
||||
},
|
||||
"exa_ai/search": {
|
||||
"input_cost_per_query": 0.007,
|
||||
"litellm_provider": "exa_ai",
|
||||
"metadata": {
|
||||
"notes": "Base price per /search request, covering up to 10 results. Each result above 10 adds $0.001, and each summarized page adds $0.001. Exa's reported costDollars.total takes precedence when present, unless an operator priced this entry. tiered_pricing keeps what older releases bill for this entry. Source: https://exa.ai/pricing (2026-10-15)"
|
||||
},
|
||||
"mode": "search",
|
||||
"tiered_pricing": [
|
||||
{
|
||||
|
|
@ -24334,6 +24338,46 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"exa_ai/search-lite": {
|
||||
"input_cost_per_query": 0.004,
|
||||
"litellm_provider": "exa_ai",
|
||||
"metadata": {
|
||||
"notes": "Base price per /search request with type lite, covering up to 10 results. Source: https://exa.ai/pricing (2026-10-22)"
|
||||
},
|
||||
"mode": "search"
|
||||
},
|
||||
"exa_ai/search-instant": {
|
||||
"input_cost_per_query": 0.004,
|
||||
"litellm_provider": "exa_ai",
|
||||
"metadata": {
|
||||
"notes": "Base price per /search request with type instant, covering up to 10 results. Source: https://exa.ai/pricing (2026-10-15)"
|
||||
},
|
||||
"mode": "search"
|
||||
},
|
||||
"exa_ai/search-deep": {
|
||||
"input_cost_per_query": 0.012,
|
||||
"litellm_provider": "exa_ai",
|
||||
"metadata": {
|
||||
"notes": "Base price per /search request with type deep, covering up to 10 results. Source: https://exa.ai/pricing (2026-10-15)"
|
||||
},
|
||||
"mode": "search"
|
||||
},
|
||||
"exa_ai/search-deep-lite": {
|
||||
"input_cost_per_query": 0.012,
|
||||
"litellm_provider": "exa_ai",
|
||||
"metadata": {
|
||||
"notes": "Base price per /search request with type deep-lite, covering up to 10 results. Source: https://exa.ai/docs/reference/pricing (2026-10-27)"
|
||||
},
|
||||
"mode": "search"
|
||||
},
|
||||
"exa_ai/search-deep-reasoning": {
|
||||
"input_cost_per_query": 0.015,
|
||||
"litellm_provider": "exa_ai",
|
||||
"metadata": {
|
||||
"notes": "Base price per /search request with type deep-reasoning, covering up to 10 results. Source: https://exa.ai/pricing (2026-10-15)"
|
||||
},
|
||||
"mode": "search"
|
||||
},
|
||||
"firecrawl/search": {
|
||||
"litellm_provider": "firecrawl",
|
||||
"mode": "search",
|
||||
|
|
|
|||
|
|
@ -24315,7 +24315,11 @@
|
|||
"output_vector_size": 2560
|
||||
},
|
||||
"exa_ai/search": {
|
||||
"input_cost_per_query": 0.007,
|
||||
"litellm_provider": "exa_ai",
|
||||
"metadata": {
|
||||
"notes": "Base price per /search request, covering up to 10 results. Each result above 10 adds $0.001, and each summarized page adds $0.001. Exa's reported costDollars.total takes precedence when present, unless an operator priced this entry. tiered_pricing keeps what older releases bill for this entry. Source: https://exa.ai/pricing (2026-10-15)"
|
||||
},
|
||||
"mode": "search",
|
||||
"tiered_pricing": [
|
||||
{
|
||||
|
|
@ -24334,6 +24338,46 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"exa_ai/search-lite": {
|
||||
"input_cost_per_query": 0.004,
|
||||
"litellm_provider": "exa_ai",
|
||||
"metadata": {
|
||||
"notes": "Base price per /search request with type lite, covering up to 10 results. Source: https://exa.ai/pricing (2026-10-22)"
|
||||
},
|
||||
"mode": "search"
|
||||
},
|
||||
"exa_ai/search-instant": {
|
||||
"input_cost_per_query": 0.004,
|
||||
"litellm_provider": "exa_ai",
|
||||
"metadata": {
|
||||
"notes": "Base price per /search request with type instant, covering up to 10 results. Source: https://exa.ai/pricing (2026-10-15)"
|
||||
},
|
||||
"mode": "search"
|
||||
},
|
||||
"exa_ai/search-deep": {
|
||||
"input_cost_per_query": 0.012,
|
||||
"litellm_provider": "exa_ai",
|
||||
"metadata": {
|
||||
"notes": "Base price per /search request with type deep, covering up to 10 results. Source: https://exa.ai/pricing (2026-10-15)"
|
||||
},
|
||||
"mode": "search"
|
||||
},
|
||||
"exa_ai/search-deep-lite": {
|
||||
"input_cost_per_query": 0.012,
|
||||
"litellm_provider": "exa_ai",
|
||||
"metadata": {
|
||||
"notes": "Base price per /search request with type deep-lite, covering up to 10 results. Source: https://exa.ai/docs/reference/pricing (2026-10-27)"
|
||||
},
|
||||
"mode": "search"
|
||||
},
|
||||
"exa_ai/search-deep-reasoning": {
|
||||
"input_cost_per_query": 0.015,
|
||||
"litellm_provider": "exa_ai",
|
||||
"metadata": {
|
||||
"notes": "Base price per /search request with type deep-reasoning, covering up to 10 results. Source: https://exa.ai/pricing (2026-10-15)"
|
||||
},
|
||||
"mode": "search"
|
||||
},
|
||||
"firecrawl/search": {
|
||||
"litellm_provider": "firecrawl",
|
||||
"mode": "search",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue