mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
fix(cost-map-schema): classify price_varies_by_provider so the synced map passes the guard
The sync marks a Vercel row seeded at a varies_by_provider headline price, but the production schema generator only knew the key from the test-side INTENDED_SCHEMA and exited on the first synced map as unclassified, so the workflow would have stopped before opening a PR. The key is a boolean in the generator's key tables, and a regression test syncs the fixtures plus a varies-by-provider row and validates the result against the generated schema.
This commit is contained in:
parent
fb8f9af5a1
commit
84b7f25e46
2 changed files with 34 additions and 0 deletions
|
|
@ -28,6 +28,7 @@ EXTRA_BOOLEAN_KEYS = frozenset(
|
|||
"use_openai_responses_path",
|
||||
"bedrock_converse_supports_strict_tools",
|
||||
"thinking_always_on",
|
||||
"price_varies_by_provider",
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from litellm.types.utils import ModelInfo, Usage
|
|||
|
||||
REPO_ROOT: Final = Path(__file__).resolve().parents[2]
|
||||
SCRIPT_PATH: Final = REPO_ROOT / "scripts" / "sync_cost_map.py"
|
||||
GENERATOR_PATH: Final = REPO_ROOT / "ci_cd" / "generate_model_prices_schema.py"
|
||||
FIXTURES: Final = Path(__file__).parent / "fixtures" / "cost_map_sync"
|
||||
OPENROUTER_RAW: Final = (FIXTURES / "openrouter_models.json").read_bytes()
|
||||
VERCEL_RAW: Final = (FIXTURES / "vercel_models.json").read_bytes()
|
||||
|
|
@ -771,6 +772,38 @@ def test_a_price_that_varies_by_provider_seeds_and_only_overwrites_what_the_bot_
|
|||
)
|
||||
|
||||
|
||||
def test_every_key_the_sync_writes_is_classified_by_the_schema_generator(sync: ModuleType) -> None:
|
||||
spec: Final = importlib.util.spec_from_file_location("generate_model_prices_schema", GENERATOR_PATH)
|
||||
assert spec is not None and spec.loader is not None
|
||||
generator: Final = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(generator)
|
||||
varies: Final = sync.load_vercel(
|
||||
_vercel_rows(
|
||||
{
|
||||
"id": "acme/varies",
|
||||
"context_window": 262144,
|
||||
"pricing": {
|
||||
"input": "0.0000015",
|
||||
"input_tiers": [
|
||||
{"cost": "0.0000015", "min": 0, "max": 128001},
|
||||
{"cost": "0.000003", "min": 128001},
|
||||
],
|
||||
"output": "0.000002",
|
||||
"input_cache_read": "0.0000003",
|
||||
"varies_by_provider": True,
|
||||
},
|
||||
}
|
||||
),
|
||||
now_ms=NOW_MS,
|
||||
)
|
||||
synced: Final = sync.compute_sync(
|
||||
_base_map(), (sync.load_openrouter(OPENROUTER_RAW), sync.load_vercel(VERCEL_RAW, now_ms=NOW_MS), varies)
|
||||
).cost_map
|
||||
|
||||
assert synced["vercel_ai_gateway/acme/varies"]["price_varies_by_provider"] is True
|
||||
assert generator.validation_errors(synced, generator.build_schema(synced)) == ()
|
||||
|
||||
|
||||
def test_image_and_audio_outputs_are_priced_per_token_or_skipped(sync: ModuleType) -> None:
|
||||
openrouter: Final = sync.load_openrouter(
|
||||
_openrouter_rows(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue