1
+import json
2
import sys
3
from pathlib import Path
4
644
assert calls == ["responses", "chat"]
645
646
647
+@pytest.mark.asyncio
648
+async def test_unified_call_falls_back_when_responses_mock_reads_sse_as_json(
649
+ monkeypatch,
650
+):
651
+ calls: list[str] = []
652
+ sse_error = json.JSONDecodeError(
653
+ "Expecting value",
654
+ 'event: response.output_text.delta\ndata: {"delta":"hello"}\n\n',
655
+ 0,
656
+ )
657
+ failing_stream = _FailingAsyncChunkStream(sse_error)
658
+
659
+ async def fake_aresponses(*args, **kwargs):
660
+ calls.append("responses")
661
+ return failing_stream
662
+
663
+ async def fake_acompletion(*args, **kwargs):
664
+ calls.append("chat")
665
+ assert kwargs["stream"] is True
666
+ assert kwargs["drop_params"] is True
667
+ return _AsyncChunkStream([_chunk("fallback")])
668
+
669
+ async def fake_rate_limiter(*args, **kwargs):
670
+ return None
671
+
672
+ monkeypatch.setattr(litellm_transport, "aresponses", fake_aresponses)
673
+ monkeypatch.setattr(litellm_transport, "acompletion", fake_acompletion)
674
+ monkeypatch.setattr(models, "apply_rate_limiter", fake_rate_limiter)
675
+
676
+ wrapper = models.LiteLLMChatWrapper(
677
+ model="omniroute/test-model",
678
+ provider="openai",
679
+ model_config=None,
680
+ )
681
+
682
+ async def response_callback(chunk: str, full: str):
683
+ return None
684
+
685
+ response, reasoning = await wrapper.unified_call(
686
+ messages=[],
687
+ response_callback=response_callback,
688
+ )
689
+
690
+ assert response == "fallback"
691
+ assert reasoning == ""
692
+ assert calls == ["responses", "chat"]
693
+ assert failing_stream.closed is True
694
+
695
+
696
@pytest.mark.asyncio
697
async def test_unified_call_falls_back_when_responses_bad_request_rejects_shape(
698
monkeypatch,