fix(litellm): bill codex/ChatGPT OAuth path at cache-read rate#758
Closed
PurpleCHOIms wants to merge 1 commit into
Closed
fix(litellm): bill codex/ChatGPT OAuth path at cache-read rate#758PurpleCHOIms wants to merge 1 commit into
PurpleCHOIms wants to merge 1 commit into
Conversation
The codex_chatgpt handler dropped the Responses-API prompt-cache hit count (usage.input_tokens_details.cached_tokens), so auth/gpt-* calls were cost- calculated at full input rate — inflating measured spend (the ChatGPT/Codex OAuth path showed 0% cache while Claude's auth path showed 88-90%). - codex_chatgpt_handler: surface cached_tokens as OpenAI-style prompt_tokens_details.cached_tokens in both the completion and streaming final-usage paths (mirrors claude_code_handler surfacing cache_read). - litellm_dynamic_config: add cache_read_input_token_cost to the auth/gpt* shadow pricing (GPT-5 gen = input * 0.1, verified against OpenAI pricing: gpt-5.5 $5 -> $0.50/1M cached, gpt-5.4 $2.50 -> $0.25/1M). LiteLLM only discounts cached tokens when this cost is present. - test: assert cached_tokens surfaced (present/absent/zero) + hermetic loader. Absent field -> 0 -> no-op, so this is safe if a backend omits cache detail. Not yet verified against a live codex payload (local refresh token rotated); verify post-deploy via LiteLLM_SpendLogs cache_read > 0 for auth/gpt rows. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Member
Author
|
검증 결과 닫습니다. 2026-07-05 fresh codex login + 직접 /responses 호출로 확인: 동일 7,556-tok 프롬프트 3회 + prompt_cache_key까지 써도 cached_tokens=0. 근본 원인은 우리 코드가 아니라 ChatGPT-구독 백엔드(chatgpt.com/backend-api/codex)의 캐싱 한계 — store:false 강제(store:true→400) + OpenAI 공식 이슈 openai/codex#5556(ChatGPT-login 모드 캐시 ~1:1 붕괴 vs API-key 모드 20:1). 이 수정은 correct하나 백엔드가 항상 0을 주므로 OAuth 경로에서 inert(비용 변화 0). 실효 레버는 상용 metered openai/ API 전환(자동 캐싱 정상) 또는 GPT-5.5 비중 축소. 백엔드 동작이 바뀌거나 API 경로로 갈 때 재개 가능. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The
codex_chatgpthandler (ChatGPT/Codex OAuth backend,auth/gpt-*) dropped the Responses-API prompt-cache hit count from its usage object, so those calls were cost-calculated at full input rate — the OAuth GPT path showed 0% cache inLiteLLM_SpendLogswhile the Claude OAuth path (auth/claude-*) correctly showed 88–90% cache-read. On a real 3-engagement sample, GPT-5.5(codex) was ~20–23% of engagement cost, entirely uncached in the billing figures.Fix (2 places)
config/codex_chatgpt_handler.py— surfaceusage.input_tokens_details.cached_tokensas OpenAI-styleprompt_tokens_details.cached_tokensin both the completion and streaming final-usage paths (mirrorsclaude_code_handlersurfacingcache_read_input_tokens). Absent field → 0 → no-op.config/litellm_dynamic_config.py— addcache_read_input_token_costto theauth/gpt*shadow pricing (GPT-5 generation cached input = input × 0.1, i.e. 90% off; verified vs OpenAI pricing: gpt-5.5 $5→$0.50/1M, gpt-5.4 $2.50→$0.25/1M). LiteLLM only discounts cached tokens when this cost is present inmodel_info.test_codex_chatgpt_handler_cache.py: cached_tokens surfaced (present / absent / zero), hermetic module loader.277 passed,ruffclean.Why draft — verification pending
The change is defensive (harmless no-op if the backend omits the field) and unit-tested, but not yet verified against a live codex
/responsespayload (local codex refresh token was rotated by prod →refresh_token_reused, can't authenticate locally). External evidence that the field is present: OpenAI Responses API spec includesinput_tokens_details.cached_tokens; Codex CLI keeps stable prefixes for caching; promptfoo #7546 shows the Codex SDK returnscached_input_tokens.To finish: either (a)
codex login+ confirm a real payload carriesinput_tokens_details.cached_tokens, or (b) after deploy, confirmLiteLLM_SpendLogsshowscache_read > 0forauth/gptrows.Deploy note (SaaS)
This is baked into the litellm image config → applying to prod needs the litellm image rebuilt +
image_tag_litellmbumped + redeploy. No effect until then. Commercial (meteredopenai/gpt-*API) path caches automatically regardless; this fix is for the current OAuth dogfooding period's cost accuracy.🤖 Generated with Claude Code