feat(litellm): preserve reasoning usage details - #31
Conversation
Pre-landing reviewGood instinct on this one — the cache-read forwarding is a real cost-accuracy win (see the "verified safe" note at the bottom). But there's a blocker, and the patch is only half-applied. 🔴 Blocking —
|
…e (0.9.1) Review fixes for the reasoning-usage passthrough: - provider.py: prompt_tokens_details / completion_tokens_details are pydantic EXTRAS on ChatUsage (extra=allow), not declared fields — attribute access on an absent extra raises AttributeError. Any streamed call whose usage frame omitted them (Anthropic-shaped or bare) crashed at the final frame, surfaced as litellm.APIConnectionError, and retry-on-connection clients re-paid for an already-settled completion. Read from model_extra instead; drop the redundant re-adds in _native_extras (extras were already copied wholesale). - provider.py: factor one shared _usage_dict used by BOTH _to_generic_chunk branches — the choice-less include_usage frame and a choices-bearing chunk carrying usage inline — so the two paths can never disagree about which detail fields survive. LiteLLM's chunk builder takes prompt_tokens_details unconditionally from the LAST usage-bearing chunk, so an asymmetric bare frame could null out detail delivered earlier. - proxy.py: _usage_to_responses builds spec-correct ResponseUsage — both detail blocks REQUIRED by openai.types.responses (typed clients crash on their absence), zero-defaulted, spec keys only (no leaked audio_tokens / prediction fields), non-dict garbage coerced to 0, Anthropic top-level cache_read_input_tokens mapped into cached_tokens. SSE loop merges usage frames instead of wholesale replacing (a later bare frame no longer wipes detail). - tests: absent-details regression (the crashing case), choices-bearing usage symmetry, Responses spec projection incl. garbage coercion, SSE detail passthrough + merge. 320 passed, 1 skipped; all three gateway usage shapes (anthropic / openai / bare) verified end-to-end through CustomStreamWrapper + stream_chunk_builder. - release 0.9.1 (pyproject + __init__) with CHANGELOG entry.
|
Pushed
The cache-read forwarding from the original PR is untouched — that part was verified correct and is the cost-accuracy win here. |
What changed
completion_tokens_details.reasoning_tokensthrough stream aggregation.Why
The gateway returned the correct reasoning breakdown, but LiteLLM's final streamed usage object retained only prompt/completion/total counts.
Validation
git diff --checkpassed.