diff --git a/litellm/proxy/hooks/proxy_track_cost_callback.py b/litellm/proxy/hooks/proxy_track_cost_callback.py index cbe7d1d66da..8c2caafe576 100644 --- a/litellm/proxy/hooks/proxy_track_cost_callback.py +++ b/litellm/proxy/hooks/proxy_track_cost_callback.py @@ -131,28 +131,18 @@ class _ProxyDBLogger(CustomLogger): existing_litellm_params = request_data.get("litellm_params", {}) - # Routes like /v1/responses, /v1/messages and the batch/file endpoints keep - # proxy-internal metadata (model_group, model_info, tags, retries) in - # ``litellm_metadata`` so the provider-facing ``metadata`` field stays clean. - # Collapse every bucket into one dict, then write it back to all of them so the - # bucket ``get_litellm_metadata_from_kwargs`` picks for the spend log carries the - # router attribution *and* this failure's status/error information. metadata_key, internal_metadata = get_or_create_metadata_bucket(request_data) merged_metadata = { **(existing_litellm_params.get("metadata") or {}), **(existing_litellm_params.get("litellm_metadata") or {}), **internal_metadata, } - # Identity comes from the authenticated key alone; a caller-supplied - # user_api_key* field in the request body must never attribute spend. spend_metadata = {key: value for key, value in merged_metadata.items() if not key.startswith("user_api_key")} spend_metadata.update(_metadata) request_data["litellm_params"]["proxy_server_request"] = ( request_data.get("proxy_server_request") or existing_litellm_params.get("proxy_server_request") or {} ) - # Failures that never reached the SDK carry no call_type, so the row lands - # without one and can't be attributed to the route the caller used. route_call_type = get_primary_call_type_for_route(request_route) if not request_data.get("call_type") and route_call_type is not None: request_data["call_type"] = route_call_type.value diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index 36676f366ba..2d960266c26 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -2254,10 +2254,6 @@ class ProxyLogging: ) input: Union[list, str, dict] = "" - # The Logging object above was built from the raw HTTP route, so its call_type - # is not a CallTypes value yet. The route is authoritative; the request body - # shape is only a fallback for routes outside the mapping (guessing from the - # body mislabels e.g. a /v1/responses request with a list input as embeddings). route_call_type = get_primary_call_type_for_route(route) normalized_call_type: str | None = route_call_type.value if route_call_type is not None else None if "messages" in request_data and isinstance(request_data["messages"], list): diff --git a/tests/proxy_unit_tests/test_proxy_utils.py b/tests/proxy_unit_tests/test_proxy_utils.py index 47ba6b8dcf1..404c08621ed 100644 --- a/tests/proxy_unit_tests/test_proxy_utils.py +++ b/tests/proxy_unit_tests/test_proxy_utils.py @@ -2482,8 +2482,6 @@ async def test_post_call_failure_hook_auth_error_llm_api_route(): "/v1/embeddings", "aembedding", ), - # #35068: a Responses request also carries "input"; the route decides the - # call type, so it must not be attributed to embeddings ( {"model": "bad-model", "input": ["hello"]}, "/v1/responses",