fix(mcp): defer proxy import so completion(tools=...) works without proxy extras - #32339
Conversation
|
|
Greptile SummaryFixes a
Confidence Score: 5/5The change is minimal and surgical: one import moved from module scope into an already-guarded branch; no logic changes anywhere. The import relocation is correct and aligns with the existing lazy-import pattern in the file. The new test exercises exactly the broken path using a subprocess fastapi blocker with No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/responses/mcp/litellm_proxy_mcp_handler.py | Moves LiteLLMProxyRequestSetup import from module top-level into the if user_api_key_auth is not None: guard, eliminating the transitive fastapi import on base SDK installs. |
| tests/test_litellm/responses/mcp/test_litellm_proxy_mcp_handler.py | Adds a subprocess-based regression test that installs a custom sys.meta_path blocker for fastapi and verifies litellm.completion() with tools succeeds; uses mock_response so no real network call is made. |
Reviews (2): Last reviewed commit: "fix(mcp): defer proxy import so completi..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
5c3652b to
fadfeab
Compare
|
@greptileai please review the current head fadfeab (rebase onto current staging; only conflict was import adjacency with the strip_known_server_prefix change, logic unchanged) |
) litellm 1.92.0 adds a module-level `from litellm.proxy.litellm_pre_call_utils import LiteLLMProxyRequestSetup` to `litellm/responses/mcp/litellm_proxy_mcp_handler.py` (line 20). That proxy module top-level-imports fastapi, so any base-SDK install that does not pull the [proxy] extra crashes with `ModuleNotFoundError: No module named 'fastapi'` the moment `completion(..., tools=[...])` is called. Upstream tracking: BerriAI/litellm#32993 (fix: BerriAI/litellm#32339). Scope of the regression: - v1.91.3: offending import absent (clean). - v1.92.0: offending import newly added. - v1.93.0-rc.1: offending import removed again (fix commit merged). The upstream fix landed on `litellm_internal_staging` on 2026-07-07 but was one of the PRs NOT cherry-picked into the v1.92.0 stable cut (that tag's commit message: "backport 11 staging PRs onto patch-1.92.0rc2 for the 1.92.0 stable cut"). Single-tag process slip, not a broader pattern. Pin narrows to `>=1.83.14,!=1.92.0,<2.0.0`, keeping the exclusion minimal so we auto-adopt the eventual 1.92.1 patch or 1.93.0 stable without another release. uv.lock stays on 1.87.0.
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
Since #31576,
litellm/responses/mcp/litellm_proxy_mcp_handler.pyimportslitellm.proxy.litellm_pre_call_utilsat module top, which imports fastapi.completion()imports that module whenevertoolsis passed (litellm/main.py), so any completion call with tools crashes on a base SDK install (no[proxy]extra) withModuleNotFoundError: No module named 'fastapi'. This is also why the CodSpeed benchmark job has been red on every run since Jul 2 (its env installs base deps only)Before the fix, on a base-deps-only env (same install the CodSpeed workflow uses):
After the fix, same command:
And the end-user scenario, a real OpenAI request with tools on a base-deps-only env:
Screen recording of the end-to-end verification on a base SDK install without the proxy extra, showing the crash on the unfixed merge-base and the success on this branch
Type
🐛 Bug Fix
Changes
Moves the
LiteLLMProxyRequestSetupimport from module top into its single call site, which only runs whenuser_api_key_authis set (proxy context, where fastapi is guaranteed installed). This matches the module's existing pattern: every other proxy-only dependency in this file is already imported lazily inside the function that needs it, precisely so the module stays importable on base SDK installsAdds a regression test that runs
completion()with function tools in a subprocess where fastapi imports are blocked, so a top-level proxy import can never leak into this path again without failing testsLink to Devin session: https://app.devin.ai/sessions/e3ebfe88cf5744afa6f27d0e61ae8b60