litellm/litellm
Ambuj Upadhyay cb70bc560e
fix(streaming): dict-usage arm drops prompt_tokens_details/completion_tokens_details its sibling arms preserve (#36678)
* fix(streaming): dict-usage arm no longer drops token detail fields

In _dispatch_provider_chunk's openai/azure else-branch, a plain-dict
usage was rebuilt into litellm.Usage from only prompt_tokens /
completion_tokens / total_tokens. prompt_tokens_details (cached_tokens),
completion_tokens_details (reasoning_tokens) and cache token counts were
silently dropped — while both sibling arms (Usage passthrough, BaseModel
via Usage(**model_dump())) preserve them.

Every in-repo chunk producer currently normalizes usage to
Usage/BaseModel before this point, so the dict arm is reachable today
only via chunks litellm did not construct (e.g. a custom
streaming_decoder feeding CustomStreamWrapper). When it does fire on a
usage-only final chunk (stream_options.include_usage), the stripped
Usage is exactly what the stream consumer receives — the early-return
path has no later aggregation to repair it.

Fix: pass the full dict through Usage(**usage_dict). Usage.__init__
coerces nested detail dicts into their wrapper types and tolerates
extra keys. Side effect: a legitimate 0 count is no longer coerced to
None by the old 'or None' expressions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: drop explanatory source comment per repo comment policy

Rationale lives in the PR body and the regression tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(streaming): type the dict-usage unpack for the basedpyright gate

Usage(**response_obj["usage"]) unpacks a dict whose value type pyright
cannot see, and the delta gate reports that once per typed constructor
parameter: five, against the three .get() calls the line replaced. Moving
the unpack behind _usage_from_payload keeps the same Usage(**payload)
call and is reported once, at the call site, so the rule count ends below
its merge base

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-10-27 15:21:11 -07:00
..
_v2 feat(cache): select Rust caching through explicit cache objects (#43601) 2026-09-29 00:01:44 +00:00
a2a_protocol refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
anthropic_interface fix(anthropic): make opening usage estimates opt-in (#48633) 2026-10-27 12:57:21 -07:00
assistants refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
batch_completion
batches fix(batches): apply the Vertex regional endpoint uplift to batch cost (#47466) 2026-10-20 01:51:51 +00:00
caching refactor(anthropic): rename llms/anthropic/pass_through to llms/anthropic/messages (#48510) 2026-10-27 10:08:25 -07:00
chat_completions refactor(rust-bridge): detect Python-only features in the catalog instead of Rust declines (#46714) 2026-10-20 15:06:25 -07:00
completion_extras fix(router)!: stop a chat-mode Mantle deployment from rewriting the shared Responses routing row (#46263) 2026-10-17 21:39:14 +00:00
compression refactor(llms): expose public names for private provider helpers (#45037) 2026-10-07 08:49:25 -07:00
containers feat(openai)!: honor per-deployment workload identity on non-chat routes (#39966) 2026-10-16 22:25:15 +00:00
decisions fix(decisions): honor base_url alias for custom backends (#48505) 2026-10-26 18:46:43 -07:00
embeddings refactor(rust-bridge): decide native routing in the catalog, drop the bypass predicates (#46750) 2026-10-20 15:06:24 -07:00
endpoints/speech/speech_to_completion_bridge feat(vertex-ai)!: support gemini 3.1 flash tts (#31915) 2026-10-21 04:18:42 +00:00
evals
experimental_mcp_client refactor(mcp): drop the experimental label from the MCP server and client paths (#48513) 2026-10-27 17:47:50 +00:00
extraction feat(extraction): add /v1/extraction with Cloudflare Clairic support (#47473) 2026-10-20 15:51:45 -07:00
files refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
fine_tuning fix(managed_files): send provider file ids when creating a fine-tuning job from managed files (#46552) 2026-10-19 14:40:15 -07:00
google_genai fix(langfuse_otel)!: send the completion start time (#45597) 2026-10-20 13:52:26 +00:00
harness refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
images fix(chatgpt): forward client credentials for image generation (#48522) 2026-10-26 19:37:14 -07:00
integrations fix(security)!: build proxy-only failure logs from an allowlist and drop caller guardrail info (#48599) 2026-10-27 12:40:59 -07:00
interactions fix(security)!: build proxy-only failure logs from an allowlist and drop caller guardrail info (#48599) 2026-10-27 12:40:59 -07:00
litellm_core_utils fix(streaming): dict-usage arm drops prompt_tokens_details/completion_tokens_details its sibling arms preserve (#36678) 2026-10-27 15:21:11 -07:00
llms fix(aiohttp_transport): close an owned aiohttp session when its transport is collected (#48650) 2026-10-27 20:33:03 +00:00
mcp_client refactor(mcp): drop the experimental label from the MCP server and client paths (#48513) 2026-10-27 17:47:50 +00:00
messages refactor(anthropic): rename llms/anthropic/pass_through to llms/anthropic/messages (#48510) 2026-10-27 10:08:25 -07:00
models refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
ocr refactor(rust-bridge): decide native routing in the catalog, drop the bypass predicates (#46750) 2026-10-20 15:06:24 -07:00
passthrough fix(bedrock)!: apply the deployment guardrailConfig on /bedrock pass-through routes (#47429) 2026-10-20 14:48:19 -07:00
proxy fix(proxy): keep every startup line JSON when json_logs is on (#47035) 2026-10-27 14:49:07 -07:00
proxy_auth refactor(types): replace Any with real types across 29 more backend files 2026-09-08 10:14:07 +00:00
rag refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
realtime_api refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
repositories fix(proxy): reconcile team member total_spend with current cycle spend (#48260) 2026-10-24 17:57:09 -07:00
rerank_api refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
responses feat(bedrock): price native guardrailConfig trace usage into spend and x-litellm-response-cost (#48278) 2026-10-27 12:10:45 -07:00
router_strategy feat(router): respect caller output budgets in complexity routing (#48632) 2026-10-27 14:04:30 -07:00
router_utils fix(router): keep a lone deployment warm under router allowed_fails unless the policy names the exception (#48644) 2026-10-27 15:12:53 -07:00
rust_bridge refactor(anthropic): rename llms/anthropic/pass_through to llms/anthropic/messages (#48510) 2026-10-27 10:08:25 -07:00
sandbox refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
search fix(search): price Tavily advanced and Linkup deep searches at their own cost map entries (#47411) 2026-10-19 23:32:31 -07:00
secret_managers refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
skills refactor(typing): clear 1143 basedpyright Any errors across 273 files (#46574) 2026-10-15 21:08:47 +00:00
systemone fix(decisions): log every request field the caller sent on /v1/systemone and /v1/decisions (#47183) 2026-10-19 14:19:14 -07:00
telemetry refactor: clean up fresh tech debt in per-user Copilot auth, Ternary FOCUS export and telemetry (#45769) 2026-10-15 04:29:27 +00:00
text_completions fix(completions): omit stream usage unless requested (#47953) (#48052) 2026-10-23 19:36:20 +00:00
tracing fix(proxy): cooldown errors carry 429, Sentry starts at boot without request bodies, tracing failures log at ERROR, exporter counters exported (#46344) 2026-10-16 00:53:52 +00:00
types fix(langfuse_otel)!: derive trace-level name, input, output and tags on traces litellm starts (#42705) 2026-10-27 10:34:55 -07:00
vector_store_files fix(secret_managers)!: resolve oidc/file and oidc/env refs in admin-configured api_key per request (#47341) 2026-10-20 01:43:59 +00:00
vector_stores refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
videos feat(dashscope): add Wan 3.0, Wan 2.7 and HappyHorse video generation via /v1/videos (#43706) 2026-10-14 10:10:07 -07:00
__init__.py fix(anthropic): make opening usage estimates opt-in (#48633) 2026-10-27 12:57:21 -07:00
_internal_context.py fix(responses): log and bill every round of non-stream MCP auto-execute (#43667) 2026-10-16 17:37:33 +00:00
_lazy_imports.py refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
_lazy_imports_registry.py refactor(anthropic): rename llms/anthropic/pass_through to llms/anthropic/messages (#48510) 2026-10-27 10:08:25 -07:00
_logging.py fix(proxy): keep every startup line JSON when json_logs is on (#47035) 2026-10-27 14:49:07 -07:00
_process_defaults.py perf(cli): start lite without initializing the litellm SDK (#46803) 2026-10-17 04:53:32 +00:00
_redis.py refactor(typing): clear 1143 basedpyright Any errors across 273 files (#46574) 2026-10-15 21:08:47 +00:00
_redis_credential_provider.py refactor: expose core private helpers under public names (#44871) 2026-10-07 00:05:27 +00:00
_service_logger.py fix(caching): report Redis circuit-breaker metrics through the Prometheus services logger (#46484) 2026-10-14 14:29:54 -07:00
_uuid.py fix: support Python 3.15 (#48359) 2026-10-26 16:00:11 +00:00
_version.py feat(sdk): build core from an independent packaging manifest (#44340) 2026-10-08 18:40:14 -07:00
anthropic_beta_headers_config.json fix(azure_ai): forward the thinking-binding-controls beta header to Foundry (#48033) 2026-10-23 16:34:55 -07:00
anthropic_beta_headers_manager.py refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
blog_posts.json
budget_manager.py refactor(typing): clear 1143 basedpyright Any errors across 273 files (#46574) 2026-10-15 21:08:47 +00:00
constants.py fix(anthropic): raise DEFAULT_ANTHROPIC_CHAT_MAX_TOKENS from 4096 to 128000 (#48502) 2026-10-26 18:54:50 -07:00
cost.json
cost_calculator.py refactor(mcp): drop the experimental label from the MCP server and client paths (#48513) 2026-10-27 17:47:50 +00:00
exceptions.py refactor(typing): clear 1181 basedpyright Any errors across 431 files (#47789) 2026-10-24 11:31:09 -07:00
main.py fix: correct Palm 'decommissioned' typo in error message (#46171) 2026-10-27 11:55:16 -07:00
model_prices_and_context_window_backup.json fix(cost-map): add 2026-11-06 deprecation_date to two together_ai rows (#48651) 2026-10-27 20:24:56 +00:00
policy_templates_backup.json fix(packaging): keep wheel paths under Windows MAX_PATH for Store Python (#43903) 2026-09-30 22:20:36 +00:00
provider_endpoints_support_backup.json feat: generate provider_endpoints_support.json from the cost map (#48619) 2026-10-27 12:06:55 -07:00
py.typed
router.py feat(router): respect caller output budgets in complexity routing (#48632) 2026-10-27 14:04:30 -07:00
scheduler.py fix(scheduler): remove a request's queue entry once it stops waiting (#43061) 2026-10-07 17:34:38 -07:00
setup_wizard.py fix(model_prices): correct Claude Sonnet 5.5 capabilities and provider keys (#43587) 2026-09-28 19:12:31 +00:00
timeout.py
tool_loop.py fix(responses bridge): round-trip tool_search_call and tool_search_output items between turns (#46444) 2026-10-14 21:40:14 -07:00
utils.py refactor(anthropic): rename llms/anthropic/pass_through to llms/anthropic/messages (#48510) 2026-10-27 10:08:25 -07:00