fix(pricing): mark realtime-only gpt-realtime models as mode realtime (#33728)

The gpt-realtime family (OpenAI and Azure) only serves /v1/realtime and is rejected by /v1/chat/completions with "This is not a chat model", but the cost map tagged them mode=chat. Retag them mode=realtime (a value already used by gemini-live and handled by the health-check realtime handler) and add realtime to the ModelInfoBase mode literal.

Co-authored-by: Krrish Dholakia <krrishdholakia@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
devin-ai-integration[bot] 2026-07-17 17:39:19 +00:00 • committed by GitHub
parent 0e88b57ec2
commit 00e0dd1bc1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 135 additions and 52 deletions

View file

@ -3451,7 +3451,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2.2e-05,
"output_cost_per_token": 2.64e-06,
"supports_audio_input": true,
@ -3470,7 +3470,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 0.00022,
"output_cost_per_token": 2.2e-05,
"supports_audio_input": true,
@ -3489,7 +3489,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 8e-05,
"output_cost_per_token": 2.2e-05,
"supported_modalities": [
@ -4687,7 +4687,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supports_audio_input": true,
@ -4707,7 +4707,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 1.6e-05,
"supported_endpoints": [
@ -4739,7 +4739,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 1.6e-05,
"supported_endpoints": [
@ -4771,7 +4771,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supported_endpoints": [
@ -4832,7 +4832,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 0.0002,
"output_cost_per_token": 2e-05,
"supports_audio_input": true,
@ -4850,7 +4850,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 8e-05,
"output_cost_per_token": 2e-05,
"supported_modalities": [
@ -7922,7 +7922,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2.2e-05,
"output_cost_per_token": 2.64e-06,
"supports_audio_input": true,
@ -7941,7 +7941,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 0.00022,
"output_cost_per_token": 2.2e-05,
"supports_audio_input": true,
@ -7960,7 +7960,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 8e-05,
"output_cost_per_token": 2.2e-05,
"supported_modalities": [
@ -22094,7 +22094,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supports_audio_input": true,
@ -22113,7 +22113,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supports_audio_input": true,
@ -22207,7 +22207,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 8e-05,
"output_cost_per_token": 2e-05,
"supports_audio_input": true,
@ -22225,7 +22225,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 8e-05,
"output_cost_per_token": 2e-05,
"supports_audio_input": true,
@ -22243,7 +22243,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 8e-05,
"output_cost_per_token": 2e-05,
"supports_audio_input": true,
@ -24438,7 +24438,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 1.6e-05,
"supported_endpoints": [
@ -24470,7 +24470,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 1.6e-05,
"supported_endpoints": [
@ -24502,7 +24502,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 1.6e-05,
"supported_endpoints": [
@ -24535,7 +24535,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 32000,
"max_tokens": 32000,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 2.4e-05,
"regional_processing_uplift_multiplier_eu": 1.1,
@ -24570,7 +24570,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"regional_processing_uplift_multiplier_eu": 1.1,
@ -24603,7 +24603,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supported_endpoints": [
@ -24635,7 +24635,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 1.6e-05,
"supported_endpoints": [
@ -43573,7 +43573,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supported_endpoints": [
@ -43606,7 +43606,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supported_endpoints": [

View file

@ -266,6 +266,7 @@ class ModelInfoBase(ProviderSpecificModelInfo, total=False):
"audio_transcription",
"responses",
"ocr",
"realtime",
]
]
tpm: Optional[int]

View file

@ -3451,7 +3451,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2.2e-05,
"output_cost_per_token": 2.64e-06,
"supports_audio_input": true,
@ -3470,7 +3470,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 0.00022,
"output_cost_per_token": 2.2e-05,
"supports_audio_input": true,
@ -3489,7 +3489,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 8e-05,
"output_cost_per_token": 2.2e-05,
"supported_modalities": [
@ -4687,7 +4687,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supports_audio_input": true,
@ -4707,7 +4707,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 1.6e-05,
"supported_endpoints": [
@ -4739,7 +4739,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 1.6e-05,
"supported_endpoints": [
@ -4771,7 +4771,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supported_endpoints": [
@ -4832,7 +4832,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 0.0002,
"output_cost_per_token": 2e-05,
"supports_audio_input": true,
@ -4850,7 +4850,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 8e-05,
"output_cost_per_token": 2e-05,
"supported_modalities": [
@ -7922,7 +7922,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2.2e-05,
"output_cost_per_token": 2.64e-06,
"supports_audio_input": true,
@ -7941,7 +7941,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 0.00022,
"output_cost_per_token": 2.2e-05,
"supports_audio_input": true,
@ -7960,7 +7960,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 8e-05,
"output_cost_per_token": 2.2e-05,
"supported_modalities": [
@ -22169,7 +22169,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supports_audio_input": true,
@ -22188,7 +22188,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supports_audio_input": true,
@ -22282,7 +22282,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 8e-05,
"output_cost_per_token": 2e-05,
"supports_audio_input": true,
@ -22300,7 +22300,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 8e-05,
"output_cost_per_token": 2e-05,
"supports_audio_input": true,
@ -22318,7 +22318,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 8e-05,
"output_cost_per_token": 2e-05,
"supports_audio_input": true,
@ -24513,7 +24513,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 1.6e-05,
"supported_endpoints": [
@ -24545,7 +24545,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 1.6e-05,
"supported_endpoints": [
@ -24577,7 +24577,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 1.6e-05,
"supported_endpoints": [
@ -24610,7 +24610,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 32000,
"max_tokens": 32000,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 2.4e-05,
"regional_processing_uplift_multiplier_eu": 1.1,
@ -24645,7 +24645,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"regional_processing_uplift_multiplier_eu": 1.1,
@ -24678,7 +24678,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supported_endpoints": [
@ -24710,7 +24710,7 @@
"max_input_tokens": 32000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 6.4e-05,
"output_cost_per_token": 1.6e-05,
"supported_endpoints": [
@ -43694,7 +43694,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supported_endpoints": [
@ -43727,7 +43727,7 @@
"max_input_tokens": 128000,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "chat",
"mode": "realtime",
"output_cost_per_audio_token": 2e-05,
"output_cost_per_token": 2.4e-06,
"supported_endpoints": [

View file

@ -0,0 +1,82 @@
import json
import typing
from pathlib import Path
import pytest
import litellm
from litellm.types.utils import ModelInfoBase
REALTIME_ONLY_GPT_MODELS = (
"azure/gpt-realtime-2025-08-28",
"azure/gpt-realtime-1.5-2026-02-23",
"azure/gpt-realtime-mini-2025-10-06",
"gpt-realtime",
"gpt-realtime-1.5",
"gpt-realtime-2",
"gpt-realtime-2.1",
"gpt-realtime-2.1-mini",
"gpt-realtime-mini",
"gpt-realtime-2025-08-28",
"gpt-realtime-mini-2025-10-06",
"gpt-realtime-mini-2025-12-15",
)
REALTIME_ONLY_GPT_MODELS_WITHOUT_ENDPOINTS = (
"azure/eu/gpt-4o-mini-realtime-preview-2024-12-17",
"azure/eu/gpt-4o-realtime-preview-2024-10-01",
"azure/eu/gpt-4o-realtime-preview-2024-12-17",
"azure/gpt-4o-mini-realtime-preview-2024-12-17",
"azure/gpt-4o-realtime-preview-2024-10-01",
"azure/gpt-4o-realtime-preview-2024-12-17",
"azure/us/gpt-4o-mini-realtime-preview-2024-12-17",
"azure/us/gpt-4o-realtime-preview-2024-10-01",
"azure/us/gpt-4o-realtime-preview-2024-12-17",
"gpt-4o-mini-realtime-preview",
"gpt-4o-mini-realtime-preview-2024-12-17",
"gpt-4o-realtime-preview",
"gpt-4o-realtime-preview-2024-12-17",
"gpt-4o-realtime-preview-2025-06-03",
)
ALL_REALTIME_ONLY_GPT_MODELS = REALTIME_ONLY_GPT_MODELS + REALTIME_ONLY_GPT_MODELS_WITHOUT_ENDPOINTS
def _load_cost_map() -> dict:
json_path = Path(__file__).parents[2] / "model_prices_and_context_window.json"
with open(json_path) as f:
return json.load(f)
def test_realtime_is_a_valid_mode_literal():
hints = typing.get_type_hints(ModelInfoBase, include_extras=False)
assert "realtime" in typing.get_args(hints["mode"])
@pytest.mark.parametrize("model", REALTIME_ONLY_GPT_MODELS)
def test_realtime_only_gpt_models_are_mode_realtime(model):
"""These models only serve /v1/realtime and are rejected by /v1/chat/completions
("This is not a chat model ..."), so they must not be tagged mode=chat."""
info = _load_cost_map()[model]
assert info["supported_endpoints"] == ["/v1/realtime"]
assert info["mode"] == "realtime"
@pytest.mark.parametrize("model", REALTIME_ONLY_GPT_MODELS_WITHOUT_ENDPOINTS)
def test_realtime_only_gpt_4o_models_are_mode_realtime(model):
"""gpt-4o(-mini)-realtime-preview are realtime-only and must not be mode=chat."""
assert _load_cost_map()[model]["mode"] == "realtime"
def test_get_model_info_reports_realtime_mode():
assert litellm.get_model_info("gpt-realtime-mini")["mode"] == "realtime"
def test_backup_matches_main_for_realtime_models():
repo_root = Path(__file__).parents[2]
with open(repo_root / "model_prices_and_context_window.json") as f:
main_cost = json.load(f)
with open(repo_root / "litellm" / "model_prices_and_context_window_backup.json") as f:
backup_cost = json.load(f)
for model in ALL_REALTIME_ONLY_GPT_MODELS:
assert backup_cost.get(model) == main_cost.get(model)