From 6544beae3408a1bd67229b4ba34bde369b1ca91b Mon Sep 17 00:00:00 2001 From: Vigilans Date: Sun, 17 May 2026 12:16:58 +0800 Subject: [PATCH] feat(proxy): add global websearch_fallback_model setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a web-search-only request targets a model that does not support web search, redirect it to the model group specified in litellm_settings.websearch_fallback_model. Uses litellm.supports_web_search() for capability detection, which correctly strips provider prefixes (e.g. github_copilot/gpt-5.5 → gpt-5.5) when looking up the model registry. Also add github_copilot to _check_provider_match exemption list, aligning it with the existing github exemption. --- litellm/proxy/common_request_processing.py | 15 ++++++++++++--- litellm/utils.py | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/litellm/proxy/common_request_processing.py b/litellm/proxy/common_request_processing.py index 9d69f4c97ba..0b985c6b785 100644 --- a/litellm/proxy/common_request_processing.py +++ b/litellm/proxy/common_request_processing.py @@ -923,9 +923,11 @@ class ProxyBaseLLMRequestProcessing: ): self.data["model"] = user_api_key_dict.aliases[self.data["model"]] - ### WEB SEARCH REDIRECT (per-deployment force) ### - # if request only contains a web_search tool and has any deployment that has - # `force_websearch_model`, redirect to that model. + ### WEB SEARCH REDIRECT ### + # if request only contains web_search tools, check for redirect: + # 1. per-deployment force: always redirect to `force_websearch_model` + # 2. global fallback: redirect to `websearch_fallback_model` only when + # the current model group does not support web search if ( isinstance(self.data.get("model"), str) and llm_router is not None @@ -939,6 +941,13 @@ class ProxyBaseLLMRequestProcessing: if model := dep.get("litellm_params", {}).get("force_websearch_model"): self.data["model"] = model break + if ( + (dep_model := dep.get("litellm_params", {}).get("model", "")) + and not litellm.supports_web_search(dep_model) + and (model := getattr(litellm, "websearch_fallback_model", None)) + ): + self.data["model"] = model + break self.data["litellm_call_id"] = request.headers.get( "x-litellm-call-id", str(uuid.uuid4()) diff --git a/litellm/utils.py b/litellm/utils.py index 2ba6ef9cae8..9121473918c 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -5579,7 +5579,7 @@ def _check_provider_match(model_info: dict, custom_llm_provider: Optional[str]) # as a last attempt if the model is not on Azure AI, Azure then fallback to OpenAI cost # tracking the cost is better than attributing 0 cost to it. return True - elif custom_llm_provider == "github": + elif custom_llm_provider in ("github", "github_copilot"): # Allow github/ aliases to reuse existing provider metadata. return True else: