mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
fix(gemini realtime): event_id, item copy, and dict guard for tool-call events
- Emit event_id on response.output_item.added for tool calls so spec-compliant OpenAI Realtime SDK clients can index/deduplicate the event like every other server-sent event in the sequence. - Pass a shallow copy of function_call_item to response.output_item.done and conversation.item.created so downstream handlers (e.g. the beta-protocol translator) that mutate the item dict don't corrupt sibling events sharing the same reference. - Guard map_openai_event against non-dict values (e.g. Gemini's 'setupComplete: true' boolean payload) so the WebSocket session doesn't die with an AttributeError on the unguarded .get() call. Add NotRequired event_id field on OpenAIRealtimeStreamResponseOutputItemAdded to keep existing call-sites that don't set event_id compatible. Co-authored-by: Yassin Kortam <yassin@berri.ai>
This commit is contained in:
parent
ec79cec7ae
commit
a8b592b634
2 changed files with 23 additions and 7 deletions
|
|
@ -1138,11 +1138,15 @@ class GeminiRealtimeConfig(BaseRealtimeConfig):
|
|||
def map_openai_event(
|
||||
self,
|
||||
key: str,
|
||||
value: dict,
|
||||
value: Any,
|
||||
current_delta_type: Optional[ALL_DELTA_TYPES],
|
||||
) -> Union[OpenAIRealtimeEventTypes, ResponsesAPIStreamEvents]:
|
||||
model_turn_event = value.get("modelTurn")
|
||||
generation_complete_event = value.get("generationComplete")
|
||||
if isinstance(value, dict):
|
||||
model_turn_event = value.get("modelTurn")
|
||||
generation_complete_event = value.get("generationComplete")
|
||||
else:
|
||||
model_turn_event = None
|
||||
generation_complete_event = None
|
||||
openai_event: Optional[
|
||||
Union[OpenAIRealtimeEventTypes, ResponsesAPIStreamEvents]
|
||||
] = None
|
||||
|
|
@ -1399,6 +1403,7 @@ class GeminiRealtimeConfig(BaseRealtimeConfig):
|
|||
returned_message.append(
|
||||
OpenAIRealtimeStreamResponseOutputItemAdded(
|
||||
type="response.output_item.added",
|
||||
event_id=f"event_{uuid.uuid4()}",
|
||||
response_id=current_response_id,
|
||||
output_index=idx,
|
||||
item={
|
||||
|
|
@ -1431,14 +1436,17 @@ class GeminiRealtimeConfig(BaseRealtimeConfig):
|
|||
)
|
||||
# response.function_call_arguments.done
|
||||
returned_message.append(tool_call)
|
||||
# response.output_item.done
|
||||
# response.output_item.done — pass a fresh copy so
|
||||
# downstream handlers that mutate the item dict (e.g. the
|
||||
# beta-protocol translator) don't corrupt the references
|
||||
# used by sibling events sharing the same function_call_item.
|
||||
returned_message.append(
|
||||
OpenAIRealtimeOutputItemDone(
|
||||
type="response.output_item.done",
|
||||
event_id=f"event_{uuid.uuid4()}",
|
||||
response_id=current_response_id,
|
||||
output_index=idx,
|
||||
item=function_call_item,
|
||||
item={**function_call_item},
|
||||
)
|
||||
)
|
||||
# conversation.item.created
|
||||
|
|
@ -1446,7 +1454,7 @@ class GeminiRealtimeConfig(BaseRealtimeConfig):
|
|||
OpenAIRealtimeConversationItemCreated(
|
||||
type="conversation.item.created",
|
||||
event_id=f"event_{uuid.uuid4()}",
|
||||
item=function_call_item,
|
||||
item={**function_call_item},
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,14 @@ from pydantic import (
|
|||
field_serializer,
|
||||
field_validator,
|
||||
)
|
||||
from typing_extensions import Annotated, Dict, Required, TypedDict, override
|
||||
from typing_extensions import (
|
||||
Annotated,
|
||||
Dict,
|
||||
NotRequired,
|
||||
Required,
|
||||
TypedDict,
|
||||
override,
|
||||
)
|
||||
|
||||
from litellm.types.llms.base import BaseLiteLLMOpenAIResponseObject
|
||||
from litellm.types.responses.main import (
|
||||
|
|
@ -1935,6 +1942,7 @@ class OpenAIRealtimeStreamResponseOutputItemAdded(TypedDict):
|
|||
response_id: str
|
||||
output_index: int
|
||||
item: OpenAIRealtimeStreamResponseOutputItem
|
||||
event_id: NotRequired[str]
|
||||
|
||||
|
||||
class OpenAIRealtimeStreamResponseBaseObject(TypedDict):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue