fix: document realtime mutable payloads

This commit is contained in:
jibanez-staticduo 2026-09-18 13:25:36 +02:00
parent de113fb1fa
commit e6ab17cc48
No known key found for this signature in database
5 changed files with 24 additions and 8 deletions

View file

@ -2768,7 +2768,9 @@ def handle_realtime_stream_cost_calculation(
potential_model_names=potential_model_names,
combined_usage_object=(
RealtimeAPITokenUsageProcessor.collect_and_combine_usage_from_realtime_stream_results(
[event for event in results if event.get("type") != "response.event"]
[ # mutable-ok: collector requires a concrete event list
event for event in results if event.get("type") != "response.event"
]
)
if any(event.get("type") == "response.event" for event in results)
else combined_usage_object
@ -2832,7 +2834,7 @@ class _LiveBackendEnvelope(BaseModel):
def _live_backend_responses(
results: OpenAIRealtimeStreamList, logging_obj: LitellmLoggingObject | None = None
) -> tuple[ResponsesAPIResponse, ...]:
responses: Final = {
responses: Final = { # mutable-ok: deduplicate terminal backend responses by response id
response.id: response
for result in results
if result.get("type") == "response.event"

View file

@ -870,7 +870,14 @@ def image_edit(
extra_body if isinstance(extra_body, dict) else None,
)
if image_edit_provider_config.use_multipart_form_data()
else {**non_default_params, **(extra_body if isinstance(extra_body, dict) else {})}
else { # mutable-ok: image provider update requires a concrete request-parameter dict
**non_default_params,
**(
extra_body
if isinstance(extra_body, dict)
else {} # mutable-ok: empty fallback is consumed immediately
),
}
)
# Pre Call logging

View file

@ -157,7 +157,12 @@ class RealTimeStreaming:
self.messages: list[OpenAIRealtimeEvents] = []
if account_usage and live_initialization_seconds > 0:
self.messages.append(
{"type": "litellm.live.initialization", "usage": {"seconds": live_initialization_seconds}}
{ # mutable-ok: initialization event is appended to the mutable event history
"type": "litellm.live.initialization",
"usage": { # mutable-ok: usage payload is consumed as part of the typed event
"seconds": live_initialization_seconds,
},
}
)
self._backend_sent_frames: bool = False
self.input_message: dict = {}

View file

@ -12176,7 +12176,9 @@ async def realtime_websocket_endpoint(
# Only use explicit parameters, not all query params
query_params: Final = cast(
RealtimeQueryParams,
dict(_realtime_query_params_template(model, intent) + ((("call_id", call_id),) if call_id is not None else ())),
dict( # mutable-ok: FastAPI request query params must be materialized as a dict
_realtime_query_params_template(model, intent) + ((("call_id", call_id),) if call_id is not None else ())
),
)
data: dict[str, object] = {

View file

@ -362,9 +362,9 @@ async def create_realtime_client_secret(
return RealtimeClientSecretResponse(**upstream_json)
@router.post("/v1/live", tags=["realtime"])
@router.post("/live", tags=["realtime"])
@router.post("/openai/v1/live", tags=["realtime"])
@router.post("/v1/live", tags=["realtime"]) # mutable-ok: FastAPI route metadata uses a mutable tag list
@router.post("/live", tags=["realtime"]) # mutable-ok: FastAPI route metadata uses a mutable tag list
@router.post("/openai/v1/live", tags=["realtime"]) # mutable-ok: FastAPI route metadata uses a mutable tag list
async def proxy_live_calls(request: Request) -> Response:
from litellm.proxy.realtime_endpoints.call_sessions import create_codex_realtime_call