mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-03 02:22:24 +00:00
refactor(azure_ai): bill FLUX.2 references at the megapixel rate instead of a separate key
Azure's reference meter costs the same per megapixel as each additional generated megapixel on both FLUX.2 models ($0.015 on Pro, $0.05 on Flex), so input_cost_per_reference_pixel only duplicated input_cost_per_pixel. References now bill at the price source's megapixel rate: the catalog rate, a deployment's own input_cost_per_pixel, or nothing on top of a flat output_cost_per_image. Billing is unchanged Drop the key from the cost map, its schema, CustomPricingLiteLLMParams, model info, the Rust catalog, the dashboard types and the Terraform provider, along with the Terraform zero-rate update it needed. If Azure ever prices the reference meter differently, the key can come back then
This commit is contained in:
parent
babf5bc3b4
commit
ba5b16226c
17 changed files with 67 additions and 253 deletions
|
|
@ -159,9 +159,6 @@ pub struct ModelInfo {
|
|||
pub input_cost_per_pixel: Option<f64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub input_cost_per_query: Option<f64>,
|
||||
/// USD per billable pixel of the reference images sent with an image edit (Azure AI FLUX.2 counts them in whole 1024x1024 megapixels).
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub input_cost_per_reference_pixel: Option<f64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub input_cost_per_request: Option<f64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@ _REFERENCE_PIXELS: Final = TypeAdapter(tuple[Annotated[int, Field(strict=True, g
|
|||
@dataclass(frozen=True, slots=True, kw_only=True)
|
||||
class _Flux2MegapixelPrices:
|
||||
first: float
|
||||
additional: float
|
||||
reference: float
|
||||
megapixel: float
|
||||
|
||||
|
||||
def _price(resolved: ModelInfo, cost_key: str) -> float | None:
|
||||
|
|
@ -52,30 +51,19 @@ def _deployment_price(deployment: ModelInfo | None, cost_key: str) -> float | No
|
|||
|
||||
|
||||
def _flux2_prices(resolved: ModelInfo, deployment: ModelInfo | None) -> _Flux2MegapixelPrices:
|
||||
# A deployment that prices the generated image itself also prices its references, unless it sets a reference
|
||||
# rate: a flat per-image price covers them, and a pixel rate bills them at that rate
|
||||
deployment_reference_rate: Final = _deployment_price(deployment, "input_cost_per_reference_pixel")
|
||||
deployment_image_price: Final = _deployment_price(deployment, "output_cost_per_image")
|
||||
if deployment_image_price is not None:
|
||||
return _Flux2MegapixelPrices(
|
||||
first=deployment_image_price,
|
||||
additional=0.0,
|
||||
reference=(deployment_reference_rate or 0.0) * MEGAPIXEL,
|
||||
)
|
||||
return _Flux2MegapixelPrices(first=deployment_image_price, megapixel=0.0)
|
||||
deployment_pixel_rate: Final = _deployment_price(deployment, "input_cost_per_pixel")
|
||||
if deployment_pixel_rate is not None:
|
||||
return _Flux2MegapixelPrices(
|
||||
first=deployment_pixel_rate * MEGAPIXEL,
|
||||
additional=deployment_pixel_rate * MEGAPIXEL,
|
||||
reference=(deployment_pixel_rate if deployment_reference_rate is None else deployment_reference_rate)
|
||||
* MEGAPIXEL,
|
||||
first=deployment_pixel_rate * MEGAPIXEL, megapixel=deployment_pixel_rate * MEGAPIXEL
|
||||
)
|
||||
catalog_megapixel_rate: Final = _pixel_rate(resolved, "input_cost_per_pixel") * MEGAPIXEL
|
||||
catalog_first_megapixel: Final = _price(resolved, "output_cost_per_image")
|
||||
return _Flux2MegapixelPrices(
|
||||
first=catalog_megapixel_rate if catalog_first_megapixel is None else catalog_first_megapixel,
|
||||
additional=catalog_megapixel_rate,
|
||||
reference=_pixel_rate(resolved, "input_cost_per_reference_pixel") * MEGAPIXEL,
|
||||
megapixel=catalog_megapixel_rate,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -84,8 +72,9 @@ def _billable_megapixels(pixels: int) -> int:
|
|||
|
||||
|
||||
def _billable_reference_megapixels(reference_pixels: tuple[int, ...]) -> int:
|
||||
# Azure's FLUX.2 request_meta (2026-09-25) bills a lone reference at no more than 4 MP, and each reference of a
|
||||
# multi-reference edit as exactly 1 MP whatever its size
|
||||
# Azure's FLUX.2 request_meta (2026-09-25) bills a lone reference at no more than 4 MP, each reference of a
|
||||
# multi-reference edit as exactly 1 MP whatever its size, and every reference megapixel at the rate of an
|
||||
# additional generated one
|
||||
match reference_pixels:
|
||||
case ():
|
||||
return 0
|
||||
|
|
@ -104,14 +93,14 @@ def _reference_cost(prices: _Flux2MegapixelPrices, image_response: ImageResponse
|
|||
except ValidationError:
|
||||
verbose_logger.warning("Ignoring malformed FLUX.2 reference pixel counts: %r", reported_pixels)
|
||||
return 0.0
|
||||
return prices.reference * _billable_reference_megapixels(reference_pixels)
|
||||
return prices.megapixel * _billable_reference_megapixels(reference_pixels)
|
||||
|
||||
|
||||
def _flux2_generated_cost(
|
||||
prices: _Flux2MegapixelPrices, image_response: ImageResponse, requested_pixels: int, n: int | None
|
||||
) -> float:
|
||||
return sum(
|
||||
prices.first + prices.additional * (_billable_megapixels(pixels) - 1)
|
||||
prices.first + prices.megapixel * (_billable_megapixels(pixels) - 1)
|
||||
for pixels in _generated_pixels(image_response, requested_pixels, n)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -11372,7 +11372,6 @@
|
|||
},
|
||||
"azure_ai/flux.2-pro": {
|
||||
"input_cost_per_pixel": 1.430511474609375e-08,
|
||||
"input_cost_per_reference_pixel": 1.430511474609375e-08,
|
||||
"litellm_provider": "azure_ai",
|
||||
"mode": "image_generation",
|
||||
"output_cost_per_image": 0.03,
|
||||
|
|
@ -11391,7 +11390,6 @@
|
|||
},
|
||||
"azure_ai/FLUX.2-flex": {
|
||||
"input_cost_per_pixel": 4.76837158203125e-08,
|
||||
"input_cost_per_reference_pixel": 4.76837158203125e-08,
|
||||
"litellm_provider": "azure_ai",
|
||||
"max_input_tokens": 32000,
|
||||
"max_tokens": 32000,
|
||||
|
|
|
|||
|
|
@ -789,7 +789,6 @@ class ModelGroupInfo(BaseModel):
|
|||
input_cost_per_token: float | None = None
|
||||
output_cost_per_token: float | None = None
|
||||
input_cost_per_pixel: float | None = None
|
||||
input_cost_per_reference_pixel: float | None = None
|
||||
mode: (
|
||||
str
|
||||
| Literal["chat", "embedding", "completion", "image_generation", "audio_transcription", "rerank", "moderations"]
|
||||
|
|
|
|||
|
|
@ -358,7 +358,6 @@ class ModelInfoBase(ProviderSpecificModelInfo, total=False):
|
|||
output_cost_per_character_above_128k_tokens: float | None # only for vertex ai models
|
||||
output_cost_per_image: float | None
|
||||
output_cost_per_pixel: ReadOnly[float | None]
|
||||
input_cost_per_reference_pixel: ReadOnly[float | None]
|
||||
output_cost_per_image_token: float | None
|
||||
output_cost_per_video_token: float | None # for gemini omni models with video output
|
||||
output_vector_size: int | None
|
||||
|
|
@ -3709,7 +3708,6 @@ class CustomPricingLiteLLMParams(MirroredPricingParams):
|
|||
output_cost_per_image_1024: float | None = None
|
||||
output_cost_per_image_1536: float | None = None
|
||||
input_cost_per_pixel: float | None = None
|
||||
input_cost_per_reference_pixel: float | None = None
|
||||
output_cost_per_pixel: float | None = None
|
||||
|
||||
# Include all ModelInfoBase fields as optional
|
||||
|
|
|
|||
|
|
@ -6265,7 +6265,6 @@ def _get_model_info_helper(
|
|||
output_cost_per_video_per_second=_model_info.get("output_cost_per_video_per_second", None),
|
||||
output_cost_per_image=_model_info.get("output_cost_per_image", None),
|
||||
output_cost_per_pixel=_model_info.get("output_cost_per_pixel", None),
|
||||
input_cost_per_reference_pixel=_model_info.get("input_cost_per_reference_pixel", None),
|
||||
output_cost_per_image_token=_model_info.get("output_cost_per_image_token", None),
|
||||
output_cost_per_video_token=_model_info.get("output_cost_per_video_token", None),
|
||||
output_vector_size=_model_info.get("output_vector_size", None),
|
||||
|
|
|
|||
|
|
@ -11372,7 +11372,6 @@
|
|||
},
|
||||
"azure_ai/flux.2-pro": {
|
||||
"input_cost_per_pixel": 1.430511474609375e-08,
|
||||
"input_cost_per_reference_pixel": 1.430511474609375e-08,
|
||||
"litellm_provider": "azure_ai",
|
||||
"mode": "image_generation",
|
||||
"output_cost_per_image": 0.03,
|
||||
|
|
@ -11391,7 +11390,6 @@
|
|||
},
|
||||
"azure_ai/FLUX.2-flex": {
|
||||
"input_cost_per_pixel": 4.76837158203125e-08,
|
||||
"input_cost_per_reference_pixel": 4.76837158203125e-08,
|
||||
"litellm_provider": "azure_ai",
|
||||
"max_input_tokens": 32000,
|
||||
"max_tokens": 32000,
|
||||
|
|
|
|||
|
|
@ -333,10 +333,6 @@
|
|||
"type": "number",
|
||||
"minimum": 0
|
||||
},
|
||||
"input_cost_per_reference_pixel": {
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
},
|
||||
"input_cost_per_request": {
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
|
|
|
|||
|
|
@ -159,8 +159,6 @@ The following arguments are supported:
|
|||
|
||||
* `input_cost_per_pixel` - (Optional) float. Cost applied per input pixel for models that charge by image size.
|
||||
|
||||
* `input_cost_per_reference_pixel` - (Optional) float. Cost applied per reference image pixel for image-edit models.
|
||||
|
||||
* `output_cost_per_pixel` - (Optional) float. Cost applied per output pixel for image-generation models.
|
||||
|
||||
* `input_cost_per_second` - (Optional) float. Cost applied per input second for audio/transcription models.
|
||||
|
|
|
|||
|
|
@ -124,10 +124,6 @@ func resourceLiteLLMModel() *schema.Resource {
|
|||
Type: schema.TypeFloat,
|
||||
Optional: true,
|
||||
},
|
||||
"input_cost_per_reference_pixel": {
|
||||
Type: schema.TypeFloat,
|
||||
Optional: true,
|
||||
},
|
||||
"output_cost_per_pixel": {
|
||||
Type: schema.TypeFloat,
|
||||
Optional: true,
|
||||
|
|
|
|||
|
|
@ -126,10 +126,6 @@ func createOrUpdateModel(d *schema.ResourceData, m interface{}, isUpdate bool) e
|
|||
if inputCostPerPixel := d.Get("input_cost_per_pixel").(float64); inputCostPerPixel > 0 {
|
||||
litellmParams["input_cost_per_pixel"] = inputCostPerPixel
|
||||
}
|
||||
inputCostPerReferencePixel := d.Get("input_cost_per_reference_pixel").(float64)
|
||||
if inputCostPerReferencePixel > 0 || (isUpdate && d.HasChange("input_cost_per_reference_pixel")) {
|
||||
litellmParams["input_cost_per_reference_pixel"] = inputCostPerReferencePixel
|
||||
}
|
||||
if outputCostPerPixel := d.Get("output_cost_per_pixel").(float64); outputCostPerPixel > 0 {
|
||||
litellmParams["output_cost_per_pixel"] = outputCostPerPixel
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,71 +242,3 @@ func TestResourceLiteLLMModelUpdateSkipsPatchWhenDisplayNameUnchanged(t *testing
|
|||
t.Fatalf("update failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourceLiteLLMModelUpdateSendsReferencePixelRate(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
oldRate, newRate string
|
||||
wantSent bool
|
||||
wantRate float64
|
||||
}{
|
||||
"rate cleared to zero is sent": {oldRate: "2e-07", newRate: "0", wantSent: true, wantRate: 0},
|
||||
"unchanged rate is sent": {oldRate: "2e-07", newRate: "2e-07", wantSent: true, wantRate: 2e-07},
|
||||
"never set rate is omitted": {oldRate: "", newRate: "0", wantSent: false},
|
||||
}
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
var updateParams map[string]interface{}
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodPost && r.URL.Path == "/model/update" {
|
||||
var payload map[string]interface{}
|
||||
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
||||
t.Errorf("failed to decode update payload: %v", err)
|
||||
}
|
||||
updateParams = payload["litellm_params"].(map[string]interface{})
|
||||
w.Write([]byte(modelInfoBody("")))
|
||||
return
|
||||
}
|
||||
w.Write([]byte(modelInfoDataEnvelope("")))
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
res := resourceLiteLLMModel()
|
||||
attrs := map[string]string{
|
||||
"model_name": "sonnet-4-5-anthropic",
|
||||
"custom_llm_provider": "anthropic",
|
||||
"base_model": "claude-sonnet-4-5",
|
||||
}
|
||||
if tc.oldRate != "" {
|
||||
attrs["input_cost_per_reference_pixel"] = tc.oldRate
|
||||
}
|
||||
state := &terraform.InstanceState{ID: "model-123", Attributes: attrs}
|
||||
config := map[string]interface{}{
|
||||
"model_name": "sonnet-4-5-anthropic",
|
||||
"custom_llm_provider": "anthropic",
|
||||
"base_model": "claude-sonnet-4-5",
|
||||
}
|
||||
if tc.newRate != "0" {
|
||||
config["input_cost_per_reference_pixel"] = tc.newRate
|
||||
}
|
||||
diff, err := res.Diff(context.Background(), state, &terraform.ResourceConfig{Config: config}, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("diff failed: %v", err)
|
||||
}
|
||||
d, err := schema.InternalMap(res.Schema).Data(state, diff)
|
||||
if err != nil {
|
||||
t.Fatalf("data failed: %v", err)
|
||||
}
|
||||
|
||||
if err := resourceLiteLLMModelUpdate(d, NewClient(srv.URL, "test-key", true)); err != nil {
|
||||
t.Fatalf("update failed: %v", err)
|
||||
}
|
||||
rate, sent := updateParams["input_cost_per_reference_pixel"]
|
||||
if sent != tc.wantSent {
|
||||
t.Fatalf("expected input_cost_per_reference_pixel sent=%v, got %v (%v)", tc.wantSent, sent, rate)
|
||||
}
|
||||
if sent && rate != tc.wantRate {
|
||||
t.Errorf("expected input_cost_per_reference_pixel %v, got %v", tc.wantRate, rate)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,6 @@ type LiteLLMParams struct {
|
|||
InputCostPerToken float64 `json:"input_cost_per_token,omitempty"`
|
||||
OutputCostPerToken float64 `json:"output_cost_per_token,omitempty"`
|
||||
InputCostPerPixel float64 `json:"input_cost_per_pixel,omitempty"`
|
||||
InputCostPerReferencePixel float64 `json:"input_cost_per_reference_pixel,omitempty"`
|
||||
OutputCostPerPixel float64 `json:"output_cost_per_pixel,omitempty"`
|
||||
InputCostPerSecond float64 `json:"input_cost_per_second,omitempty"`
|
||||
OutputCostPerSecond float64 `json:"output_cost_per_second,omitempty"`
|
||||
|
|
|
|||
|
|
@ -184,11 +184,9 @@ def test_flux2_image_edit_preserves_controls_and_pixel_cost(dimensions: Mapping[
|
|||
steps="32",
|
||||
**dimensions,
|
||||
)
|
||||
generated_rate, reference_rate = _flex_rates()
|
||||
rate: Final = _flex_megapixel_rate()
|
||||
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(
|
||||
generated_rate * 2048 * 1024 * 2 + reference_rate * 1024 * 1024
|
||||
)
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(rate * 2048 * 1024 * 2 + rate * 1024 * 1024)
|
||||
|
||||
|
||||
def test_flux2_image_edit_accepts_and_drops_openai_only_parameters():
|
||||
|
|
@ -225,9 +223,8 @@ def _webp(width: int, height: int) -> bytes:
|
|||
)
|
||||
|
||||
|
||||
def _flex_rates() -> tuple[float, float]:
|
||||
row: Final = litellm.model_cost["azure_ai/FLUX.2-flex"]
|
||||
return row["input_cost_per_pixel"], row["input_cost_per_reference_pixel"]
|
||||
def _flex_megapixel_rate() -> float:
|
||||
return litellm.model_cost["azure_ai/FLUX.2-flex"]["input_cost_per_pixel"]
|
||||
|
||||
|
||||
def _edit_ok(request: httpx.Request) -> httpx.Response:
|
||||
|
|
@ -251,14 +248,12 @@ def test_flux2_image_edit_measures_every_reference_but_bills_each_of_several_as_
|
|||
client=HTTPHandler(client=httpx.Client(transport=httpx.MockTransport(respond))),
|
||||
size="1024x1024",
|
||||
)
|
||||
generated_rate, reference_rate = _flex_rates()
|
||||
rate: Final = _flex_megapixel_rate()
|
||||
|
||||
assert sent["input_image"] == base64.b64encode(references[0]).decode()
|
||||
assert sent["input_image_3"] == base64.b64encode(references[2]).decode()
|
||||
assert response._hidden_params["reference_image_pixels"] == (1024 * 1024, 800 * 600, 640 * 480)
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(
|
||||
generated_rate * 1024 * 1024 + reference_rate * 3 * 1024 * 1024
|
||||
)
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(rate * 1024 * 1024 + rate * 3 * 1024 * 1024)
|
||||
|
||||
|
||||
class _ReadOnlyUpload:
|
||||
|
|
@ -353,12 +348,10 @@ def test_flux2_image_edit_sends_and_bills_every_readable_upload(
|
|||
client=HTTPHandler(client=httpx.Client(transport=httpx.MockTransport(respond))),
|
||||
size="1024x1024",
|
||||
)
|
||||
generated_rate, reference_rate = _flex_rates()
|
||||
rate: Final = _flex_megapixel_rate()
|
||||
|
||||
assert sent_images == [base64.b64encode(reference).decode()]
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(
|
||||
generated_rate * 1024 * 1024 + reference_rate * 2 * 1024 * 1024
|
||||
)
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(rate * 1024 * 1024 + rate * 2 * 1024 * 1024)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("upload_kind", ("bytesio", "buffered-reader", "named-temporary-file-at-eof"))
|
||||
|
|
@ -420,12 +413,10 @@ def test_flux2_image_edit_measures_a_stream_reference():
|
|||
client=HTTPHandler(client=httpx.Client(transport=httpx.MockTransport(_edit_ok))),
|
||||
size="1024x1024",
|
||||
)
|
||||
generated_rate, reference_rate = _flex_rates()
|
||||
rate: Final = _flex_megapixel_rate()
|
||||
|
||||
assert response._hidden_params["reference_image_pixels"] == (2048 * 2048,)
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(
|
||||
generated_rate * 1024 * 1024 + reference_rate * 2048 * 2048
|
||||
)
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(rate * 1024 * 1024 + rate * 2048 * 2048)
|
||||
|
||||
|
||||
# Billable megapixels for a lone reference as Azure's FLUX.2-pro request_meta reported them on 2026-09-25
|
||||
|
|
@ -447,10 +438,10 @@ def test_flux2_image_edit_bills_a_lone_reference_in_whole_megapixels(reference:
|
|||
client=HTTPHandler(client=httpx.Client(transport=httpx.MockTransport(_edit_ok))),
|
||||
size="1024x1024",
|
||||
)
|
||||
generated_rate, reference_rate = _flex_rates()
|
||||
rate: Final = _flex_megapixel_rate()
|
||||
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(
|
||||
generated_rate * 1024 * 1024 + reference_rate * billed_megapixels * 1024 * 1024
|
||||
rate * 1024 * 1024 + rate * billed_megapixels * 1024 * 1024
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -472,12 +463,10 @@ def test_flux2_image_edit_bills_a_lone_unmeasurable_reference_as_one_megapixel(r
|
|||
client=HTTPHandler(client=httpx.Client(transport=httpx.MockTransport(_edit_ok))),
|
||||
size="1024x1024",
|
||||
)
|
||||
generated_rate, reference_rate = _flex_rates()
|
||||
rate: Final = _flex_megapixel_rate()
|
||||
|
||||
assert response._hidden_params["reference_image_pixels"] == (UNMEASURED_REFERENCE_IMAGE_PIXELS,)
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(
|
||||
generated_rate * 1024 * 1024 + reference_rate * 1024 * 1024
|
||||
)
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(rate * 1024 * 1024 + rate * 1024 * 1024)
|
||||
|
||||
|
||||
def test_flux2_image_edit_still_bills_every_reference_when_one_header_reports_zero_pixels():
|
||||
|
|
@ -490,11 +479,9 @@ def test_flux2_image_edit_still_bills_every_reference_when_one_header_reports_ze
|
|||
client=HTTPHandler(client=httpx.Client(transport=httpx.MockTransport(_edit_ok))),
|
||||
size="1024x1024",
|
||||
)
|
||||
generated_rate, reference_rate = _flex_rates()
|
||||
rate: Final = _flex_megapixel_rate()
|
||||
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(
|
||||
generated_rate * 1024 * 1024 + reference_rate * 2 * 1024 * 1024
|
||||
)
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(rate * 1024 * 1024 + rate * 2 * 1024 * 1024)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("stream_position", ("start", "end"))
|
||||
|
|
@ -526,7 +513,7 @@ def test_flux2_image_edit_resends_and_rebills_a_reused_stream(stream_position: s
|
|||
assert [response._hidden_params["reference_image_pixels"] for response in responses] == [(2048 * 1024,)] * 2
|
||||
|
||||
|
||||
def test_flux2_pro_image_edit_bills_references_on_the_pro_reference_rate():
|
||||
def test_flux2_pro_image_edit_bills_references_at_the_pro_megapixel_rate():
|
||||
pro_row: Final = litellm.model_cost["azure_ai/flux.2-pro"]
|
||||
response: Final = litellm.image_edit(
|
||||
model="azure_ai/flux.2-pro",
|
||||
|
|
@ -538,9 +525,9 @@ def test_flux2_pro_image_edit_bills_references_on_the_pro_reference_rate():
|
|||
size="1024x1024",
|
||||
)
|
||||
|
||||
assert pro_row["input_cost_per_reference_pixel"] > 0
|
||||
assert pro_row["input_cost_per_pixel"] > 0
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(
|
||||
pro_row["output_cost_per_image"] + pro_row["input_cost_per_reference_pixel"] * 2 * 1024 * 1024
|
||||
pro_row["output_cost_per_image"] + pro_row["input_cost_per_pixel"] * 2 * 1024 * 1024
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -548,8 +535,7 @@ async def test_flux2_router_image_edit_bills_the_deployment_rates(monkeypatch: p
|
|||
mock_client: Final = AsyncHTTPHandler()
|
||||
mock_client.client = httpx.AsyncClient(transport=httpx.MockTransport(_edit_ok))
|
||||
monkeypatch.setattr(llm_http_handler_module, "get_async_httpx_client", lambda **_kwargs: mock_client)
|
||||
generated_rate: Final = 1e-07
|
||||
reference_rate: Final = 2e-07
|
||||
megapixel_rate: Final = 1e-07
|
||||
router: Final = litellm.Router(
|
||||
model_list=[
|
||||
{
|
||||
|
|
@ -558,8 +544,7 @@ async def test_flux2_router_image_edit_bills_the_deployment_rates(monkeypatch: p
|
|||
"model": "azure_ai/FLUX.2-flex",
|
||||
"api_base": "https://example.services.ai.azure.com",
|
||||
"api_key": "test-key",
|
||||
"input_cost_per_pixel": generated_rate,
|
||||
"input_cost_per_reference_pixel": reference_rate,
|
||||
"input_cost_per_pixel": megapixel_rate,
|
||||
},
|
||||
}
|
||||
]
|
||||
|
|
@ -573,7 +558,7 @@ async def test_flux2_router_image_edit_bills_the_deployment_rates(monkeypatch: p
|
|||
)
|
||||
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(
|
||||
generated_rate * 2 * 1024 * 1024 + reference_rate * 2 * 1024 * 1024
|
||||
megapixel_rate * 2 * 1024 * 1024 + megapixel_rate * 2 * 1024 * 1024
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -582,8 +567,8 @@ async def test_flux2_router_image_edit_bills_the_deployment_rates(monkeypatch: p
|
|||
(
|
||||
({"output_cost_per_image": 0.5}, 0.5),
|
||||
(
|
||||
{"input_cost_per_pixel": 1e-07, "input_cost_per_reference_pixel": 2e-07},
|
||||
1e-07 * 2 * 1024 * 1024 + 2e-07 * 2 * 1024 * 1024,
|
||||
{"input_cost_per_pixel": 1e-07},
|
||||
1e-07 * 2 * 1024 * 1024 + 1e-07 * 2 * 1024 * 1024,
|
||||
),
|
||||
),
|
||||
ids=("flat", "per-pixel"),
|
||||
|
|
@ -663,7 +648,7 @@ def test_flux2_image_edit_bills_the_generated_image_azure_returned(size: str | N
|
|||
assert response._hidden_params["response_cost"] == pytest.approx(
|
||||
pro_row["output_cost_per_image"]
|
||||
+ pro_row["input_cost_per_pixel"] * 1024 * 1024
|
||||
+ pro_row["input_cost_per_reference_pixel"] * 2 * 1024 * 1024
|
||||
+ pro_row["input_cost_per_pixel"] * 2 * 1024 * 1024
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -679,9 +664,7 @@ async def test_flux2_aimage_edit_bills_references_like_image_edit():
|
|||
client=client,
|
||||
size="1024x1024",
|
||||
)
|
||||
generated_rate, reference_rate = _flex_rates()
|
||||
rate: Final = _flex_megapixel_rate()
|
||||
|
||||
assert response._hidden_params["reference_image_pixels"] == (1024 * 1024, 1024 * 1024)
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(
|
||||
generated_rate * 1024 * 1024 + reference_rate * 2 * 1024 * 1024
|
||||
)
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(rate * 1024 * 1024 + rate * 2 * 1024 * 1024)
|
||||
|
|
|
|||
|
|
@ -35,10 +35,6 @@ def _flex_pixel_rate() -> float:
|
|||
return litellm.model_cost["azure_ai/FLUX.2-flex"]["input_cost_per_pixel"]
|
||||
|
||||
|
||||
def _flex_reference_rate() -> float:
|
||||
return litellm.model_cost["azure_ai/FLUX.2-flex"]["input_cost_per_reference_pixel"]
|
||||
|
||||
|
||||
def _flex_edit_cost(response: ImageResponse, model_info: dict | None = None) -> float:
|
||||
return CostCalculatorUtils.route_image_generation_cost_calculator(
|
||||
model="FLUX.2-flex",
|
||||
|
|
@ -58,13 +54,9 @@ def _edit_response(reference_image_pixels: object) -> ImageResponse:
|
|||
)
|
||||
|
||||
|
||||
def _pro_megapixel_rates() -> tuple[float, float, float]:
|
||||
def _pro_megapixel_rates() -> tuple[float, float]:
|
||||
row: Final = litellm.model_cost["azure_ai/flux.2-pro"]
|
||||
return (
|
||||
row["output_cost_per_image"],
|
||||
row["input_cost_per_pixel"] * 1024 * 1024,
|
||||
row["input_cost_per_reference_pixel"] * 1024 * 1024,
|
||||
)
|
||||
return row["output_cost_per_image"], row["input_cost_per_pixel"] * 1024 * 1024
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
@ -171,13 +163,9 @@ def test_flux2_flex_model_info():
|
|||
|
||||
|
||||
@pytest.mark.parametrize("model", ("flux.2-pro", "FLUX.2-flex"))
|
||||
def test_flux2_model_info_reports_the_reference_rate_and_the_edit_endpoint(model: str):
|
||||
def test_flux2_model_info_lists_the_edit_endpoint(model: str):
|
||||
model_info: Final = litellm.get_model_info(model=model, custom_llm_provider="azure_ai")
|
||||
|
||||
assert (
|
||||
model_info["input_cost_per_reference_pixel"]
|
||||
== litellm.model_cost[f"azure_ai/{model}"]["input_cost_per_reference_pixel"]
|
||||
)
|
||||
assert "/v1/images/edits" in model_info["supported_endpoints"]
|
||||
|
||||
|
||||
|
|
@ -269,7 +257,7 @@ def test_flux2_flex_generation_rounds_each_image_up_to_whole_megapixels():
|
|||
|
||||
@pytest.mark.parametrize(("size", "megapixels"), (("256x256", 1), ("1024x1280", 2), ("2048x2048", 4)))
|
||||
def test_flux2_pro_generation_bills_the_first_megapixel_then_each_additional_one(size: str, megapixels: int):
|
||||
first, additional, _reference = _pro_megapixel_rates()
|
||||
first, additional = _pro_megapixel_rates()
|
||||
|
||||
cost: Final = CostCalculatorUtils.route_image_generation_cost_calculator(
|
||||
model="flux.2-pro",
|
||||
|
|
@ -305,9 +293,6 @@ def _catalog_image_cost(model: str, megapixels: int) -> float:
|
|||
lambda megapixels: 1e-07 * 1024 * 1024 * megapixels,
|
||||
id="deployment-pixel-rate-prices-every-megapixel",
|
||||
),
|
||||
pytest.param(
|
||||
{"input_cost_per_reference_pixel": 3e-07}, None, id="deployment-reference-rate-keeps-catalog-output"
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_flux2_generation_bills_each_price_source_as_its_owner_set_it(
|
||||
|
|
@ -333,24 +318,16 @@ def test_flux2_generation_bills_each_price_source_as_its_owner_set_it(
|
|||
@pytest.mark.parametrize(
|
||||
("deployment_prices", "reference_megapixel_price"),
|
||||
(
|
||||
pytest.param(None, None, id="catalog-reference-rate"),
|
||||
pytest.param(None, None, id="catalog-megapixel-rate"),
|
||||
pytest.param({"output_cost_per_image": 0.07}, 0.0, id="deployment-flat-price-covers-references"),
|
||||
pytest.param(
|
||||
{"output_cost_per_image": 0.07, "input_cost_per_reference_pixel": 3e-07},
|
||||
3e-07 * 1024 * 1024,
|
||||
id="deployment-flat-price-with-its-reference-rate",
|
||||
{"output_cost_per_image": 0.07, "input_cost_per_pixel": 1e-07},
|
||||
0.0,
|
||||
id="deployment-flat-price-covers-references-despite-its-pixel-rate",
|
||||
),
|
||||
pytest.param(
|
||||
{"input_cost_per_pixel": 1e-07}, 1e-07 * 1024 * 1024, id="deployment-pixel-rate-prices-references"
|
||||
),
|
||||
pytest.param(
|
||||
{"input_cost_per_pixel": 1e-07, "input_cost_per_reference_pixel": 3e-07},
|
||||
3e-07 * 1024 * 1024,
|
||||
id="deployment-reference-rate-wins-over-its-pixel-rate",
|
||||
),
|
||||
pytest.param(
|
||||
{"input_cost_per_reference_pixel": 3e-07}, 3e-07 * 1024 * 1024, id="deployment-reference-rate-alone"
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_flux2_edit_prices_references_from_the_source_that_priced_the_image(
|
||||
|
|
@ -367,7 +344,7 @@ def test_flux2_edit_prices_references_from_the_source_that_priced_the_image(
|
|||
)
|
||||
|
||||
expected_per_megapixel: Final = (
|
||||
litellm.model_cost[f"azure_ai/{model}"]["input_cost_per_reference_pixel"] * 1024 * 1024
|
||||
litellm.model_cost[f"azure_ai/{model}"]["input_cost_per_pixel"] * 1024 * 1024
|
||||
if reference_megapixel_price is None
|
||||
else reference_megapixel_price
|
||||
)
|
||||
|
|
@ -397,7 +374,7 @@ def _png_b64(width: int, height: int) -> str:
|
|||
def test_flux2_pro_bills_each_generated_image_by_its_returned_size(
|
||||
returned_images: tuple[tuple[int, int] | None, ...], requested_size: str, expected_megapixels: tuple[int, ...]
|
||||
):
|
||||
first, additional, _reference = _pro_megapixel_rates()
|
||||
first, additional = _pro_megapixel_rates()
|
||||
response: Final = ImageResponse(
|
||||
data=[ImageObject(b64_json="aW1n" if image is None else _png_b64(*image)) for image in returned_images]
|
||||
)
|
||||
|
|
@ -415,7 +392,7 @@ def test_flux2_pro_bills_each_generated_image_by_its_returned_size(
|
|||
|
||||
@pytest.mark.parametrize("size", ("auto", "large", "0x1024", "1024x"))
|
||||
def test_flux2_pro_bills_one_megapixel_for_a_size_it_cannot_measure(size: str):
|
||||
first, _additional, _reference = _pro_megapixel_rates()
|
||||
first, _additional = _pro_megapixel_rates()
|
||||
|
||||
cost: Final = CostCalculatorUtils.route_image_generation_cost_calculator(
|
||||
model="flux.2-pro",
|
||||
|
|
@ -429,7 +406,7 @@ def test_flux2_pro_bills_one_megapixel_for_a_size_it_cannot_measure(size: str):
|
|||
|
||||
|
||||
def test_flux2_pro_bills_the_requested_size_when_the_returned_image_is_not_valid_base64():
|
||||
first, additional, _reference = _pro_megapixel_rates()
|
||||
first, additional = _pro_megapixel_rates()
|
||||
|
||||
cost: Final = CostCalculatorUtils.route_image_generation_cost_calculator(
|
||||
model="flux.2-pro",
|
||||
|
|
@ -444,7 +421,7 @@ def test_flux2_pro_bills_the_requested_size_when_the_returned_image_is_not_valid
|
|||
|
||||
@pytest.mark.parametrize(("n", "billed_images"), ((2, 2), (None, 0)))
|
||||
def test_flux2_pro_bills_the_requested_image_count_when_the_response_lists_none(n: int | None, billed_images: int):
|
||||
first, _additional, _reference = _pro_megapixel_rates()
|
||||
first, _additional = _pro_megapixel_rates()
|
||||
|
||||
cost: Final = CostCalculatorUtils.route_image_generation_cost_calculator(
|
||||
model="flux.2-pro",
|
||||
|
|
@ -459,7 +436,7 @@ def test_flux2_pro_bills_the_requested_image_count_when_the_response_lists_none(
|
|||
|
||||
|
||||
def test_flux2_pro_reads_an_uppercase_size():
|
||||
first, additional, _reference = _pro_megapixel_rates()
|
||||
first, additional = _pro_megapixel_rates()
|
||||
|
||||
cost: Final = CostCalculatorUtils.route_image_generation_cost_calculator(
|
||||
model="flux.2-pro",
|
||||
|
|
@ -475,22 +452,20 @@ def test_flux2_pro_reads_an_uppercase_size():
|
|||
def test_flux2_edit_parses_string_prices_registered_in_the_cost_map(monkeypatch: pytest.MonkeyPatch):
|
||||
row: Final = litellm.model_cost["azure_ai/FLUX.2-flex"]
|
||||
monkeypatch.setitem(row, "input_cost_per_pixel", "2e-07")
|
||||
monkeypatch.setitem(row, "input_cost_per_reference_pixel", "3e-07")
|
||||
litellm.get_model_info.cache_clear()
|
||||
_invalidate_model_cost_lowercase_map()
|
||||
|
||||
assert _flex_edit_cost(_edit_response((1024 * 1024,))) == pytest.approx(2e-07 * 1024 * 1024 + 3e-07 * 1024 * 1024)
|
||||
assert _flex_edit_cost(_edit_response((1024 * 1024,))) == pytest.approx(2e-07 * 1024 * 1024 * 2)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def distinct_pro_megapixel_prices(monkeypatch: pytest.MonkeyPatch) -> tuple[float, float, float]:
|
||||
def distinct_pro_megapixel_prices(monkeypatch: pytest.MonkeyPatch) -> tuple[float, float]:
|
||||
row: Final = litellm.model_cost["azure_ai/flux.2-pro"]
|
||||
monkeypatch.setitem(row, "output_cost_per_image", 0.05)
|
||||
monkeypatch.setitem(row, "input_cost_per_pixel", 2e-08)
|
||||
monkeypatch.setitem(row, "input_cost_per_reference_pixel", 3e-08)
|
||||
litellm.get_model_info.cache_clear()
|
||||
_invalidate_model_cost_lowercase_map()
|
||||
return 0.05, 2e-08 * 1024 * 1024, 3e-08 * 1024 * 1024
|
||||
return 0.05, 2e-08 * 1024 * 1024
|
||||
|
||||
|
||||
# Billable megapixels as Azure's request_meta reported them for FLUX.2-pro edits on 2026-09-25
|
||||
|
|
@ -511,9 +486,9 @@ def test_flux2_pro_edit_bills_the_megapixels_azure_meters(
|
|||
reference_pixels: tuple[int, ...],
|
||||
output_megapixels: int,
|
||||
reference_megapixels: int,
|
||||
distinct_pro_megapixel_prices: tuple[float, float, float],
|
||||
distinct_pro_megapixel_prices: tuple[float, float],
|
||||
):
|
||||
first, additional, reference = distinct_pro_megapixel_prices
|
||||
first, megapixel = distinct_pro_megapixel_prices
|
||||
|
||||
cost: Final = CostCalculatorUtils.route_image_generation_cost_calculator(
|
||||
model="flux.2-pro",
|
||||
|
|
@ -523,7 +498,7 @@ def test_flux2_pro_edit_bills_the_megapixels_azure_meters(
|
|||
call_type="image_edit",
|
||||
)
|
||||
|
||||
assert cost == pytest.approx(first + additional * (output_megapixels - 1) + reference * reference_megapixels)
|
||||
assert cost == pytest.approx(first + megapixel * (output_megapixels - 1 + reference_megapixels))
|
||||
|
||||
|
||||
def test_flux2_flex_edit_bills_reference_pixels_on_top_of_generated_pixels():
|
||||
|
|
@ -531,10 +506,10 @@ def test_flux2_flex_edit_bills_reference_pixels_on_top_of_generated_pixels():
|
|||
|
||||
assert generated_only == pytest.approx(_flex_pixel_rate() * 1024 * 1024)
|
||||
assert _flex_edit_cost(_edit_response((1024 * 1024,))) - generated_only == pytest.approx(
|
||||
_flex_reference_rate() * 1024 * 1024
|
||||
_flex_pixel_rate() * 1024 * 1024
|
||||
)
|
||||
assert _flex_edit_cost(_edit_response((3 * 1024 * 1024,))) - generated_only == pytest.approx(
|
||||
_flex_reference_rate() * 3 * 1024 * 1024
|
||||
_flex_pixel_rate() * 3 * 1024 * 1024
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -546,7 +521,7 @@ def test_flux2_flex_edit_reference_cost_does_not_scale_with_image_count():
|
|||
)
|
||||
|
||||
assert _flex_edit_cost(two_outputs) == pytest.approx(
|
||||
_flex_pixel_rate() * 1024 * 1024 * 2 + _flex_reference_rate() * 2048 * 1024
|
||||
_flex_pixel_rate() * 1024 * 1024 * 2 + _flex_pixel_rate() * 2048 * 1024
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -582,16 +557,6 @@ def test_flux2_flex_edit_ignores_reference_pixels_when_provider_reports_token_us
|
|||
assert _flex_edit_cost(response, model_info=token_rates) == pytest.approx(50 * 1e-05 + 100 * 2e-05 + 1000 * 4e-05)
|
||||
|
||||
|
||||
def test_flux2_flex_edit_reads_the_reference_rate_from_its_own_catalog_key(monkeypatch: pytest.MonkeyPatch):
|
||||
monkeypatch.setitem(litellm.model_cost["azure_ai/FLUX.2-flex"], "input_cost_per_reference_pixel", 3e-07)
|
||||
litellm.get_model_info.cache_clear()
|
||||
_invalidate_model_cost_lowercase_map()
|
||||
|
||||
assert _flex_edit_cost(_edit_response((1024 * 1024,))) == pytest.approx(
|
||||
_flex_pixel_rate() * 1024 * 1024 + 3e-07 * 1024 * 1024
|
||||
)
|
||||
|
||||
|
||||
def test_flux2_flex_edit_prices_output_from_the_request_size_not_the_reference():
|
||||
large_reference_small_output: Final = ImageResponse(
|
||||
data=[ImageObject(b64_json="aW1n")],
|
||||
|
|
@ -600,7 +565,7 @@ def test_flux2_flex_edit_prices_output_from_the_request_size_not_the_reference()
|
|||
)
|
||||
|
||||
assert _flex_edit_cost(large_reference_small_output) == pytest.approx(
|
||||
_flex_pixel_rate() * 1024 * 1024 + _flex_reference_rate() * 2048 * 2048
|
||||
_flex_pixel_rate() * 1024 * 1024 + _flex_pixel_rate() * 2048 * 2048
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -610,51 +575,30 @@ def test_flux2_flex_edit_with_a_free_deployment_pixel_rate_bills_nothing():
|
|||
assert cost == 0.0
|
||||
|
||||
|
||||
def test_flux2_flex_edit_prefers_deployment_reference_rate():
|
||||
cost: Final = _flex_edit_cost(
|
||||
_edit_response((1024 * 1024,)),
|
||||
model_info={"input_cost_per_pixel": 2e-07, "input_cost_per_reference_pixel": 3e-07},
|
||||
)
|
||||
|
||||
assert cost == pytest.approx(2e-07 * 1024 * 1024 + 3e-07 * 1024 * 1024)
|
||||
|
||||
|
||||
def test_flux2_flex_edit_deployment_reference_rate_alone_keeps_catalog_generated_rate():
|
||||
cost: Final = _flex_edit_cost(_edit_response((1024 * 1024,)), model_info={"input_cost_per_reference_pixel": 3e-07})
|
||||
|
||||
assert cost == pytest.approx(_flex_pixel_rate() * 1024 * 1024 + 3e-07 * 1024 * 1024)
|
||||
|
||||
|
||||
def test_flux2_flex_edit_honors_explicit_zero_deployment_reference_rate():
|
||||
cost: Final = _flex_edit_cost(_edit_response((1024 * 1024,)), model_info={"input_cost_per_reference_pixel": 0.0})
|
||||
|
||||
assert cost == pytest.approx(_flex_pixel_rate() * 1024 * 1024)
|
||||
|
||||
|
||||
def test_custom_named_flux2_deployment_bills_its_own_megapixel_and_reference_rates() -> None:
|
||||
def test_custom_named_flux2_deployment_bills_its_own_megapixel_rate_for_output_and_references() -> None:
|
||||
cost: Final = CostCalculatorUtils.route_image_generation_cost_calculator(
|
||||
model="my-flux2-prod",
|
||||
completion_response=_edit_response((1024 * 1280,)),
|
||||
custom_llm_provider="azure_ai",
|
||||
size="1024x1280",
|
||||
call_type="image_edit",
|
||||
model_info={"input_cost_per_pixel": 1e-07, "input_cost_per_reference_pixel": 2e-07},
|
||||
model_info={"input_cost_per_pixel": 1e-07},
|
||||
)
|
||||
|
||||
assert cost == pytest.approx(1e-07 * 1024 * 1024 * 2 + 2e-07 * 1024 * 1024 * 2)
|
||||
assert cost == pytest.approx(1e-07 * 1024 * 1024 * 2 + 1e-07 * 1024 * 1024 * 2)
|
||||
|
||||
|
||||
def test_custom_named_flux2_deployment_with_only_a_reference_rate_bills_only_its_references() -> None:
|
||||
def test_custom_named_flux2_deployment_without_an_image_price_bills_nothing() -> None:
|
||||
cost: Final = CostCalculatorUtils.route_image_generation_cost_calculator(
|
||||
model="my-flux2-prod",
|
||||
completion_response=_edit_response((1024 * 1280,)),
|
||||
custom_llm_provider="azure_ai",
|
||||
size="1024x1280",
|
||||
call_type="image_edit",
|
||||
model_info={"input_cost_per_reference_pixel": 2e-07},
|
||||
model_info={"input_cost_per_second": 1.0},
|
||||
)
|
||||
|
||||
assert cost == pytest.approx(2e-07 * 1024 * 1024 * 2)
|
||||
assert cost == 0.0
|
||||
|
||||
|
||||
def test_azure_ai_image_cost_calculator_rejects_a_response_that_is_not_an_image_response() -> None:
|
||||
|
|
@ -712,7 +656,7 @@ def test_unlisted_azure_ai_deployment_without_a_generated_image_price_bills_noth
|
|||
custom_llm_provider="azure_ai",
|
||||
size="1024x1024",
|
||||
call_type="image_generation",
|
||||
model_info={"input_cost_per_reference_pixel": 1e-07},
|
||||
model_info={"input_cost_per_second": 1.0},
|
||||
)
|
||||
|
||||
assert cost == 0.0
|
||||
|
|
|
|||
|
|
@ -647,7 +647,6 @@ def validate_model_cost_values(model_data, exceptions=None):
|
|||
"output_cost_per_image_2K",
|
||||
"output_cost_per_image_4K",
|
||||
"input_cost_per_pixel",
|
||||
"input_cost_per_reference_pixel",
|
||||
"output_cost_per_pixel",
|
||||
"input_cost_per_second",
|
||||
"output_cost_per_second",
|
||||
|
|
@ -824,7 +823,6 @@ def test_aaamodel_prices_and_context_window_json_is_valid():
|
|||
"regional_processing_uplift_multiplier_eu": {"type": "number"},
|
||||
"regional_processing_uplift_multiplier_us": {"type": "number"},
|
||||
"input_cost_per_pixel": {"type": "number"},
|
||||
"input_cost_per_reference_pixel": {"type": "number"},
|
||||
"input_cost_per_query": {"type": "number"},
|
||||
"input_cost_per_request": {"type": "number"},
|
||||
"input_cost_per_second": {"type": "number"},
|
||||
|
|
|
|||
6
ui/litellm-dashboard/src/lib/http/schema.d.ts
generated
vendored
6
ui/litellm-dashboard/src/lib/http/schema.d.ts
generated
vendored
|
|
@ -33053,8 +33053,6 @@ export interface components {
|
|||
input_cost_per_pixel?: number | null;
|
||||
/** Input Cost Per Query */
|
||||
input_cost_per_query?: number | null;
|
||||
/** Input Cost Per Reference Pixel */
|
||||
input_cost_per_reference_pixel?: number | null;
|
||||
/** Input Cost Per Second */
|
||||
input_cost_per_second?: number | null;
|
||||
/** Input Cost Per Token */
|
||||
|
|
@ -35942,8 +35940,6 @@ export interface components {
|
|||
health_status?: string | null;
|
||||
/** Input Cost Per Pixel */
|
||||
input_cost_per_pixel?: number | null;
|
||||
/** Input Cost Per Reference Pixel */
|
||||
input_cost_per_reference_pixel?: number | null;
|
||||
/** Input Cost Per Token */
|
||||
input_cost_per_token?: number | null;
|
||||
/**
|
||||
|
|
@ -46850,8 +46846,6 @@ export interface components {
|
|||
input_cost_per_pixel?: number | null;
|
||||
/** Input Cost Per Query */
|
||||
input_cost_per_query?: number | null;
|
||||
/** Input Cost Per Reference Pixel */
|
||||
input_cost_per_reference_pixel?: number | null;
|
||||
/** Input Cost Per Second */
|
||||
input_cost_per_second?: number | null;
|
||||
/** Input Cost Per Token */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue