fix(responses): close the reasoning item before announcing the message item

This commit is contained in:
mateo-berri 2026-09-18 21:37:01 -07:00
parent 8ce2887888
commit 4468c9fdcb
2 changed files with 26 additions and 6 deletions

View file

@ -927,12 +927,6 @@ class LiteLLMCompletionStreamingIterator(ResponsesAPIStreamingIterator):
def _ensure_output_item_for_chunk(self, chunk: ModelResponseStream) -> None:
# Change: Never return a value, just enqueue output item events
if self.sent_output_item_added_event:
if (
not self.sent_message_item_added_event
and chunk.choices
and self._get_delta_string_from_streaming_choices(chunk.choices)
):
self._queue_message_item_added_events()
return
if not chunk.choices:
return

View file

@ -1058,6 +1058,32 @@ async def test_reasoning_then_text_announces_message_item_before_text_events(syn
assert announced_indexes_by_item_type["message"] != announced_indexes_by_item_type["reasoning"]
@pytest.mark.asyncio
async def test_reasoning_item_closes_before_message_item_opens():
iterator: Final = _build_iterator(
[
_reasoning_chunk("let me think"),
_chunk("Hello"),
_chunk("!", finish_reason="stop"),
]
)
events: Final = await _collect_events(iterator, sync_mode=False)
item_lifecycle: Final = [
(event.type, event.item.type)
for event in events
if getattr(event, "type", None)
in (ResponsesAPIStreamEvents.OUTPUT_ITEM_ADDED, ResponsesAPIStreamEvents.OUTPUT_ITEM_DONE)
]
assert item_lifecycle == [
(ResponsesAPIStreamEvents.OUTPUT_ITEM_ADDED, "reasoning"),
(ResponsesAPIStreamEvents.OUTPUT_ITEM_DONE, "reasoning"),
(ResponsesAPIStreamEvents.OUTPUT_ITEM_ADDED, "message"),
(ResponsesAPIStreamEvents.OUTPUT_ITEM_DONE, "message"),
]
@pytest.mark.parametrize("sync_mode", [True, False])
@pytest.mark.asyncio
async def test_tool_then_reasoning_then_text_gives_message_its_own_output_index(sync_mode: bool):