chore(typing): clear 2.7k basedpyright Any errors across 15 hotspot files - #34745
Conversation
…iles Replace Any-typed seams with real types in the files carrying the highest reportAny/reportExplicitAny density: typed Prisma read helpers in the MCP db layer and verification token repository, TypedDicts for OAuth credential payloads and aggregated spend rows, a DailySpendRecord protocol for the daily activity endpoints, and concrete request/response types in the volcengine, openai evals, azure batches, azure_ai count_tokens, and ocr transformation modules. Modernize touched annotations to PEP 604/585 forms. No casts, no type: ignore, no noqa, no new Any annotations, no behavior changes. Whole-tree basedpyright: reportAny 27,005 -> 24,427, reportExplicitAny 7,439 -> 7,280, no rule increased anywhere. Budgets ratcheted: basedpyright -2,869, ruff-strict -1,505, type-discipline -167.
|
bugbot run |
Greptile SummaryThis PR strengthens static typing across provider transformations, MCP credential handling, management endpoints, usage aggregation, registries, and Prisma boundaries
Confidence Score: 5/5The PR appears safe to merge No blocking failure remains
|
| Filename | Overview |
|---|---|
| litellm/proxy/_experimental/mcp_server/db.py | Adds typed Prisma and OAuth credential boundaries while preserving the existing stored credential fields and refresh flow |
| litellm/proxy/_experimental/mcp_server/server.py | Narrows MCP server and prefetched OAuth credential types without changing admission or dispatch behavior |
| litellm/proxy/management_endpoints/common_daily_activity.py | Introduces typed spend-record and aggregate-row representations while retaining nullable SQL aggregate handling |
| litellm/proxy/guardrails/usage_endpoints.py | Retypes guardrail usage aggregation and log transformation helpers |
| enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py | Adds typed Prisma table access and Pydantic validation at project-management data boundaries |
| litellm/llms/openai/evals/transformation.py | Uses concrete eval request and response models and adds transformation coverage |
| litellm/llms/volcengine/responses/transformation.py | Retypes response parsing and field-fill transformations with expanded streaming and fallback tests |
| .github/workflows/test-linting.yml | Raises the Node.js heap limit for the basedpyright budget check |
| basedpyright-code-budget.json | Ratchets type-checking diagnostic ceilings downward to retain the reductions from this refactor |
Reviews (2): Last reviewed commit: "test: cover volcengine responses and ope..." | Re-trigger Greptile
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit fbfb63c. Configure here.
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
basedpyright's inference load now exceeds node's ~4GB default heap cap on ubuntu-latest once the Any hotspots carry real types; the node process died with a JS heap OOM, emitted nothing, and the gate refused the vacuous run. 12GB leaves headroom on the 16GB runner.
Exercises the streaming field-fill heuristics, model_construct fallbacks, and the get/cancel/delete/list request and response transforms that had no tests.
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 8b08c31. Configure here.
Replace Any-typed seams with real types in files carrying the highest remaining reportAny/reportExplicitAny density after BerriAI#34745: the proxy server and its utils, the router, the streaming handler and chunk builder, litellm_logging, the redis cache, the MCP db/tool-registry/spend-writer layer, the anthropic pass-through adapters and guardrail translation, the lasso and presidio guardrail hooks, the azure_ai agents handler, the management endpoints (keys, users, ui_sso, model access groups, config override, MCP, projects), the responses MCP handlers, response polling background streaming, and the containers and vector stores mains No casts, no type: ignore, no noqa, no new suppressions, and no Any annotations that were not already at base. Whole-tree basedpyright: reportAny 14,610 -> 14,009, reportExplicitAny 5,100 -> 4,780, total 144,743 -> 143,471, with no rule increasing repo-wide or in any file. Budgets ratcheted: basedpyright -1,272 across 48 rules, ruff-strict -85, type-discipline -37
TLDR
Problem this solves:
How it solves it:
Relevant issues
Linear ticket
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
@greptileaito re-request a review after pushing changes)Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
Whole-tree basedpyright before and after this branch, measured with the same command the CI gate runs (
uv run basedpyright --outputjson | python scripts/type_check_gate.py), counting severity=error diagnostics in-tree:No basedpyright rule increased, repo-wide or in any individual file; every one of the 48 budgeted rules is at or below its baseline count.
make lint-budget-updateoutput confirming the fixes are real and the ceilings now hold them:from litellm import *import safety and the circular import check both pass, andmake pre-commitis greenType
🧹 Refactoring
Changes
Typing-only changes across the 15 files with the highest reportAny/reportExplicitAny density, plus the small blast radius those fixes surfaced in 7 neighboring files. No runtime behavior changes: annotations, TYPE_CHECKING imports, TypedDicts, Protocols, and pydantic
model_validateswaps that are runtime-equivalent to theModel(**dict)constructors they replaceThe recurring root causes and their fixes: untyped Prisma reads now go through typed helpers that pay the Any-to-typed crossing once per boundary (
mcp_server/db.py,verification_token_repository.py);dict[str, Any]payloads became local TypedDicts (OAuth credential payloads, aggregated spend rows, guardrail usage responses); duck-typed spend records got aDailySpendRecordProtocol shared by the daily-activity endpoints; response transformation modules (volcengine, openai evals, azure batches, azure_ai count_tokens, ocr) now use the concrete request/response types they already importedForbidden constructs were not used anywhere in the diff: no
cast(), no# type: ignore, no# noqa, no suppression comments, no newAnyannotations. Diagnostics that could not be fixed without one of those were left in place rather than hidden, which is why roughly 380 target errors remain in the touched files (mostly the irreducible one-flag-per-seam residue where upstream sources likePrismaWrapper.__getattr__still return Any)Budget files are ratcheted by
make lint-budget-updateso the cleared headroom cannot silently grow back. The existing mapped suites for every touched module pass (1,140 tests, 0 failures)Two follow-up commits round the PR out. 26ab846 raises the lint job's node heap to 12GB for the basedpyright budget step: with the hotspots now carrying real types, basedpyright's inference load exceeds node's ~4GB default cap on ubuntu-latest, so the process died with a JS heap OOM and the gate correctly refused the vacuous run (deterministic; a rerun at fbfb63c OOM'd the same way). 8b08c31 adds tests for the volcengine responses and openai evals transformation modules, covering the streaming field-fill heuristics, the model_construct fallbacks, and the get/cancel/delete/list request and response transforms that previously had no tests; these are retyped surfaces of this PR, and covering them also lifts the diff's patch coverage past the codecov target
QA runbook
make lint-basedpyright lint-type-discipline lint-ruff-budgetall green on this branchgit diff litellm_internal_staging --statshows only typing edits, budget JSONs, and no test deletionspython litellm/proxy/proxy_cli.py --config litellm/proxy/dev_config.yaml) and confirm clean startup, then exercise a touched surface end to end, e.g.curl http://localhost:4000/user/daily/activity?start_date=2026-07-01&end_date=2026-07-25 -H "Authorization: Bearer sk-1234"and the MCP credential list athttp://localhost:4000/ui/?page=mcp-servers; responses are byte-identical to litellm_internal_staging because no runtime code path changedFinal Attestation
Note
Low Risk
Refactor is typing-only with equivalent Pydantic validation patterns; main operational risk is CI memory for basedpyright, which this PR explicitly addresses.
Overview
This PR lowers basedpyright error ceilings in
basedpyright-code-budget.json(notablyreportAnyand related rules) and setsNODE_OPTIONS=--max-old-space-size=12288on the lint workflow’s basedpyright step so the heavier typed tree does not OOM in CI.Across the code changes, the work is annotation and boundary typing, not new product behavior: modern union/
listsyntax,model_validateinstead of**dictconstruction, andTYPE_CHECKING+ Prisma model types with small DB accessor helpers (especially in MCPdb.pyand enterprise project endpoints). OAuth credential payloads get explicitTypedDicts; MCP REST/outbound OAuth stores useMappinginstead of loose dicts. LLM provider modules (Azure batches, OpenAI evals, Volcengine responses, Azure AI count_tokens, OCR) get stricter request/response typing and shared JSON-parse helpers where needed.Reviewed by Cursor Bugbot for commit 8b08c31. Bugbot is set up for automated code reviews on this repo. Configure here.