Skip to content

fix(model_prices): add gpt-realtime-2.1 models with regional processing uplift - #32387

Merged
mateo-berri merged 2 commits into
litellm_internal_stagingfrom
litellm_lit3912_gpt_realtime_21_regional_uplift
Jul 8, 2026
Merged

fix(model_prices): add gpt-realtime-2.1 models with regional processing uplift#32387
mateo-berri merged 2 commits into
litellm_internal_stagingfrom
litellm_lit3912_gpt_realtime_21_regional_uplift

Conversation

@mateo-berri

@mateo-berri mateo-berri commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Relevant issues

Linear ticket

Resolves LIT-3912

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Screenshots / Proof of Fix

Verified on a live local proxy hitting the real OpenAI realtime API over a WebSocket, one worktree per branch, each in its own fresh venv. Both runs used LITELLM_LOCAL_MODEL_COST_MAP=True so the proxy reads the in-repo cost map instead of the copy on main, an identical config with gpt-realtime-2.1 / gpt-realtime-2.1-mini pointed at openai/..., and the exact same text-only realtime request ("Reply with exactly one word: ok"). The only variable between the two runs is the branch. The realtime client is a short websockets script that opens ws://localhost:PORT/v1/realtime?model=gpt-realtime-2.1 with Authorization: Bearer sk-1234, sends a session.update (text modality), a conversation.item.create, and a response.create, then prints the response.done event and its usage

Both runs produced the identical real response and usage (129 text input tokens, 16 text output tokens with 11 reasoning tokens). The difference is purely in cost tracking

Before (branch litellm_internal_staging)

/v1/model/info has no prices and no uplift fields for either model

$ curl -s http://localhost:58823/v1/model/info -H "Authorization: Bearer sk-1234" \
  | jq -c '.data[] | select(.model_name | test("gpt-realtime-2.1")) | {model_name, input_cost_per_token: .model_info.input_cost_per_token, output_cost_per_token: .model_info.output_cost_per_token, uplift_eu: .model_info.regional_processing_uplift_multiplier_eu, uplift_us: .model_info.regional_processing_uplift_multiplier_us}'
{"model_name":"gpt-realtime-2.1","input_cost_per_token":0,"output_cost_per_token":0,"uplift_eu":null,"uplift_us":null}
{"model_name":"gpt-realtime-2.1-mini","input_cost_per_token":0,"output_cost_per_token":0,"uplift_eu":null,"uplift_us":null}

The same real realtime call still returns a valid answer from OpenAI

$ python rt_client.py 58823 gpt-realtime-2.1 sk-1234
EVENT session.created: {"type": "session.created", ..., "session": {"type": "realtime", "model": "gpt-realtime-2.1", "output_modalities": ["audio"], ...}}
EVENT response.done: {"type": "response.done", ..., "response": {"status": "completed", "output": [{"type": "message", "role": "assistant", "content": [{"type": "output_text", "text": "ok"}]}], "output_modalities": ["text"], ...}}
USAGE: {"total_tokens": 145, "input_tokens": 129, "output_tokens": 16, "input_token_details": {"text_tokens": 129, "audio_tokens": 0, "cached_tokens": 0}, "output_token_details": {"text_tokens": 16, "audio_tokens": 0, "reasoning_tokens": 11}}
GOT_DONE=True

but the proxy cannot cost it: the model is unmapped, so both token costs default to 0 and the response cost is 0.0

$ grep -E "has no (input|output)_cost_per_token in model_cost_map|response_cost: 0" before_proxy.log
... model=gpt-realtime-2.1, custom_llm_provider=openai has no input_cost_per_token in model_cost_map. Defaulting to 0.
... model=gpt-realtime-2.1, custom_llm_provider=openai has no output_cost_per_token in model_cost_map. Defaulting to 0.
... litellm_logging.py:1455 - response_cost: 0.0

After (branch litellm_lit3912_gpt_realtime_21_regional_uplift)

/v1/model/info now returns the token prices and both uplift multipliers set to 1.1

$ curl -s http://localhost:58824/v1/model/info -H "Authorization: Bearer sk-1234" \
  | jq -c '.data[] | select(.model_name | test("gpt-realtime-2.1")) | {model_name, input_cost_per_token: .model_info.input_cost_per_token, output_cost_per_token: .model_info.output_cost_per_token, input_cost_per_audio_token: .model_info.input_cost_per_audio_token, output_cost_per_audio_token: .model_info.output_cost_per_audio_token, uplift_eu: .model_info.regional_processing_uplift_multiplier_eu, uplift_us: .model_info.regional_processing_uplift_multiplier_us}'
{"model_name":"gpt-realtime-2.1","input_cost_per_token":0.000004,"output_cost_per_token":0.000024,"input_cost_per_audio_token":0.000032,"output_cost_per_audio_token":0.000064,"uplift_eu":1.1,"uplift_us":1.1}
{"model_name":"gpt-realtime-2.1-mini","input_cost_per_token":6E-7,"output_cost_per_token":0.0000024,"input_cost_per_audio_token":0.00001,"output_cost_per_audio_token":0.00002,"uplift_eu":1.1,"uplift_us":1.1}

The same real realtime call returns the same answer and usage

$ python rt_client.py 58824 gpt-realtime-2.1 sk-1234
EVENT session.created: {"type": "session.created", ..., "session": {"type": "realtime", "model": "gpt-realtime-2.1", "output_modalities": ["audio"], ...}}
EVENT response.done: {"type": "response.done", ..., "response": {"status": "completed", "output": [{"type": "message", "role": "assistant", "content": [{"type": "output_text", "text": "ok"}]}], "output_modalities": ["text"], ...}}
USAGE: {"total_tokens": 145, "input_tokens": 129, "output_tokens": 16, "input_token_details": {"text_tokens": 129, "audio_tokens": 0, "cached_tokens": 0}, "output_token_details": {"text_tokens": 16, "audio_tokens": 0, "reasoning_tokens": 11}}
GOT_DONE=True

and this time the proxy computes a real nonzero cost with no "Defaulting to 0"

$ grep -E "response_cost: [0-9]" after_proxy.log
... litellm_logging.py:1455 - response_cost: 0.001164

That 0.001164 is exactly what the new prices give: 129 text input tokens at $4 / 1M is 0.000516, and 16 output text tokens plus 11 reasoning tokens at $24 / 1M is 0.000648, summing to 0.001164

Regional processing uplift

The available OpenAI key is a global-project key, so a real call to a data-residency host is rejected by OpenAI itself rather than by LiteLLM

$ curl -s https://us.api.openai.com/v1/models -H "Authorization: Bearer sk-...REDACTED"
{"error":{"message":"Attempted to access resource with incorrect regional hostname. Please make your request to api.openai.com","type":"invalid_request_error","param":null,"code":"incorrect_hostname"}}

As far as real keys allow, the uplift is proven two ways on this branch. First, /v1/model/info above exposes regional_processing_uplift_multiplier_eu and regional_processing_uplift_multiplier_us equal to 1.1 on both models. Second, running the same cost path the realtime handler uses, against the real in-repo cost map, applies exactly 1.1x when data_residency is eu or us

$ LITELLM_LOCAL_MODEL_COST_MAP=True python - <<'PY'
from litellm.litellm_core_utils.llm_cost_calc.utils import generic_cost_per_token
from litellm.types.utils import Usage
usage = Usage(prompt_tokens=129, completion_tokens=27, total_tokens=156)
base = sum(generic_cost_per_token(model="gpt-realtime-2.1", usage=usage, custom_llm_provider="openai"))
for region in ("eu", "us"):
    total = sum(generic_cost_per_token(model="gpt-realtime-2.1", usage=usage, custom_llm_provider="openai", data_residency=region))
    print(region, round(total, 8), "ratio", round(total / base, 4))
PY
eu 0.0012804 ratio 1.1
us 0.0012804 ratio 1.1

When the api_base is a regional host (eu.api.openai.com or us.api.openai.com), infer_openai_data_residency sets data_residency accordingly and the same 1.1x lands on the live realtime cost

Type

🐛 Bug Fix

Changes

gpt-realtime-2.1 and gpt-realtime-2.1-mini were missing entirely from the cost map, so usage on them resolved to zero cost and never picked up the 10% regional processing uplift that OpenAI charges on data-residency endpoints

This adds both models to model_prices_and_context_window.json and the identical litellm/model_prices_and_context_window_backup.json, mirroring the field structure of the existing gpt-realtime-2 / gpt-realtime-mini entries with prices taken from OpenAI's pricing page. gpt-realtime-2.1 is text input $4, cached text $0.40, text output $24, audio input $32, cached audio $0.40, audio output $64, image input $5. gpt-realtime-2.1-mini is text input $0.60, cached text $0.06, text output $2.40, audio input $10, cached audio $0.30, audio output $20, image input $0.80, all per 1M tokens

Both models are on OpenAI's list of models eligible for the regional processing (data residency) uplift for releases on or after 2026-03-05, so each entry carries regional_processing_uplift_multiplier_eu and regional_processing_uplift_multiplier_us set to 1.1, matching the convention already used for the gpt-5.4/5.5 series. The uplift is applied by _get_regional_uplift_multiplier in litellm/litellm_core_utils/llm_cost_calc/utils.py when data_residency is inferred from the api_base (eu.api.openai.com -> eu, us.api.openai.com -> us)

The existing test_data_residency_applies_uplift regression test in tests/test_litellm/litellm_core_utils/llm_cost_calc/test_llm_cost_calc_utils.py is extended to parametrize over the two new models, asserting that cost with data_residency set to eu or us is exactly 1.1x the base cost on both the prompt and completion sides. The test fails if either entry or its multiplier fields are removed

@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes zero-cost tracking for gpt-realtime-2.1 and gpt-realtime-2.1-mini by adding both models to the primary and backup cost maps, including the 10% regional processing uplift multipliers required for OpenAI data-residency endpoints.

  • Adds complete pricing entries for both models (text/audio input+output, image, and all cache costs) aligned with OpenAI's pricing page, and sets regional_processing_uplift_multiplier_eu/us: 1.1 matching the gpt-5.4/5.5 convention.
  • Extends the test_data_residency_applies_uplift test via parametrization to assert the 1.1× uplift is applied for both new models under eu and us data residency; no network calls are made (uses the _local_model_cost_map fixture).

Confidence Score: 5/5

Safe to merge — the change is purely additive data entries in the cost map; no existing model entries are modified and no production logic is touched.

All numeric values are consistent with the PR description and align with the existing gpt-realtime-2 / gpt-realtime-mini structure. The previously flagged missing cache_read_input_audio_token_cost field is now present on gpt-realtime-2.1. Both JSON files are in sync. The test uses a local cost-map fixture with no network calls.

No files require special attention.

Important Files Changed

Filename Overview
model_prices_and_context_window.json Adds gpt-realtime-2.1 and gpt-realtime-2.1-mini entries with correct pricing, audio/text cache costs, regional uplift multipliers (1.1), and supported-endpoints metadata — consistent with the existing gpt-realtime-2 / gpt-realtime-mini pattern; previously flagged cache_read_input_audio_token_cost gap is now present.
litellm/model_prices_and_context_window_backup.json Backup JSON updated identically to the primary — all pricing fields, cache costs, and regional uplift multipliers match the primary file; no drift between the two files.
tests/test_litellm/litellm_core_utils/llm_cost_calc/test_llm_cost_calc_utils.py Existing test_data_residency_applies_uplift parametrized to cover gpt-realtime-2.1 and gpt-realtime-2.1-mini; uses the _local_model_cost_map fixture (no network calls), correctly asserts 1.10x uplift on both prompt and completion sides.

Reviews (2): Last reviewed commit: "fix(model_prices): add cache_read_input_..." | Re-trigger Greptile

Comment thread model_prices_and_context_window.json
Comment thread litellm/model_prices_and_context_window_backup.json
@codecov

codecov Bot commented Jul 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed-hq

codspeed-hq Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will degrade performance by 14.81%

❌ 1 regressed benchmark
✅ 29 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
test_completion_simple_message 4.1 ms 4.8 ms -14.81%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing litellm_lit3912_gpt_realtime_21_regional_uplift (a08d91d) with litellm_internal_staging (9652509)

Open in CodSpeed

@mateo-berri

Copy link
Copy Markdown
Contributor Author

@greptileai

@mateo-berri
mateo-berri merged commit bd6cabe into litellm_internal_staging Jul 8, 2026
125 of 128 checks passed
@mateo-berri
mateo-berri deleted the litellm_lit3912_gpt_realtime_21_regional_uplift branch July 8, 2026 01:56
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.

3 participants