Skip to content

refactor: regenerate model_prices backup at build time - #27147

Closed
Chesars wants to merge 4 commits into
litellm_internal_stagingfrom
litellm_remove_redundant_model_cost_backup_file
Closed

refactor: regenerate model_prices backup at build time#27147
Chesars wants to merge 4 commits into
litellm_internal_stagingfrom
litellm_remove_redundant_model_cost_backup_file

Conversation

@Chesars

@Chesars Chesars commented May 5, 2026

Copy link
Copy Markdown
Contributor

Title

refactor: regenerate model_prices backup at build time

Relevant issues

Closes #27124

(Replays the design of the reverted #16590 against the current release pipeline.)

Background

litellm ships two model-pricing JSONs that must stay byte-identical:

  • model_prices_and_context_window.json (repo root, edited in PRs)
  • litellm/model_prices_and_context_window_backup.json (mirror used as the local fallback)

In practice they drift — features land in the root file but the backup is forgotten. The two files are conceptually one piece of data with two storage locations. Treat the second one as a build artefact of the first.

Pre-Submission checklist

  • Tests added/updated under tests/ (touched tests/local_testing/test_get_model_file.py and tests/test_litellm/test_deepseek_model_metadata.py to load via the public helper)
  • make test-unit passes locally for the touched suites (40 / 40 green: test_get_model_file, test_deepseek_model_metadata, test_model_cost_map_resilience)
  • Black-clean
  • PR scope is isolated: single problem (DRY the model-cost map)

Type

🧹 Refactoring

Solution

Stop committing the backup. Make it a generated build artefact instead.

Code

  • litellm/litellm_core_utils/get_model_cost_map.pyload_local_model_cost_map() now resolves to the repo-root JSON when running from a source checkout (editable install), and falls back to the bundled litellm/model_prices_and_context_window_backup.json in installed wheels. Single source of truth in dev; production behaviour unchanged.

Build / packaging

  • .github/workflows/publish_to_pypi.yml — already copies root → backup before uv build (no change needed; line 124-125).
  • 5 Dockerfiles that build a wheel from source (uv sync --no-editable) now run the same cp after COPY . . and before the wheel-producing sync: Dockerfile, docker/Dockerfile.alpine, docker/Dockerfile.non_root, docker/Dockerfile.dev, docker/Dockerfile.database.
  • Dockerfile.health_check, Dockerfile.custom_ui, deploy/Dockerfile.ghcr_base, docker/build_from_pip/Dockerfile.build_from_pip are unaffected (they don't build a wheel from source — they install another tool, base off a pre-built image, or pip install from PyPI).

Cleanup

  • litellm/model_prices_and_context_window_backup.json — deleted; gitignored.
  • ci_cd/check_files_match.py — removed (no longer invoked by any workflow; checked the root JSON against its own generated copy, which is meaningless once one is the artefact of the other).

Tests

  • tests/local_testing/test_get_model_file.py and tests/test_litellm/test_deepseek_model_metadata.py previously bypassed the helper and opened the file directly via importlib.resources.open_text(...) / os.path.dirname(litellm.__file__) + "/...". They now go through GetModelCostMap.load_local_model_cost_map() and so inherit the dev/prod resolution automatically.

Resulting flow

Surface Has backup file? Source
Repo (git) No
Dev / editable install No (code reads the root JSON directly) Repo root
publish_to_pypi.yml build Yes, in the wheel Workflow cp step
Docker images built from source Yes, in the wheel inside the image Dockerfile RUN cp step
Wheel installed by end users (pip install litellm) Yes, bundled Came with the wheel

The root JSON remains the single editable source of truth; every other "copy" is regenerated automatically wherever a wheel is built. No manual sync, no drift class.

Local verification

  • make test-unit for the touched suites: 40 / 40 passing.
  • Smoke test with the backup deleted: LITELLM_LOCAL_MODEL_COST_MAP=True python -c "from litellm.litellm_core_utils.get_model_cost_map import GetModelCostMap; print(len(GetModelCostMap.load_local_model_cost_map()))"2692 (and source info reports source=local, is_env_forced=True).
  • uv run black --check on the touched files: clean.

Test plan

  • Confirm CircleCI / GitHub Actions build the package with the backup present in the wheel
  • Confirm Docker image build from source includes litellm/model_prices_and_context_window_backup.json in /app/.venv/.../site-packages/litellm/
  • Run LITELLM_LOCAL_MODEL_COST_MAP=True end-to-end against a built wheel and verify the local fallback resolves

The local backup `litellm/model_prices_and_context_window_backup.json`
was a hand-edited mirror of the root `model_prices_and_context_window.json`.
The two routinely drifted (xAI grok-3 prompt-caching, deepseek capability
flags, etc.), masking real bugs in CI. Make the backup a generated build
artefact instead of a committed file:

- `get_model_cost_map.load_local_model_cost_map()` now reads the root JSON
  when available (source checkout / editable install) and falls back to
  the bundled package copy in installed wheels.
- The release pipeline already copies root -> backup before build
  (`publish_to_pypi.yml`); add the same step to the 5 Dockerfiles that
  build a wheel from source (`Dockerfile`, `docker/Dockerfile.{alpine,non_root,dev,database}`).
- Delete the committed backup JSON and `ci_cd/check_files_match.py`,
  gitignore the backup path.
- Tests that opened the backup directly now go through the helper.

Closes #27124
@Chesars
Chesars changed the base branch from main to litellm_internal_staging May 5, 2026 00:36
@codspeed-hq

codspeed-hq Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

Congrats! CodSpeed is installed 🎉

🆕 16 new benchmarks were detected.

You will start to see performance impacts in the reports once the benchmarks are run from your default branch.

Detected benchmarks


Open in CodSpeed

… litellm_remove_redundant_model_cost_backup_file

# Conflicts:
#	litellm/model_prices_and_context_window_backup.json
@greptile-apps

greptile-apps Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR treats litellm/model_prices_and_context_window_backup.json as a build artifact rather than a committed file: load_local_model_cost_map() now reads the repo-root JSON in a source checkout and falls back to the bundled backup in installed wheels, while a cp step in each source-build Dockerfile (and the existing PyPI workflow) materializes the backup before uv sync --no-editable. Previous review concerns (missing-file error handling, pyproject.toml sentinel for the depth heuristic, and debug logging) are all addressed in this revision. The only remaining gap is that the files(\"litellm\") bundled-backup branch is never exercised by CI tests — see the inline comment on test_get_model_file.py.

Confidence Score: 5/5

Safe to merge; the implementation is sound and all previous blocking concerns are addressed.

No P0 or P1 findings. The single P2 (bundled-backup code path not exercised in CI) is a coverage gap, not a production defect — the backup is still materialised correctly at build time and the FileNotFoundError re-raise makes any omission immediately actionable.

tests/local_testing/test_get_model_file.py — the bundled-backup branch of load_local_model_cost_map() lacks a CI test

Important Files Changed

Filename Overview
litellm/litellm_core_utils/get_model_cost_map.py load_local_model_cost_map() now resolves to repo-root JSON in dev and bundled backup in wheels; previous thread concerns (missing-file error, depth heuristic, logging) are all addressed
Dockerfile Adds cp step after COPY and before uv sync --no-editable to materialize the backup JSON into the wheel; ordering is correct
docker/Dockerfile.non_root Same cp step at line 56, before the uv sync --no-editable at line 78+; ordering verified correct
docker/Dockerfile.alpine cp step added in correct position before uv sync --no-editable
docker/Dockerfile.database cp step added in correct position before uv sync --no-editable
docker/Dockerfile.dev cp step added in correct position before uv sync --no-editable
ci_cd/check_files_match.py Deleted; confirmed no remaining references in the repo — removal is safe
tests/local_testing/test_get_model_file.py test_get_backup_model_cost_map replaced with test_load_local_model_cost_map; the bundled-backup code path (files("litellm")...) is no longer exercised in CI since the file is gitignored in source checkouts
.gitignore Backup JSON correctly gitignored since it is now a build artifact

Reviews (2): Last reviewed commit: "fix(get_model_cost_map): give an actiona..." | Re-trigger Greptile

Comment thread litellm/litellm_core_utils/get_model_cost_map.py Outdated
Comment thread litellm/litellm_core_utils/get_model_cost_map.py Outdated
Comment thread litellm/litellm_core_utils/get_model_cost_map.py Outdated
Chesars added 2 commits May 4, 2026 21:54
…olved path

Address PR feedback:
- Witness the repo root with pyproject.toml so moving get_model_cost_map.py
  cannot silently break detection (parents[2] alone was depth-fragile).
- Emit verbose_logger.debug at each branch so the resolved file is
  observable when diagnosing pricing issues.
… is missing

Wrap the package-resource load so that a wheel built without the
prerequisite cp step (e.g. a manual `uv build`) surfaces a message that
names the missing file, points at the canonical build steps, and shows
the one-liner fix. The original FileNotFoundError is preserved via
`raise ... from e`.

Addresses Greptile review P1.
@oss-pr-review-agent-shin

Copy link
Copy Markdown
Contributor

🤖 litellm-agent: This PR's commits have been merged into the staging branch litellm_agent_oss_staging_05_05_2026.

Staging PR: #27162

oss-pr-review-agent-shin Bot added a commit that referenced this pull request May 5, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@github-actions github-actions Bot added the stale label Aug 4, 2026
@github-actions github-actions Bot closed this Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore: backup model_cost JSON drift vs root model_prices_and_context_window.json

1 participant