fix(responses): allocate the message output index from the shared item allocator

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Devin AI 2026-09-17 05:15:07 +00:00
parent d4e54a0f34
commit 42c4c81633
2 changed files with 31 additions and 2 deletions

View file

@ -599,7 +599,9 @@ class LiteLLMCompletionStreamingIterator(ResponsesAPIStreamingIterator):
self._cached_item_id = f"msg_{uuid.uuid4()}"
self.sent_message_item_added_event = True
self.sent_content_part_added_event = True
self._message_output_index = 1 if self._cached_reasoning_item_id is not None else 0
if self._cached_reasoning_item_id is not None:
self._message_output_index = self._next_tool_output_index
self._next_tool_output_index += 1
self._sequence_number += 1
event: Final = OutputItemAddedEvent(
type=ResponsesAPIStreamEvents.OUTPUT_ITEM_ADDED,
@ -953,7 +955,6 @@ class LiteLLMCompletionStreamingIterator(ResponsesAPIStreamingIterator):
if self._cached_reasoning_item_id is None:
self._cached_reasoning_item_id = f"rs_{uuid.uuid4()}"
self._reasoning_item_id = self._cached_reasoning_item_id
self._next_tool_output_index = max(self._next_tool_output_index, 2)
event = OutputItemAddedEvent(
type=ResponsesAPIStreamEvents.OUTPUT_ITEM_ADDED,

View file

@ -1063,6 +1063,34 @@ 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.parametrize("sync_mode", [True, False])
@pytest.mark.asyncio
async def test_tool_then_reasoning_then_text_gives_message_its_own_output_index(sync_mode):
iterator: Final = _build_iterator(
[
_tool_call_chunk(),
_reasoning_chunk("thinking"),
_chunk("Hello"),
_chunk("!", finish_reason="stop"),
]
)
events: Final = await _collect_events(iterator, sync_mode)
output_item_added_events: Final = [
event for event in events if getattr(event, "type", None) == ResponsesAPIStreamEvents.OUTPUT_ITEM_ADDED
]
message_item_adds: Final = [event for event in output_item_added_events if _is_message_item(event)]
function_call_adds: Final = [
event for event in output_item_added_events if getattr(event.item, "type", None) == "function_call"
]
assert len(message_item_adds) == 1
assert all(message_item_adds[0].output_index != event.output_index for event in function_call_adds)
output_indexes_by_item_id: Final = {event.item.id: event.output_index for event in output_item_added_events}
assert len(output_indexes_by_item_id) == len(set(output_indexes_by_item_id.values()))
@pytest.mark.parametrize("sync_mode", [True, False])
@pytest.mark.asyncio
async def test_plain_text_stream_announces_exactly_one_message_item(sync_mode):