mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-07 08:26:10 +00:00
fix(ci): skip variable-priced catalog rows so the schema gate stays green
This commit is contained in:
parent
cc3d07511d
commit
f0c6efc695
2 changed files with 44 additions and 3 deletions
|
|
@ -69,6 +69,10 @@ def write_to_file(file_path: str, data: dict[str, object]) -> None:
|
|||
def transform_openrouter_data(data):
|
||||
transformed = {}
|
||||
for row in data:
|
||||
if float(row["pricing"]["prompt"]) < 0 or float(row["pricing"]["completion"]) < 0:
|
||||
print(f"Skipping openrouter/{row['id']}: the catalog lists no usable per-token price for it.")
|
||||
continue
|
||||
|
||||
# Add the fields 'max_tokens' and 'input_cost_per_token'
|
||||
obj = {
|
||||
"max_tokens": row["context_length"],
|
||||
|
|
@ -106,8 +110,10 @@ def transform_openrouter_data(data):
|
|||
def _vercel_entry(model: VercelModel) -> dict[str, object] | None:
|
||||
mode: Final = VERCEL_TYPE_TO_MODE[model.type]
|
||||
pricing: Final = model.pricing if model.pricing is not None else VercelPricing()
|
||||
if pricing.input is None or (mode == "chat" and pricing.output is None):
|
||||
print(f"Skipping vercel_ai_gateway/{model.id}: the catalog lists no per-token price for it.")
|
||||
input_price_unusable: Final = pricing.input is None or pricing.input < 0
|
||||
output_price_unusable: Final = mode == "chat" and (pricing.output is None or pricing.output < 0)
|
||||
if input_price_unusable or output_price_unusable:
|
||||
print(f"Skipping vercel_ai_gateway/{model.id}: the catalog lists no usable per-token price for it.")
|
||||
return None
|
||||
candidate: Final = {
|
||||
"max_tokens": model.max_tokens,
|
||||
|
|
|
|||
|
|
@ -40,11 +40,31 @@ VIDEO_ROW = {
|
|||
"pricing": {"video_duration_pricing": [{"resolution": "720p", "price_per_second": "0.4"}]},
|
||||
}
|
||||
IMAGE_ROW = {"id": "openai/gpt-image-1", "type": "image"}
|
||||
NEGATIVE_PRICE_LANGUAGE_ROW = {
|
||||
"id": "openrouter/auto",
|
||||
"type": "language",
|
||||
"context_window": 2000000,
|
||||
"max_tokens": 2000000,
|
||||
"pricing": {"input": "-1", "output": "-1"},
|
||||
}
|
||||
OPENROUTER_ROW = {
|
||||
"id": "anthropic/claude-sonnet-4.5",
|
||||
"context_length": 1000000,
|
||||
"pricing": {"prompt": "0.000003", "completion": "0.000015", "image": "0"},
|
||||
"top_provider": {"max_completion_tokens": 64000},
|
||||
"architecture": {"modality": "text+image->text"},
|
||||
}
|
||||
OPENROUTER_VARIABLE_PRICE_ROW = {
|
||||
"id": "openrouter/auto",
|
||||
"context_length": 2000000,
|
||||
"pricing": {"prompt": "-1", "completion": "-1"},
|
||||
"top_provider": {"max_completion_tokens": None},
|
||||
}
|
||||
|
||||
|
||||
def test_vercel_rows_without_per_token_pricing_are_skipped_instead_of_crashing() -> None:
|
||||
result = price_sync.transform_vercel_ai_gateway_data(
|
||||
[LANGUAGE_ROW, EMBEDDING_ROW, UNPRICED_LANGUAGE_ROW, VIDEO_ROW, IMAGE_ROW]
|
||||
[LANGUAGE_ROW, EMBEDDING_ROW, UNPRICED_LANGUAGE_ROW, VIDEO_ROW, IMAGE_ROW, NEGATIVE_PRICE_LANGUAGE_ROW]
|
||||
)
|
||||
|
||||
assert result == {
|
||||
|
|
@ -71,6 +91,21 @@ def test_vercel_rows_without_per_token_pricing_are_skipped_instead_of_crashing()
|
|||
}
|
||||
|
||||
|
||||
def test_openrouter_variable_priced_rows_are_skipped_so_the_schema_gate_stays_green() -> None:
|
||||
result = price_sync.transform_openrouter_data([OPENROUTER_ROW, OPENROUTER_VARIABLE_PRICE_ROW])
|
||||
|
||||
assert result == {
|
||||
"openrouter/anthropic/claude-sonnet-4.5": {
|
||||
"max_tokens": 1000000,
|
||||
"max_output_tokens": 64000,
|
||||
"input_cost_per_token": 3e-06,
|
||||
"output_cost_per_token": 1.5e-05,
|
||||
"litellm_provider": "openrouter",
|
||||
"mode": "chat",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_write_to_file_matches_the_checked_in_cost_map_format(tmp_path: Path) -> None:
|
||||
target = tmp_path / "model_prices_and_context_window.json"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue