This commit is contained in:
Onat Özmen 2026-08-27 12:24:37 -07:00 committed by GitHub
commit 4b51afe18f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 40 additions and 0 deletions

View file

@ -276,6 +276,7 @@ class MCPEnhancedStreamingIterator(BaseResponsesAPIStreamingIterator):
# Streaming state management
self.phase = "initial_response" # initial_response -> mcp_discovery -> (continue_initial_response <-> tool_execution) -> finished
self.finished = False
self.completed_response: Any | None = None
# Event queues and generation flags
self.mcp_discovery_events: list[ResponsesAPIStreamingResponse] = (

View file

@ -258,3 +258,42 @@ async def test_initial_call_failure_is_stashed_for_eager_reraise(monkeypatch):
assert iterator._initial_creation_error is not None
assert "initial boom" in str(iterator._initial_creation_error)
@pytest.mark.asyncio
async def test_mid_stream_error_leaves_completed_response_readable(monkeypatch):
"""
Regression test: on a mid-stream provider error the Router's fallback path
reads `completed_response` off this iterator directly (see
Router._extract_partial_responses_usage). This iterator skips
super().__init__(), so that read used to raise AttributeError and mask the
provider error, stopping the fallback from running.
"""
from litellm import Router
from litellm.exceptions import MidStreamFallbackError
_mock_mcp_environment(monkeypatch)
class _ErroringStream:
def __aiter__(self):
return self
async def __anext__(self):
raise MidStreamFallbackError(
message="provider overloaded",
model="gpt-4",
llm_provider="openai",
)
iterator = MCPEnhancedStreamingIterator(
base_iterator=_ErroringStream(),
mcp_events=[],
tool_server_map={},
original_request_params={"model": "gpt-4"},
)
with pytest.raises(MidStreamFallbackError):
await iterator.__anext__()
assert iterator.completed_response is None
assert Router._extract_partial_responses_usage(iterator) is None