fix(spend_tracking): honour the global litellm_proxy override when inferring a model group provider

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
yassin 2026-09-17 00:03:01 +00:00
parent 5f1d87911a
commit b35ca7d2c3
4 changed files with 32 additions and 2 deletions

View file

@ -160,7 +160,7 @@ def get_llm_provider(
if model is None:
raise ValueError("model parameter is required but was None. Please provide a valid model name.")
if litellm.LiteLLMProxyChatConfig._should_use_litellm_proxy_by_default(
if litellm.LiteLLMProxyChatConfig.should_use_litellm_proxy_by_default(
litellm_params=cast(LiteLLM_Params | None, litellm_params)
):
return litellm.LiteLLMProxyChatConfig.litellm_proxy_get_custom_llm_provider_info(

View file

@ -54,7 +54,7 @@ class LiteLLMProxyChatConfig(OpenAIGPTConfig):
return api_key or get_secret_str("LITELLM_PROXY_API_KEY")
@staticmethod
def _should_use_litellm_proxy_by_default(
def should_use_litellm_proxy_by_default(
litellm_params: LiteLLM_Params | None = None,
):
"""

View file

@ -49,6 +49,7 @@ from litellm.types.utils import (
PROMPT_CARRYING_GUARDRAIL_FIELDS,
CallTypes,
CostBreakdown,
LlmProviders,
StandardLoggingGuardrailInformation,
StandardLoggingMCPToolCall,
StandardLoggingModelInformation,
@ -346,6 +347,8 @@ def _sl_attribution_fallback(
def _deployment_provider(deployment: DeploymentTypedDict) -> str | None:
litellm_params: Final = LiteLLM_Params.model_validate(deployment["litellm_params"])
if litellm.LiteLLMProxyChatConfig.should_use_litellm_proxy_by_default(litellm_params=litellm_params):
return LlmProviders.LITELLM_PROXY.value
declared: Final = declared_authenticating_provider(litellm_params.model, litellm_params.custom_llm_provider)
if declared is not None:
return declared

View file

@ -4078,6 +4078,33 @@ def test_get_logging_payload_inferred_provider_never_resolves_declared_authentic
assert resolution_attempts == []
@pytest.mark.parametrize(
"litellm_params",
[
{"model": "github_copilot/gpt-4o"},
{"model": "gpt-5", "custom_llm_provider": "chatgpt"},
{"model": "openai/gpt-4o-mini", "api_key": "sk-a"},
],
)
def test_get_logging_payload_inferred_provider_honours_global_litellm_proxy_override(
monkeypatch, litellm_params: dict[str, str]
):
def _router_init_stub(model, custom_llm_provider=None, *args, **kwargs):
return model.split("/", 1)[-1], custom_llm_provider or model.split("/", 1)[0], None, None
def _oauth_tripwire(model, *args, **kwargs):
raise AssertionError("get_llm_provider would run the OAuth device flow")
monkeypatch.setattr(litellm, "get_llm_provider", _router_init_stub)
llm_router = litellm.Router(model_list=[{"model_name": "proxied-group", "litellm_params": litellm_params}])
monkeypatch.setattr(litellm, "get_llm_provider", _oauth_tripwire)
monkeypatch.setattr(litellm, "use_litellm_proxy", True)
payload = _router_rejected_failure_payload("proxied-group", llm_router)
assert payload["custom_llm_provider"] == "litellm_proxy"
def test_get_logging_payload_router_rejected_request_for_unresolvable_deployment_leaves_provider_empty(
monkeypatch,
):