Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions litellm/llms/perplexity/cost_calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,11 @@ def _safe_float_cast(
if num_search_queries > 0 and search_cost_value is not None:
# Handle both dict and float formats
if isinstance(search_cost_value, dict):
# Use the "low" size as default - tests expect 0.005 / 1000
search_cost_per_query = (
_safe_float_cast(search_cost_value.get("search_context_size_low", 0))
/ 1000
# search_context_cost_per_query stores the per-request price in USD
# (e.g. sonar low = $0.005/request). Use it directly, matching the
# gemini cost calculator which reads the same field per request.
search_cost_per_query = _safe_float_cast(
search_cost_value.get("search_context_size_low", 0)
)
else:
search_cost_per_query = _safe_float_cast(search_cost_value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import math
import os
import sys
from unittest.mock import Mock, patch
from unittest.mock import patch

import pytest

Expand Down Expand Up @@ -120,10 +120,10 @@ def test_search_queries_cost_calculation(self):
# Expected costs:
# Input: 100 tokens * $2e-6 = $0.0002
# Output: 50 tokens * $8e-6 = $0.0004
# Search: 3 queries * ($0.005 / 1000) = $0.000015
# Total completion cost: $0.000415
# Search: 3 queries * $0.005 per request = $0.015
# Total completion cost: $0.0154
expected_prompt_cost = 100 * 2e-6
expected_completion_cost = (50 * 8e-6) + (3 / 1000 * 0.005)
expected_completion_cost = (50 * 8e-6) + (3 * 0.005)

assert math.isclose(prompt_cost, expected_prompt_cost, rel_tol=1e-6)
assert math.isclose(completion_cost, expected_completion_cost, rel_tol=1e-6)
Expand Down Expand Up @@ -195,10 +195,10 @@ def test_comprehensive_cost_calculation(self):
# Total prompt cost = $0.00026
# Output (text): (50 - 15) tokens * $8e-6 = $0.00028
# Reasoning: 15 tokens * $3e-6 = $0.000045
# Search: 2 queries * ($0.005 / 1000) = $0.00001
# Total completion cost = $0.000335
# Search: 2 queries * $0.005 per request = $0.01
# Total completion cost = $0.010325
expected_prompt_cost = (100 * 2e-6) + (30 * 2e-6)
expected_completion_cost = ((50 - 15) * 8e-6) + (15 * 3e-6) + (2 / 1000 * 0.005)
expected_completion_cost = ((50 - 15) * 8e-6) + (15 * 3e-6) + (2 * 0.005)

assert math.isclose(prompt_cost, expected_prompt_cost, rel_tol=1e-6)
assert math.isclose(completion_cost, expected_completion_cost, rel_tol=1e-6)
Expand Down Expand Up @@ -311,7 +311,7 @@ def test_integration_with_completion_cost_function(self):
# Calculate expected total cost (reasoning is a subset of completion_tokens)
expected_prompt_cost = (100 * 2e-6) + (15 * 2e-6) # Input + citation
expected_completion_cost = (
((50 - 10) * 8e-6) + (10 * 3e-6) + (1 / 1000 * 0.005)
((50 - 10) * 8e-6) + (10 * 3e-6) + (1 * 0.005)
) # Output (text) + reasoning + search
expected_total = expected_prompt_cost + expected_completion_cost

Expand Down Expand Up @@ -361,7 +361,7 @@ def test_cost_calculation_combinations(
expected_completion_cost = (
((50 - reasoning_tokens) * 8e-6)
+ (reasoning_tokens * 3e-6)
+ (search_queries / 1000 * 0.005)
+ (search_queries * 0.005)
)

assert math.isclose(prompt_cost, expected_prompt_cost, rel_tol=1e-6)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import math
import os
import sys
from unittest.mock import Mock, patch

import pytest

Expand Down Expand Up @@ -106,8 +105,8 @@ def test_end_to_end_cost_calculation_with_transformation(self):

expected_prompt_cost = (100 * 2e-6) + (citation_tokens * 2e-6)
expected_completion_cost = (
((50 - 10) * 8e-6) + (10 * 3e-6) + (2 / 1000 * 0.005)
)
((50 - 10) * 8e-6) + (10 * 3e-6) + (2 * 0.005)
) # Output (text) + reasoning + search
expected_total = expected_prompt_cost + expected_completion_cost

assert math.isclose(total_cost, expected_total, rel_tol=1e-6)
Expand Down Expand Up @@ -152,8 +151,8 @@ def test_main_cost_calculator_integration(self):

expected_prompt_cost = (200 * 2e-6) + (40 * 2e-6)
expected_completion_cost = (
((100 - 25) * 8e-6) + (25 * 3e-6) + (3 / 1000 * 0.005)
)
((100 - 25) * 8e-6) + (25 * 3e-6) + (3 * 0.005)
) # Output (text) + reasoning + search

assert math.isclose(prompt_cost, expected_prompt_cost, rel_tol=1e-6)
assert math.isclose(completion_cost_val, expected_completion_cost, rel_tol=1e-6)
Expand Down Expand Up @@ -262,9 +261,9 @@ def test_high_volume_cost_calculation(self):

expected_prompt_cost = (50000 * 2e-6) + (5000 * 2e-6)
expected_completion_cost = (
((25000 - 10000) * 8e-6) + (10000 * 3e-6) + (100 / 1000 * 0.005)
)
expected_total = expected_prompt_cost + expected_completion_cost
((25000 - 10000) * 8e-6) + (10000 * 3e-6) + (100 * 0.005)
) # $0.65
expected_total = expected_prompt_cost + expected_completion_cost # $0.76

assert math.isclose(total_cost, expected_total, rel_tol=1e-6)
assert total_cost > 0.25
Expand Down Expand Up @@ -326,7 +325,7 @@ def test_case_insensitive_provider_matching(self, provider_name):

# Should calculate costs correctly
expected_prompt_cost = (100 * 2e-6) + (10 * 2e-6)
expected_completion_cost = (50 * 8e-6) + (1 / 1000 * 0.005)
expected_completion_cost = (50 * 8e-6) + (1 * 0.005)

assert math.isclose(prompt_cost, expected_prompt_cost, rel_tol=1e-6)
assert math.isclose(completion_cost_val, expected_completion_cost, rel_tol=1e-6)
Loading