litellm/tests/unit/proxy/spend_tracking
Kerry Lu 6c971b7412
fix(proxy): attribute retry attempt spend rows to their deployment and keep them out of daily request counts (#47658)
* fix(proxy): attribute retry attempt spend rows to their own deployment and keep them out of daily request counts

Each <request_id>-attempt-<n> row now carries the model, provider, api_base and model group of the deployment that billed it (looked up by model_info.id through the proxy router, injected as deployment_lookup) instead of copying the final row's, and is stamped internal_call_origin=billed_retry_attempt so the daily spend tables keep its spend and tokens while counting zero api_requests and failed_requests for it

* fix(proxy): declare DeploymentLookup as a TypeAlias and leave the test file's untouched lines as they were

* fix(proxy): mark attempt rows with billed_retry_attempt instead of internal_call_origin so model usage keeps their spend

Bugbot: an internal_call_origin stamp made build_model_usage_transaction drop the attempt rows from LiteLLM_DailyModelUsage. The rows now carry their own SpendLogsMetadata flag, which only the daily request counters read

* fix(proxy): read the billed_retry_attempt flag through a typed helper so the basedpyright gate holds

* fix(proxy): keep the typed litellm_params local in _deployment_provider so the basedpyright gate holds

* fix(proxy): annotate the validated litellm_params as LiteLLM_Params in _deployment_provider

* fix(proxy): keep billed retry attempts out of daily request errors and strip the flag from caller metadata

Bugbot: _record_request_error counted every attempt row as a caller failure in LiteLLM_DailyRequestErrors. Veria: a caller could send metadata.billed_retry_attempt to zero its own request counts, so the key joins the untrusted metadata fields the proxy strips on the way in

* fix(proxy): stamp billed_retry_attempt explicitly in the spend log metadata so the basedpyright gate holds

---------

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
(cherry picked from commit 5dce13d2c2)
2026-10-27 19:57:39 -07:00
..
__init__.py ci: move tests/proxy_unit_tests to tests/unit/proxy and run the proxy-db shards from litellm-tests (#42903) 2026-09-24 22:59:11 +00:00
test_background_interaction_settlement.py feat(interactions): durable cross-pod settlement for background interaction billing (#41955) 2026-10-02 21:08:38 -07:00
test_baseline_accounting.py fix(router): preserve native baseline identity and accounting (#44960) 2026-10-07 11:00:31 -07:00
test_budget_reservation.py refactor(types): replace Any with proven types in 137 files (#44478) 2026-10-05 11:01:45 -07:00
test_budget_reservation_redis_failure.py test(proxy): move middleware, spend_tracking, pass_through, common_utils and root proxy tests into tests/unit/proxy (#44015) 2026-10-01 18:23:31 +00:00
test_carried_budget_state.py test(proxy): move middleware, spend_tracking, pass_through, common_utils and root proxy tests into tests/unit/proxy (#44015) 2026-10-01 18:23:31 +00:00
test_cloudzero_endpoints.py test(proxy): move middleware, spend_tracking, pass_through, common_utils and root proxy tests into tests/unit/proxy (#44015) 2026-10-01 18:23:31 +00:00
test_compression_savings.py test(proxy): move middleware, spend_tracking, pass_through, common_utils and root proxy tests into tests/unit/proxy (#44015) 2026-10-01 18:23:31 +00:00
test_input_tokens.py test(proxy): move middleware, spend_tracking, pass_through, common_utils and root proxy tests into tests/unit/proxy (#44015) 2026-10-01 18:23:31 +00:00
test_key_metadata_recovery.py fix: cap cold MCP schema workers at usable CPUs and deflake wall-clock unit tests (#45791) 2026-10-15 00:47:59 -07:00
test_ptu_feature_flag.py feat(proxy): split Azure PTU deployments across teams with per-team PTU ceilings and PTU-hour reporting (#43043) 2026-10-15 18:44:30 +00:00
test_ptu_flat_cost_rollup.py feat(proxy): split Azure PTU deployments across teams with per-team PTU ceilings and PTU-hour reporting (#43043) 2026-10-15 18:44:30 +00:00
test_savings.py test(proxy): move middleware, spend_tracking, pass_through, common_utils and root proxy tests into tests/unit/proxy (#44015) 2026-10-01 18:23:31 +00:00
test_search_api_logging.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
test_spend_capture_rate.py test(proxy): move middleware, spend_tracking, pass_through, common_utils and root proxy tests into tests/unit/proxy (#44015) 2026-10-01 18:23:31 +00:00
test_spend_counter_batch.py test(proxy): move middleware, spend_tracking, pass_through, common_utils and root proxy tests into tests/unit/proxy (#44015) 2026-10-01 18:23:31 +00:00
test_spend_event.py test(proxy): move middleware, spend_tracking, pass_through, common_utils and root proxy tests into tests/unit/proxy (#44015) 2026-10-01 18:23:31 +00:00
test_spend_event_producer.py test(proxy): move middleware, spend_tracking, pass_through, common_utils and root proxy tests into tests/unit/proxy (#44015) 2026-10-01 18:23:31 +00:00
test_spend_log_error_logger.py test(proxy): move middleware, spend_tracking, pass_through, common_utils and root proxy tests into tests/unit/proxy (#44015) 2026-10-01 18:23:31 +00:00
test_spend_management_endpoints.py fix(proxy): attribute retry attempt spend rows to their deployment and keep them out of daily request counts (#47658) 2026-10-27 19:57:39 -07:00
test_spend_query_optimization.py fix(proxy): share ownership permissions for spend logs and traces (#44239) 2026-10-03 01:38:54 +00:00
test_spend_tracking_utils.py fix(proxy): honor disable_end_user_cost_tracking in spend logs and end-user tables (#40945) 2026-10-15 21:48:20 +00:00