mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-25 05:54:53 +00:00
Merge 1965867b7e into da80552897
This commit is contained in:
commit
3c41d01f1c
5 changed files with 46 additions and 6 deletions
|
|
@ -45,6 +45,7 @@ from litellm.types.llms.openai import (
|
|||
ResponseIncompleteEvent,
|
||||
ResponseInProgressEvent,
|
||||
ResponseInputParam,
|
||||
ResponsePartAddedEvent,
|
||||
ResponsesAPIOptionalRequestParams,
|
||||
ResponsesAPIResponse,
|
||||
ResponsesAPIStreamEvents,
|
||||
|
|
@ -1059,12 +1060,20 @@ class LiteLLMCompletionStreamingIterator(ResponsesAPIStreamingIterator):
|
|||
"id": self._cached_reasoning_item_id,
|
||||
"type": "reasoning",
|
||||
"status": "in_progress",
|
||||
"summary": None,
|
||||
"summary": [],
|
||||
}
|
||||
),
|
||||
)
|
||||
event.__dict__["sequence_number"] = self._sequence_number
|
||||
self._pending_response_events.append(event)
|
||||
self._sequence_number += 1
|
||||
part_added_event: Final = ResponsePartAddedEvent(
|
||||
type=ResponsesAPIStreamEvents.RESPONSE_PART_ADDED,
|
||||
item_id=self._cached_reasoning_item_id,
|
||||
output_index=self._reasoning_index(),
|
||||
sequence_number=self._sequence_number,
|
||||
part={"type": "summary_text", "text": ""},
|
||||
)
|
||||
self._pending_response_events.extend([event, part_added_event])
|
||||
return
|
||||
|
||||
# Tool-first
|
||||
|
|
|
|||
|
|
@ -1819,6 +1819,7 @@ def build_synthetic_response_events(
|
|||
item_id=item_id,
|
||||
output_index=output_index,
|
||||
summary_index=summary_index,
|
||||
sequence_number=sequence_number,
|
||||
part={**summary_payload, "text": ""},
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1720,8 +1720,9 @@ class ResponsePartAddedEvent(BaseLiteLLMOpenAIResponseObject):
|
|||
type: Literal[ResponsesAPIStreamEvents.RESPONSE_PART_ADDED]
|
||||
item_id: str
|
||||
output_index: int
|
||||
summary_index: int = 0
|
||||
sequence_number: int
|
||||
part: dict
|
||||
summary_index: int = 0
|
||||
|
||||
|
||||
class ReasoningSummaryTextDeltaEvent(BaseLiteLLMOpenAIResponseObject):
|
||||
|
|
|
|||
|
|
@ -4831,8 +4831,8 @@ class TestEnsureOutputItemContentPartAdded:
|
|||
assert completed_event.response.status == "completed"
|
||||
|
||||
def test_reasoning_item_does_not_emit_content_part_added(self):
|
||||
"""Reasoning items should not get a content_part.added event."""
|
||||
from litellm.types.llms.openai import OutputItemAddedEvent
|
||||
"""Reasoning items get a reasoning_summary_part.added event, not a content_part.added one."""
|
||||
from litellm.types.llms.openai import OutputItemAddedEvent, ResponsePartAddedEvent
|
||||
|
||||
iterator = self._make_iterator()
|
||||
chunk = self._make_reasoning_chunk()
|
||||
|
|
@ -4840,8 +4840,9 @@ class TestEnsureOutputItemContentPartAdded:
|
|||
iterator._ensure_output_item_for_chunk(chunk)
|
||||
|
||||
events = iterator._pending_response_events
|
||||
assert len(events) == 1
|
||||
assert len(events) == 2
|
||||
assert isinstance(events[0], OutputItemAddedEvent)
|
||||
assert isinstance(events[1], ResponsePartAddedEvent)
|
||||
assert iterator.sent_content_part_added_event is False
|
||||
|
||||
def test_only_emits_once(self):
|
||||
|
|
|
|||
|
|
@ -1385,6 +1385,34 @@ async def test_plain_text_stream_announces_exactly_one_message_item(sync_mode: b
|
|||
assert event.item_id == message_item_adds[0].item.id
|
||||
|
||||
|
||||
@pytest.mark.parametrize("sync_mode", [True, False])
|
||||
@pytest.mark.asyncio
|
||||
async def test_reasoning_item_opens_with_empty_summary_and_a_summary_part(sync_mode: bool):
|
||||
iterator: Final = _build_iterator(
|
||||
[_reasoning_chunk("let me "), _reasoning_chunk("think"), _chunk("hi", finish_reason="stop")]
|
||||
)
|
||||
events: Final = await _collect_events(iterator, sync_mode)
|
||||
|
||||
types: Final = [event.type for event in events]
|
||||
item_added: Final = next(
|
||||
e for e in events if e.type == ResponsesAPIStreamEvents.OUTPUT_ITEM_ADDED and e.item.type == "reasoning"
|
||||
)
|
||||
part_added: Final = next(e for e in events if e.type == ResponsesAPIStreamEvents.RESPONSE_PART_ADDED)
|
||||
first_delta: Final = types.index(ResponsesAPIStreamEvents.REASONING_SUMMARY_TEXT_DELTA)
|
||||
|
||||
assert item_added.item.summary == []
|
||||
assert (
|
||||
types.index(ResponsesAPIStreamEvents.OUTPUT_ITEM_ADDED)
|
||||
< types.index(ResponsesAPIStreamEvents.RESPONSE_PART_ADDED)
|
||||
< first_delta
|
||||
)
|
||||
assert types.count(ResponsesAPIStreamEvents.RESPONSE_PART_ADDED) == 1
|
||||
assert part_added.item_id == item_added.item.id
|
||||
assert part_added.output_index == item_added.output_index
|
||||
assert part_added.summary_index == 0
|
||||
assert part_added.part == {"type": "summary_text", "text": ""}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("sync_mode", [True, False])
|
||||
@pytest.mark.asyncio
|
||||
async def test_anthropic_tool_search_call_streams_as_tool_search_call_item(sync_mode: bool):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue