fix(interactions): address greptile review feedback

- Avoid mutating caller's generation_config dict by shallow-copying
  before popping image_config, preventing silent failures on retries
- Skip schema key in response_format when response_format is None to
  avoid sending schema: null to the Google Interactions API
- Remove delta field from step.stop events (new schema only); the
  StepStop model has no delta field and sending it duplicates already-
  streamed text and breaks spec-conformant clients

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Sameer Kankute 2026-05-18 14:05:54 +05:30
parent 58a52da9d5
commit a4d0ffcc83
No known key found for this signature in database
2 changed files with 53 additions and 26 deletions

View file

@ -241,13 +241,18 @@ class LiteLLMResponsesInteractionsStreamingIterator:
and self.sent_content_start
and transformed.event_type == completion_event_type
):
stop_chunk = InteractionsAPIStreamingResponse(
event_type=stop_event_type,
index=0,
id=transformed.id,
object="content",
delta={"type": "text", "text": self.collected_text},
)
stop_kwargs: Dict[str, Any] = {
"event_type": stop_event_type,
"index": 0,
"id": transformed.id,
"object": "content",
}
if self._use_legacy:
stop_kwargs["delta"] = {
"type": "text",
"text": self.collected_text,
}
stop_chunk = InteractionsAPIStreamingResponse(**stop_kwargs)
self._pending_interaction_complete = transformed
return stop_chunk
return transformed
@ -262,12 +267,17 @@ class LiteLLMResponsesInteractionsStreamingIterator:
stop_event_type = (
"content.stop" if self._use_legacy else "step.stop"
)
return InteractionsAPIStreamingResponse(
event_type=stop_event_type,
index=0,
object="content",
delta={"type": "text", "text": self.collected_text},
)
stop_kwargs = {
"event_type": stop_event_type,
"index": 0,
"object": "content",
}
if self._use_legacy:
stop_kwargs["delta"] = {
"type": "text",
"text": self.collected_text,
}
return InteractionsAPIStreamingResponse(**stop_kwargs)
raise StopIteration
@ -317,12 +327,19 @@ class LiteLLMResponsesInteractionsStreamingIterator:
and self.sent_content_start
and transformed.event_type == completion_event_type
):
stop_kwargs_async: Dict[str, Any] = {
"event_type": stop_event_type,
"index": 0,
"id": transformed.id,
"object": "content",
}
if self._use_legacy:
stop_kwargs_async["delta"] = {
"type": "text",
"text": self.collected_text,
}
stop_chunk = InteractionsAPIStreamingResponse(
event_type=stop_event_type,
index=0,
id=transformed.id,
object="content",
delta={"type": "text", "text": self.collected_text},
**stop_kwargs_async
)
self._pending_interaction_complete = transformed
return stop_chunk
@ -338,11 +355,16 @@ class LiteLLMResponsesInteractionsStreamingIterator:
stop_event_type = (
"content.stop" if self._use_legacy else "step.stop"
)
return InteractionsAPIStreamingResponse(
event_type=stop_event_type,
index=0,
object="content",
delta={"type": "text", "text": self.collected_text},
)
stop_kwargs_async = {
"event_type": stop_event_type,
"index": 0,
"object": "content",
}
if self._use_legacy:
stop_kwargs_async["delta"] = {
"type": "text",
"text": self.collected_text,
}
return InteractionsAPIStreamingResponse(**stop_kwargs_async)
raise StopAsyncIteration

View file

@ -191,11 +191,13 @@ class GoogleAIStudioInteractionsConfig(BaseInteractionsAPIConfig):
or "mime_type" not in response_format
):
# Wrap the legacy schema into the new polymorphic format.
response_format = {
new_rf: Dict[str, Any] = {
"type": "text",
"mime_type": response_mime_type,
"schema": response_format,
}
if response_format is not None:
new_rf["schema"] = response_format
response_format = new_rf
if response_format is not None:
request_body["response_format"] = response_format
@ -207,6 +209,9 @@ class GoogleAIStudioInteractionsConfig(BaseInteractionsAPIConfig):
if generation_config is not None:
image_config = None
if isinstance(generation_config, dict):
generation_config = dict(
generation_config
) # avoid mutating the caller's dict
image_config = generation_config.pop("image_config", None)
if not generation_config:
generation_config = None