Fix credential name tag injection by moving to Router level

The previous approach tried to inject litellm_credential_name as a tag
in get_standard_logging_object_payload, but the credential name was never
available in litellm_params because the Logging object is created by the
proxy BEFORE the Router selects a deployment. The credential name only
exists in the deployment's litellm_params, which is resolved later.

This fix injects the credential name as a tag in
Router._update_kwargs_with_deployment(), right alongside the existing
deployment-level tags mechanism. This ensures the credential name flows
through the normal metadata.tags pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
yuneng-jiang 2026-02-20 17:16:36 -08:00
parent 8c5d48348c
commit e08989dd8f
6 changed files with 87 additions and 214 deletions

View file

@ -32,7 +32,6 @@ _OPTIONAL_KWARGS_KEYS = frozenset({
"aws_bedrock_runtime_endpoint",
"tpm",
"rpm",
"litellm_credential_name",
})

View file

@ -5076,11 +5076,6 @@ def get_standard_logging_object_payload(
litellm_params=litellm_params, proxy_server_request=proxy_server_request
)
# Inject credential name as tag for spend tracking
credential_name = litellm_params.get("litellm_credential_name")
if credential_name and credential_name not in request_tags:
request_tags.append(credential_name)
# cleanup timestamps
(
start_time_float,

View file

@ -2019,6 +2019,16 @@ class Router:
merged_tags.append(tag)
kwargs[metadata_variable_name]["tags"] = merged_tags
## CREDENTIAL NAME AS TAG
credential_name = deployment.get("litellm_params", {}).get(
"litellm_credential_name"
)
if credential_name:
existing_tags = kwargs[metadata_variable_name].get("tags") or []
if credential_name not in existing_tags:
existing_tags.append(credential_name)
kwargs[metadata_variable_name]["tags"] = existing_tags
kwargs["model_info"] = model_info
kwargs["timeout"] = self._get_timeout(

View file

@ -126,12 +126,3 @@ class TestGetLitellmParamsExplicitFields:
result = get_litellm_params(no_log=True)
assert result["no-log"] is True
def test_litellm_credential_name_captured(self):
"""litellm_credential_name should be captured via _OPTIONAL_KWARGS_KEYS."""
result = get_litellm_params(litellm_credential_name="my-credential")
assert result["litellm_credential_name"] == "my-credential"
def test_litellm_credential_name_absent(self):
"""When litellm_credential_name is not passed, it should not appear."""
result = get_litellm_params()
assert "litellm_credential_name" not in result

View file

@ -1357,202 +1357,3 @@ def test_get_error_information_error_code_priority():
assert result["error_class"] == "NoCodeException"
def test_credential_name_injected_as_tag():
"""
Test that litellm_credential_name from litellm_params is injected into
request_tags in the standard logging payload.
In the real flow, litellm_credential_name is captured into litellm_params
by get_litellm_params() via _OPTIONAL_KWARGS_KEYS.
"""
from litellm.litellm_core_utils.litellm_logging import (
get_standard_logging_object_payload,
Logging,
)
from datetime import datetime
logging_obj = Logging(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
stream=False,
call_type="completion",
start_time=datetime.now(),
litellm_call_id="test-cred-tag",
function_id="test-function",
)
mock_response = {
"id": "chatcmpl-123",
"object": "chat.completion",
"model": "gpt-4o",
"usage": {
"prompt_tokens": 10,
"completion_tokens": 20,
"total_tokens": 30,
},
"choices": [
{
"index": 0,
"message": {"role": "assistant", "content": "Hi!"},
"finish_reason": "stop",
}
],
}
kwargs = {
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}],
"response_cost": 0.001,
"custom_llm_provider": "openai",
"litellm_params": {
"litellm_credential_name": "my-openai-credential",
},
}
start_time = datetime.now()
end_time = datetime.now()
payload = get_standard_logging_object_payload(
kwargs=kwargs,
init_response_obj=mock_response,
start_time=start_time,
end_time=end_time,
logging_obj=logging_obj,
status="success",
)
assert payload is not None
assert "my-openai-credential" in payload["request_tags"]
def test_credential_name_not_injected_when_absent():
"""
Test that when litellm_credential_name is not in litellm_params,
request_tags are unchanged.
"""
from litellm.litellm_core_utils.litellm_logging import (
get_standard_logging_object_payload,
Logging,
)
from datetime import datetime
logging_obj = Logging(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
stream=False,
call_type="completion",
start_time=datetime.now(),
litellm_call_id="test-no-cred",
function_id="test-function",
)
mock_response = {
"id": "chatcmpl-456",
"object": "chat.completion",
"model": "gpt-4o",
"usage": {
"prompt_tokens": 10,
"completion_tokens": 20,
"total_tokens": 30,
},
"choices": [
{
"index": 0,
"message": {"role": "assistant", "content": "Hi!"},
"finish_reason": "stop",
}
],
}
kwargs = {
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}],
"response_cost": 0.001,
"custom_llm_provider": "openai",
}
start_time = datetime.now()
end_time = datetime.now()
payload = get_standard_logging_object_payload(
kwargs=kwargs,
init_response_obj=mock_response,
start_time=start_time,
end_time=end_time,
logging_obj=logging_obj,
status="success",
)
assert payload is not None
# No credential-related tags should be present
for tag in payload["request_tags"]:
assert tag.startswith("User-Agent:")
def test_credential_name_not_duplicated_in_tags():
"""
Test that if the credential name already exists in the tags list,
it is not duplicated.
"""
from litellm.litellm_core_utils.litellm_logging import (
get_standard_logging_object_payload,
Logging,
)
from datetime import datetime
logging_obj = Logging(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
stream=False,
call_type="completion",
start_time=datetime.now(),
litellm_call_id="test-dup-cred",
function_id="test-function",
)
mock_response = {
"id": "chatcmpl-789",
"object": "chat.completion",
"model": "gpt-4o",
"usage": {
"prompt_tokens": 10,
"completion_tokens": 20,
"total_tokens": 30,
},
"choices": [
{
"index": 0,
"message": {"role": "assistant", "content": "Hi!"},
"finish_reason": "stop",
}
],
}
kwargs = {
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}],
"response_cost": 0.001,
"custom_llm_provider": "openai",
"litellm_params": {
"litellm_credential_name": "my-openai-credential",
"metadata": {"tags": ["my-openai-credential", "other-tag"]},
},
}
start_time = datetime.now()
end_time = datetime.now()
payload = get_standard_logging_object_payload(
kwargs=kwargs,
init_response_obj=mock_response,
start_time=start_time,
end_time=end_time,
logging_obj=logging_obj,
status="success",
)
assert payload is not None
credential_count = payload["request_tags"].count("my-openai-credential")
assert credential_count == 1, (
f"Expected credential name once, found {credential_count} times"
)

View file

@ -2186,3 +2186,80 @@ def test_update_kwargs_with_deployment_merge_tools_request_overrides_tool_choice
# Request tool_choice should be preserved (merged tools still applied)
assert kwargs["tool_choice"] == "none"
def test_credential_name_injected_as_tag():
"""
Test that litellm_credential_name from deployment litellm_params
is injected as a tag into metadata during _update_kwargs_with_deployment.
"""
router = litellm.Router(
model_list=[
{
"model_name": "xai-model",
"litellm_params": {
"model": "xai/grok-4-1-fast",
"litellm_credential_name": "xAI",
},
}
],
)
kwargs: dict = {"metadata": {"tags": ["A.101"]}}
deployment = router.get_deployment_by_model_group_name(
model_group_name="xai-model"
)
router._update_kwargs_with_deployment(deployment=deployment, kwargs=kwargs)
assert "xAI" in kwargs["metadata"]["tags"]
assert "A.101" in kwargs["metadata"]["tags"]
def test_credential_name_not_duplicated_in_tags():
"""
Test that if the credential name already exists in the tags list,
it is not duplicated.
"""
router = litellm.Router(
model_list=[
{
"model_name": "xai-model",
"litellm_params": {
"model": "xai/grok-4-1-fast",
"litellm_credential_name": "xAI",
},
}
],
)
kwargs: dict = {"metadata": {"tags": ["xAI", "A.101"]}}
deployment = router.get_deployment_by_model_group_name(
model_group_name="xai-model"
)
router._update_kwargs_with_deployment(deployment=deployment, kwargs=kwargs)
assert kwargs["metadata"]["tags"].count("xAI") == 1
def test_credential_name_not_injected_when_absent():
"""
Test that when no litellm_credential_name is set, tags are unchanged.
"""
router = litellm.Router(
model_list=[
{
"model_name": "gpt-model",
"litellm_params": {
"model": "gpt-4o",
},
}
],
)
kwargs: dict = {"metadata": {"tags": ["A.101"]}}
deployment = router.get_deployment_by_model_group_name(
model_group_name="gpt-model"
)
router._update_kwargs_with_deployment(deployment=deployment, kwargs=kwargs)
assert kwargs["metadata"]["tags"] == ["A.101"]