Skip to content

fix(proxy): forward every method on the typesafe pass-through route - #41723

Merged
yuneng-berri merged 6 commits into
mainfrom
litellm_/circleci-specific-sha-0cf414
Sep 18, 2026
Merged

yuneng-berri merged 6 commits into
mainfrom
litellm_/circleci-specific-sha-0cf414

Conversation

@yuneng-berri

@yuneng-berri yuneng-berri commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

How it solves it:

  • The typesafe route forwards every method like the other REST pass-throughs, so TypeSafe decides
  • A GHA unit test sends each method through the proxy to a mocked upstream so the PR gate catches this
  • test_models_by_provider skips evaluation-mode providers the way it already skips search ones

User Flow

Before: a developer sending anything but GET or POST to /typesafe/... gets the proxy's own 405, and a TypeSafe endpoint added with another method would need a proxy release first

  1. The proxy admin sets TYPESAFE_API_KEY and restarts the proxy
  2. The developer sends PUT https://litellm-domain/typesafe/v1/systemone with their virtual key and a JSON body
  3. The gateway answers 405 {"detail":"Method Not Allowed"} and nothing reaches TypeSafe

After: the same request is forwarded and TypeSafe's own answer comes back

  1. The proxy admin sets TYPESAFE_API_KEY and restarts the proxy
  2. The developer sends PUT https://litellm-domain/typesafe/v1/systemone with their virtual key and a JSON body
  3. The gateway forwards it with the proxy's TypeSafe key and returns whatever TypeSafe answers, a 405 for today's API and a real response for any endpoint TypeSafe adds later

Relevant issues

Follows up #41607. CircleCI pipeline 89758 on main flagged both gaps: https://app.circleci.com/pipelines/github/BerriAI/litellm/89758

TypeSafe's public OpenAPI (v0.2.0 at https://api.typesafe.ai/openapi.json, read 2026-09-18) lists only POST /v1/systemone and GET /v1/models, and TypeSafe itself answers 405 to PUT, DELETE and PATCH today. #41607 mirrored that surface with GET and POST. The wider method set is this repo's pass-through convention, enforced by test_pass_through_routes_support_all_methods: the proxy forwards every method and the upstream decides, with the exemption list reserved for wire protocols that admit a single method like Amazon Comprehend Medical. That test only runs on CircleCI, so the PR gate never showed it

Registering typesafe in models_by_provider would have turned test_models_by_provider green too, but it was dropped on purpose. typesafe has no LlmProviders member, so a typesafe/* deployment fails to load, get_valid_models returns nothing for it, and its spend is priced straight from model_cost. The registry entry would only silence the test. The test already carves out search-mode providers for the same reason, so the carve-out now covers evaluation mode as well

Affected release

Linear ticket

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • The handful of test files covering my change pass locally, e.g. uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*, make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more
  • My PR passes all required CI/CD checks (e.g., lint, schema.d.ts sync check, etc.)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to 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

Shared setup. TYPESAFE_API_BASE points at a local echo server that answers every method with what it received, because no TypeSafe credentials are available on this machine; the proxy side, which is what changes here, is the real proxy

general_settings:
  master_key: sk-1234
TYPESAFE_API_KEY=sk-local TYPESAFE_API_BASE=http://127.0.0.1:53612 LITELLM_LOCAL_MODEL_COST_MAP=True \
  python -m litellm.proxy.proxy_cli --config config.yaml --port 53611

Before (7e03084)

  1. curl -s -w '\nHTTP %{http_code}\n' -X PUT http://127.0.0.1:53611/typesafe/v1/systemone -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" -d '{"state":"x"}'
  2. Observed output
{"detail":"Method Not Allowed"}
HTTP 405

After (50ccb2c)

  1. curl -s -w '\nHTTP %{http_code}\n' -X PUT http://127.0.0.1:53611/typesafe/v1/systemone -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" -d '{"state":"x"}'
  2. Observed output
{"upstream_saw": {"method": "PUT", "path": "/v1/systemone", "body": "{\"state\":\"x\"}"}}
HTTP 200

Type

🐛 Bug Fix
✅ Test

Caveats (if any)

Low

  • The proof's upstream is a local echo server, not api.typesafe.ai
  • The test_models_by_provider change only runs on CircleCI, hence the run-ci label

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

#41607 registered the typesafe pass-through with a route that only accepted
GET and POST, so a PUT, DELETE or PATCH to /typesafe/... came back 405
before reaching the upstream. CircleCI's pass-through method test caught it,
but that lane does not run on the PR gate, so the mapped unit test now
covers the same invariant for typesafe

The same CircleCI run also failed test_models_by_provider because typesafe
is not a key of models_by_provider. Registering it there would satisfy the
assertion without changing behaviour: typesafe has no LlmProviders member,
so a typesafe/* deployment never loads and get_valid_models returns nothing,
and its spend is priced straight from model_cost. The test already skips
search-mode providers for that reason, so it now skips evaluation mode too
@yuneng-berri
yuneng-berri requested a review from a team September 18, 2026 01:11
@codspeed

codspeed Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_/circleci-specific-sha-0cf414 (50ccb2c) with main (c25c098)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (7e03084) during the generation of this report, so c25c098 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩

@greptile-apps

greptile-apps Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

The TypeSafe route change is sound, but the generated audit API regression and required behavioral test coverage should be fixed before merging

Findings

  1. P1 Audit search typing removed ▶
  2. P2 Test checks routing only ▶

Summary

This PR expands the TypeSafe pass-through route to accept PUT, DELETE, and PATCH and updates generated API artifacts

  • Adds route-resolution coverage for the five supported pass-through methods
  • Exempts evaluation-mode entries from the model-provider registry consistency test
  • Accidentally removes an existing audit-log query parameter from the generated dashboard schema

Reviews (1) · Last reviewed commit: "chore(proxy): regenerate the OpenAPI sna..."

Comment thread ui/litellm-dashboard/src/lib/http/schema.d.ts
The previous regeneration ran on Python 3.13, which strips docstring
indentation at compile time, so one description and one query field came out
different from what the Python 3.12 sync check produces. Regenerated on 3.12
so only the typesafe route entries differ from main
…ed upstream

The route test only resolved route names. It now sends every method through
the proxy with a virtual key and asserts the upstream receives that method,
the proxy's TypeSafe key and the caller's body
@codecov

codecov Bot commented Sep 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@yuneng-berri
yuneng-berri merged commit 34718f0 into main Sep 18, 2026
143 of 145 checks passed
@yuneng-berri
yuneng-berri deleted the litellm_/circleci-specific-sha-0cf414 branch September 18, 2026 01:57
mgmonteleone pushed a commit to mgmonteleone/litellm that referenced this pull request Sep 22, 2026
Partial backport of upstream BerriAI#41607 (price rows and the
"evaluation" model mode only; the /typesafe pass-through is not carried),
plus the test_models_by_provider skip from BerriAI#41723.

The Jev classifier (BerriAI#41615) prices its calls from typesafe/jev-* registry
rows, so they must exist even when LITELLM_LOCAL_MODEL_COST_MAP is set.

Drop this commit when rebasing onto a release that contains BerriAI#41607.

Co-Authored-By: Mateo Wang <277851410+mateo-berri@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
devin-ai-integration Bot pushed a commit that referenced this pull request Sep 22, 2026
Backport of #41723 to stable/1.102.x.
Cherry-picked from 34718f0 (main).
devin-ai-integration Bot pushed a commit that referenced this pull request Sep 23, 2026
Backport of #41723 to stable/1.101.x.
Cherry-picked from 34718f0 (main).
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.

2 participants