litellm/litellm/proxy/db
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
..
db_transaction_queue fix(proxy): bound spend-log cleanup delete transactions to the statement timeout (#43279) 2026-10-10 11:30:20 -07:00
autorouter_session_rollup.py feat(ui): add auto-router usage and savings table (#45152) 2026-10-07 15:04:07 -07:00
base_client.py refactor(typing): clear 1143 basedpyright Any errors across 273 files (#46574) 2026-10-15 21:08:47 +00:00
baseline_accounting.py feat(spend_logs): configure which metadata fields are stored in LiteLLM_SpendLogs (#44659) 2026-10-08 14:51:44 -07:00
budget_window_spend_writer.py refactor(typing): clear 1143 basedpyright Any errors across 273 files (#46574) 2026-10-15 21:08:47 +00:00
check_migration.py fix(proxy): kill the whole prisma process group when a boot migration command times out (#39509) 2026-09-08 10:06:53 -07:00
create_views.py fix(otel): name postgres service spans by operation and table (#44240) 2026-10-03 09:20:28 -07:00
daily_spend_bulk_upsert.py fix(proxy): estimate auto-router baseline costs from durable cache history 2026-09-19 12:44:47 -07:00
db_lookup_gate.py fix(proxy): fail parked DB lookups at a deadline and flip readiness while they stall (#42654) 2026-09-24 10:09:49 -05:00
db_span.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
db_spend_update_writer.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
db_url_settings.py fix(proxy): sign RDS IAM tokens for the database's own region (#44782) 2026-10-09 15:41:07 -07:00
dynamo_db.py chore(lint): strip inert type: ignore comments and zero LIT009, LIT010, LIT011 headroom 2026-08-05 02:37:24 -07:00
exception_handler.py fix(proxy): bound daily spend rollup row-lock waits with lock_timeout and requeue 55P03 (#44450) 2026-10-06 17:38:55 -05:00
gateway_request_tracking.py feat(proxy): track failed requests by HTTP status and caller (#45244) 2026-10-09 14:27:56 -07:00
health_check_latest.py refactor(typing): clear 1143 basedpyright Any errors across 273 files (#46574) 2026-10-15 21:08:47 +00:00
log_db_metrics.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
master_key_migration.py fix(search_tools): encrypt search tool litellm_params at rest (#43631) 2026-10-02 22:53:18 -07:00
model_insights_tasks.py refactor(types): replace Any with proven types in 137 files (#44478) 2026-10-05 11:01:45 -07:00
model_usage_rollup.py fix(responses): bill a background response once, on the first read or poll that sees it finished (#45703) 2026-10-15 11:00:14 -07:00
pgbouncer.py feat(proxy): offload spend tracking to a pod-local collector sidecar (#40545) 2026-09-10 17:14:13 -07:00
prisma_client.py refactor(typing): clear 1143 basedpyright Any errors across 273 files (#46574) 2026-10-15 21:08:47 +00:00
prisma_query_span.py feat(lens): isolate ingestion and investigations in a Rust service (#45148) 2026-10-07 17:18:58 -07:00
proxy_worker_heartbeat.py refactor(typing): clear 1143 basedpyright Any errors across 273 files (#46574) 2026-10-15 21:08:47 +00:00
query_engine_reaper.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
request_error_tracking.py feat(proxy): track failed requests by HTTP status and caller (#45244) 2026-10-09 14:27:56 -07:00
rollup_lock_timeout.py fix(proxy): bound daily spend rollup row-lock waits with lock_timeout and requeue 55P03 (#44450) 2026-10-06 17:38:55 -05:00
routing_prisma_wrapper.py refactor(typing): clear 1143 basedpyright Any errors across 273 files (#46574) 2026-10-15 21:08:47 +00:00
shadow_eval_funnel.py fix(otel): name postgres service spans by operation and table (#44240) 2026-10-03 09:20:28 -07:00
spend_counter_reseed.py fix(otel): nest cache spans under their operation and name service spans by purpose (#44150) 2026-10-03 09:20:27 -07:00
spend_log_batching.py fix(spend): bound each spend-log write statement by row count as well as bytes (#37758) 2026-08-21 09:49:51 -07:00
spend_log_tool_index.py fix(proxy): bound daily spend rollup row-lock waits with lock_timeout and requeue 55P03 (#44450) 2026-10-06 17:38:55 -05:00
token_auth.py fix(proxy): sign RDS IAM tokens for the database's own region (#44782) 2026-10-09 15:41:07 -07:00
tool_registry_writer.py refactor(typing): clear 1143 basedpyright Any errors across 273 files (#46574) 2026-10-15 21:08:47 +00:00