From e39742c429b3e8f026df2624f11e5c70f5c7ea44 Mon Sep 17 00:00:00 2001 From: Shroominic Date: Mon, 22 Dec 2025 09:35:23 +0100 Subject: [PATCH] rm completion_image pricing with manual overrides --- routstr/payment/cost_calculation.py | 29 +---------------------------- routstr/payment/models.py | 25 ------------------------- 2 files changed, 1 insertion(+), 53 deletions(-) diff --git a/routstr/payment/cost_calculation.py b/routstr/payment/cost_calculation.py index 037efc42..03b37362 100644 --- a/routstr/payment/cost_calculation.py +++ b/routstr/payment/cost_calculation.py @@ -121,7 +121,6 @@ async def calculate_cost( # todo: can be sync MSATS_PER_1K_OUTPUT_TOKENS: float = ( float(settings.fixed_per_1k_output_tokens) * 1000.0 ) - MSATS_PER_1K_IMAGE_COMPLETION_TOKENS: float = 0.0 if not settings.fixed_pricing: response_model = response_data.get("model", "") @@ -156,13 +155,11 @@ async def calculate_cost( # todo: can be sync try: mspp = float(model_obj.sats_pricing.prompt) mspc = float(model_obj.sats_pricing.completion) - mspci = float(getattr(model_obj.sats_pricing, "completion_image", 0.0)) except Exception: return CostDataError(message="Invalid pricing data", code="pricing_invalid") MSATS_PER_1K_INPUT_TOKENS = mspp * 1_000_000.0 MSATS_PER_1K_OUTPUT_TOKENS = mspc * 1_000_000.0 - MSATS_PER_1K_IMAGE_COMPLETION_TOKENS = mspci * 1_000_000.0 logger.info( "Applied model-specific pricing", @@ -170,7 +167,6 @@ async def calculate_cost( # todo: can be sync "model": response_model, "input_price_msats_per_1k": MSATS_PER_1K_INPUT_TOKENS, "output_price_msats_per_1k": MSATS_PER_1K_OUTPUT_TOKENS, - "image_completion_price_msats_per_1k": MSATS_PER_1K_IMAGE_COMPLETION_TOKENS, }, ) @@ -195,32 +191,10 @@ async def calculate_cost( # todo: can be sync output_tokens if output_tokens != 0 else usage_data.get("output_tokens", 0) ) - # Calculate image completion cost - image_completion_msats = 0.0 - if MSATS_PER_1K_IMAGE_COMPLETION_TOKENS > 0: - completion_details = usage_data.get("completion_tokens_details", {}) - image_tokens = completion_details.get("image_tokens", 0) - - if image_tokens > 0: - if output_tokens >= image_tokens: - output_tokens -= image_tokens - - image_completion_msats = round( - image_tokens / 1000 * MSATS_PER_1K_IMAGE_COMPLETION_TOKENS, 3 - ) - - logger.info( - "Calculated image completion cost", - extra={ - "image_tokens": image_tokens, - "image_completion_msats": image_completion_msats, - }, - ) - input_msats = round(input_tokens / 1000 * MSATS_PER_1K_INPUT_TOKENS, 3) output_msats = round(output_tokens / 1000 * MSATS_PER_1K_OUTPUT_TOKENS, 3) - token_based_cost = math.ceil(input_msats + output_msats + image_completion_msats) + token_based_cost = math.ceil(input_msats + output_msats) logger.info( "Calculated token-based cost", @@ -229,7 +203,6 @@ async def calculate_cost( # todo: can be sync "output_tokens": output_tokens, "input_cost_msats": input_msats, "output_cost_msats": output_msats, - "image_completion_msats": image_completion_msats, "total_cost_msats": token_based_cost, "model": response_data.get("model", "unknown"), }, diff --git a/routstr/payment/models.py b/routstr/payment/models.py index 4c8dbde4..d6eccf5d 100644 --- a/routstr/payment/models.py +++ b/routstr/payment/models.py @@ -31,7 +31,6 @@ class Pricing(BaseModel): completion: float request: float = 0.0 image: float = 0.0 - completion_image: float = 0.0 web_search: float = 0.0 internal_reasoning: float = 0.0 input_cache_read: float = 0.0 @@ -41,13 +40,6 @@ class Pricing(BaseModel): max_cost: float = 0.0 # in sats not msats -PRICING_OVERRIDES = { - "gemini-3-pro-image-preview": {"completion_image": 0.00012}, - "gemini-2.5-flash-image": {"completion_image": 0.00003}, - "gemini-2.0-flash": {"completion_image": 0.00003}, -} - - class TopProvider(BaseModel): context_length: int | None = None max_completion_tokens: int | None = None @@ -124,16 +116,6 @@ async def async_fetch_openrouter_models(source_filter: str | None = None) -> lis if not _has_valid_pricing(model): continue - # Apply manual pricing overrides - if model_id in PRICING_OVERRIDES: - pricing = model.get("pricing", {}) - if pricing: - for k, v in PRICING_OVERRIDES[model_id].items(): - pricing[k] = str( - v - ) # OpenRouter API returns strings for pricing - model["pricing"] = pricing - models_data.append(model) return models_data @@ -166,12 +148,6 @@ def _row_to_model( if isinstance(pricing, dict) and float(pricing.get("request", 0.0)) <= 0.0: pricing["request"] = max(pricing.get("request", 0.0), 0.0) - # Apply defaults for missing fields from manual overrides - if row.id in PRICING_OVERRIDES and isinstance(pricing, dict): - for k, v in PRICING_OVERRIDES[row.id].items(): - if k not in pricing: - pricing[k] = v - parsed_pricing = Pricing.parse_obj(pricing) model = Model( id=row.id, @@ -531,7 +507,6 @@ def _pricing_matches( "completion", "request", "image", - "completion_image", "web_search", "internal_reasoning", ]