Skip to content

fix(litellm): bill codex/ChatGPT OAuth path at cache-read rate#758

Closed
PurpleCHOIms wants to merge 1 commit into
mainfrom
feat/codex-oauth-cache-cost
Closed

fix(litellm): bill codex/ChatGPT OAuth path at cache-read rate#758
PurpleCHOIms wants to merge 1 commit into
mainfrom
feat/codex-oauth-cache-cost

Conversation

@PurpleCHOIms

Copy link
Copy Markdown
Member

Problem

The codex_chatgpt handler (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 in LiteLLM_SpendLogs while 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)

  1. config/codex_chatgpt_handler.py — surface usage.input_tokens_details.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_input_tokens). Absent field → 0 → no-op.
  2. config/litellm_dynamic_config.py — add cache_read_input_token_cost to the auth/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 in model_info.
  3. testtest_codex_chatgpt_handler_cache.py: cached_tokens surfaced (present / absent / zero), hermetic module loader. 277 passed, ruff clean.

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 /responses payload (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 includes input_tokens_details.cached_tokens; Codex CLI keeps stable prefixes for caching; promptfoo #7546 shows the Codex SDK returns cached_input_tokens.

To finish: either (a) codex login + confirm a real payload carries input_tokens_details.cached_tokens, or (b) after deploy, confirm LiteLLM_SpendLogs shows cache_read > 0 for auth/gpt rows.

Deploy note (SaaS)

This is baked into the litellm image config → applying to prod needs the litellm image rebuilt + image_tag_litellm bumped + redeploy. No effect until then. Commercial (metered openai/gpt-* API) path caches automatically regardless; this fix is for the current OAuth dogfooding period's cost accuracy.

🤖 Generated with Claude Code

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>
@PurpleCHOIms

Copy link
Copy Markdown
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 경로로 갈 때 재개 가능.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant