mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
fix(logging): resolve model_map_value for proxy custom pricing (#31940)
* fix(logging): resolve model_map_value for proxy custom pricing Use deployment model for standard logging cost-map lookup when the router overrides response.model to a group alias, and flush stdout when printing the payload. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(logging): add comment and test for deployment fallback in standard logging payload Address review: explain why the metadata["deployment"] fallback is unconditional, and add a test covering the get_standard_logging_object_payload code path. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(test): update model_map_key assertion for provider-prefixed keys Co-authored-by: Cursor <cursoragent@cursor.com> * fix(logging): scope base_model to model param only under custom_pricing Passing model=base_model unconditionally caused _get_provider_for_cost_calc to infer and prepend a provider prefix on all non-custom-pricing calls, changing model_map_key for existing deployments. Scope it to custom_pricing=True where the fix is actually needed. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Mateo Wang <277851410+mateo-berri@users.noreply.github.com>
This commit is contained in:
parent
a16d9c6f9e
commit
8d0dc9294d
2 changed files with 75 additions and 2 deletions
|
|
@ -4722,7 +4722,7 @@ class StandardLoggingPayloadSetup:
|
|||
api_base: Optional[str] = None,
|
||||
) -> StandardLoggingModelInformation:
|
||||
model_cost_name = _select_model_name_for_cost_calc(
|
||||
model=None,
|
||||
model=base_model if custom_pricing else None,
|
||||
completion_response=init_response_obj, # type: ignore
|
||||
base_model=base_model,
|
||||
custom_pricing=custom_pricing,
|
||||
|
|
@ -5268,6 +5268,11 @@ def get_standard_logging_object_payload(
|
|||
|
||||
## Get model cost information ##
|
||||
base_model = _get_base_model_from_metadata(model_call_details=kwargs)
|
||||
# The router overrides completion_response.model to the model-group alias before
|
||||
# this payload is built, so cost-map lookup via that alias always misses.
|
||||
# Fall back to the actual deployment model set by the router in metadata.
|
||||
if base_model is None:
|
||||
base_model = metadata.get("deployment")
|
||||
custom_pricing = use_custom_pricing_for_model(litellm_params=litellm_params)
|
||||
raw_response_cost = kwargs.get("response_cost")
|
||||
response_cost: float = raw_response_cost or 0.0
|
||||
|
|
@ -5389,7 +5394,7 @@ def get_standard_logging_object_payload(
|
|||
|
||||
def emit_standard_logging_payload(payload: StandardLoggingPayload):
|
||||
if os.getenv("LITELLM_PRINT_STANDARD_LOGGING_PAYLOAD"):
|
||||
print(json.dumps(payload, indent=4)) # noqa: T201
|
||||
print(json.dumps(payload, indent=4), flush=True) # noqa: T201
|
||||
|
||||
|
||||
def get_standard_logging_metadata(
|
||||
|
|
|
|||
|
|
@ -335,6 +335,74 @@ def test_get_model_cost_information():
|
|||
)
|
||||
|
||||
|
||||
def test_get_model_cost_information_custom_pricing_uses_base_model():
|
||||
result = StandardLoggingPayloadSetup.get_model_cost_information(
|
||||
base_model="bedrock/invoke/global.anthropic.claude-opus-4-6-v1",
|
||||
custom_pricing=True,
|
||||
custom_llm_provider="bedrock",
|
||||
init_response_obj={"model": "invoke_test_claude"},
|
||||
)
|
||||
assert result["model_map_value"] is not None
|
||||
assert result["model_map_key"] != "invoke_test_claude"
|
||||
|
||||
|
||||
def test_standard_logging_payload_uses_deployment_when_no_base_model():
|
||||
"""metadata["deployment"] is used for cost-map lookup when base_model is not set."""
|
||||
from datetime import datetime
|
||||
|
||||
from litellm.litellm_core_utils.litellm_logging import (
|
||||
Logging,
|
||||
get_standard_logging_object_payload,
|
||||
)
|
||||
|
||||
logging_obj = Logging(
|
||||
model="invoke_test_claude",
|
||||
messages=[{"role": "user", "content": "hi"}],
|
||||
stream=False,
|
||||
call_type="completion",
|
||||
start_time=datetime.now(),
|
||||
litellm_call_id="test-deploy-fallback",
|
||||
function_id="test-fn",
|
||||
)
|
||||
|
||||
kwargs = {
|
||||
"model": "invoke_test_claude",
|
||||
"messages": [{"role": "user", "content": "hi"}],
|
||||
"custom_llm_provider": "bedrock",
|
||||
"litellm_params": {
|
||||
"metadata": {
|
||||
"deployment": "bedrock/invoke/global.anthropic.claude-opus-4-6-v1",
|
||||
},
|
||||
},
|
||||
}
|
||||
mock_response = {
|
||||
"id": "chatcmpl-deploy-test",
|
||||
"object": "chat.completion",
|
||||
"model": "invoke_test_claude",
|
||||
"usage": {"prompt_tokens": 5, "completion_tokens": 10, "total_tokens": 15},
|
||||
"choices": [
|
||||
{
|
||||
"index": 0,
|
||||
"message": {"role": "assistant", "content": "hello"},
|
||||
"finish_reason": "stop",
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
payload = get_standard_logging_object_payload(
|
||||
kwargs=kwargs,
|
||||
init_response_obj=mock_response,
|
||||
start_time=datetime.now(),
|
||||
end_time=datetime.now(),
|
||||
logging_obj=logging_obj,
|
||||
status="success",
|
||||
)
|
||||
|
||||
assert payload is not None
|
||||
assert payload["model_map_information"]["model_map_value"] is not None
|
||||
assert payload["model_map_information"]["model_map_key"] != "invoke_test_claude"
|
||||
|
||||
|
||||
def test_get_hidden_params():
|
||||
"""Test get_hidden_params with different inputs"""
|
||||
# Test with None
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue