From 217e1fc957513c9e6804f5ab1fd3bc66cf105b4b Mon Sep 17 00:00:00 2001 From: Xubin Ren Date: Sun, 12 Apr 2026 12:08:43 +0000 Subject: [PATCH] test(retry): lock in-place image fallback behavior Add a focused regression test for the successful no-image retry path so the original message history stays stripped after fallback and the repeated retry loop cannot silently return. Made-with: Cursor --- tests/providers/test_provider_retry.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/providers/test_provider_retry.py b/tests/providers/test_provider_retry.py index c64e2a0f8..2ef784a3d 100644 --- a/tests/providers/test_provider_retry.py +++ b/tests/providers/test_provider_retry.py @@ -165,6 +165,24 @@ async def test_non_transient_error_with_images_retries_without_images() -> None: assert any("[image: /media/test.png]" in (b.get("text") or "") for b in content) +@pytest.mark.asyncio +async def test_successful_image_retry_mutates_original_messages_in_place() -> None: + """Successful no-image retry should update the caller's message history.""" + provider = ScriptedProvider([ + LLMResponse(content="model does not support images", finish_reason="error"), + LLMResponse(content="ok, no image"), + ]) + messages = copy.deepcopy(_IMAGE_MSG) + + response = await provider.chat_with_retry(messages=messages) + + assert response.content == "ok, no image" + content = messages[0]["content"] + assert isinstance(content, list) + assert all(block.get("type") != "image_url" for block in content) + assert any("[image: /media/test.png]" in (block.get("text") or "") for block in content) + + @pytest.mark.asyncio async def test_non_transient_error_without_images_no_retry() -> None: """Non-transient errors without image content are returned immediately."""