fix(dashscope): keep the qwen-image-3.0 input-image fee out of the shared cost map row

Released proxies read the cost map from main and bill input_cost_per_image as the
flat price of each DashScope image, so the row's $0.003 input fee billed every
qwen-image-3.0 image there at a tenth of its $0.03 price. A deployment can still
set input_cost_per_image to bill DashScope's input images
This commit is contained in:
mateo-berri 2026-10-29 11:47:14 -07:00
parent 29634127b1
commit ff42ff4512
4 changed files with 25 additions and 25 deletions

View file

@ -18298,7 +18298,6 @@
]
},
"dashscope/qwen-image-3.0": {
"input_cost_per_image": 0.003,
"litellm_provider": "dashscope",
"mode": "image_generation",
"output_cost_per_image": 0.03,

View file

@ -18298,7 +18298,6 @@
]
},
"dashscope/qwen-image-3.0": {
"input_cost_per_image": 0.003,
"litellm_provider": "dashscope",
"mode": "image_generation",
"output_cost_per_image": 0.03,

View file

@ -288,14 +288,14 @@ def test_the_input_images_dashscope_reports_are_billed_on_top_of_the_edited_imag
model="dashscope/qwen-image-3.0", image=[PNG, PNG], prompt="p", api_key="k", client=_sync_client([], reply)
)
prices: Final = litellm.model_cost["dashscope/qwen-image-3.0"]
assert prices["input_cost_per_image"] > 0
assert litellm.completion_cost(
assert isinstance(response, litellm.ImageResponse)
assert CostCalculatorUtils.route_image_generation_cost_calculator(
model="qwen-image-3.0",
completion_response=response,
model="dashscope/qwen-image-3.0",
call_type="aimage_edit",
custom_llm_provider="dashscope",
) == pytest.approx(2 * prices["input_cost_per_image"] + prices["output_cost_per_image"])
call_type="aimage_edit",
model_info=ModelInfo(input_cost_per_image=0.004, output_cost_per_image=0.04),
) == pytest.approx(2 * 0.004 + 0.04)
def _edited_images(count: int, input_images: int) -> litellm.ImageResponse:
@ -327,22 +327,6 @@ def test_a_deployment_image_price_bills_the_edit_the_way_it_bills_any_image_call
assert cost == pytest.approx(expected_cost)
@pytest.mark.usefixtures("local_model_cost_map")
def test_a_deployment_output_image_price_keeps_billing_the_input_images_at_the_shared_price() -> None:
prices: Final = litellm.model_cost["dashscope/qwen-image-3.0"]
cost: Final = CostCalculatorUtils.route_image_generation_cost_calculator(
model="qwen-image-3.0",
completion_response=_edited_images(count=2, input_images=3),
custom_llm_provider="dashscope",
call_type="aimage_edit",
model_info=ModelInfo(output_cost_per_image=0.05),
)
assert prices["input_cost_per_image"] > 0
assert cost == pytest.approx(2 * 0.05 + 3 * prices["input_cost_per_image"])
@pytest.mark.usefixtures("local_model_cost_map")
def test_a_deployment_that_copies_both_image_prices_bills_edited_and_input_images_at_its_own_prices() -> None:
cost: Final = CostCalculatorUtils.route_image_generation_cost_calculator(
@ -368,4 +352,4 @@ def test_a_deployment_token_price_keeps_the_shared_per_image_billing() -> None:
model_info=ModelInfo(input_cost_per_token=1e-06),
)
assert cost == pytest.approx(2 * prices["input_cost_per_image"] + prices["output_cost_per_image"])
assert cost == pytest.approx(2 * prices.get("input_cost_per_image", 0.0) + prices["output_cost_per_image"])

View file

@ -5,6 +5,7 @@ qwen-image-3.0, qwen-image-3.0-pro).
Run in docker: pytest tests/unit/test_dashscope_image_generation.py -v
"""
from typing import Final
from unittest.mock import MagicMock, patch
import httpx
@ -12,6 +13,7 @@ import pytest
from pydantic import ValidationError
import litellm
from litellm.cost_calculator import default_image_cost_calculator
from litellm.llms.dashscope.image_generation.transformation import (
DashScopeImageGenerationConfig,
DEFAULT_API_BASE,
@ -593,3 +595,19 @@ def test_a_per_pixel_deployment_bills_the_size_dashscope_rendered_when_the_calle
)
assert cost == pytest.approx(2048 * 1536 * 1e-08)
@pytest.mark.parametrize("model", ("qwen-image-2.0", "qwen-image-2.0-pro", "qwen-image-3.0"))
@pytest.mark.usefixtures("local_model_cost_map")
def test_a_shared_row_bills_a_generated_image_the_same_on_the_default_calculator_released_proxies_use(model: str):
dashscope_cost: Final = CostCalculatorUtils.route_image_generation_cost_calculator(
model=model,
completion_response=ImageResponse(data=[{"url": "https://a.example/1.png"}]),
custom_llm_provider="dashscope",
call_type="image_generation",
)
assert dashscope_cost > 0
assert default_image_cost_calculator(model=f"dashscope/{model}", custom_llm_provider="dashscope") == pytest.approx(
dashscope_cost
)