From d767d0eed84353a46fdb16d4a520082c6d3b0ab7 Mon Sep 17 00:00:00 2001 From: Sergey Borisov Date: Mon, 6 Apr 2026 20:10:12 +0200 Subject: [PATCH 1/2] fix: exclude null file_id from input_image payload to prevent 400 schema error (#5120) --- python/packages/a2a/tests/test_a2a_agent.py | 22 ++++++++----------- .../agent_framework_openai/_chat_client.py | 9 ++++---- .../tests/openai/test_openai_chat_client.py | 2 +- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/python/packages/a2a/tests/test_a2a_agent.py b/python/packages/a2a/tests/test_a2a_agent.py index a0919cbda4..442960a7ee 100644 --- a/python/packages/a2a/tests/test_a2a_agent.py +++ b/python/packages/a2a/tests/test_a2a_agent.py @@ -1284,13 +1284,11 @@ async def test_streaming_artifact_update_event_does_not_duplicate_terminal_task_ final=True, ) - mock_a2a_client.responses.extend( - [ - (working_task, first_chunk), - (working_task, second_chunk), - (terminal_task, terminal_event), - ] - ) + mock_a2a_client.responses.extend([ + (working_task, first_chunk), + (working_task, second_chunk), + (terminal_task, terminal_event), + ]) stream = a2a_agent.run("Hello", stream=True) updates: list[AgentResponseUpdate] = [] @@ -1371,12 +1369,10 @@ async def test_streaming_terminal_task_only_emits_unstreamed_artifacts( final=True, ) - mock_a2a_client.responses.extend( - [ - (working_task, streamed_chunk), - (terminal_task, terminal_event), - ] - ) + mock_a2a_client.responses.extend([ + (working_task, streamed_chunk), + (terminal_task, terminal_event), + ]) stream = a2a_agent.run("Hello", stream=True) updates: list[AgentResponseUpdate] = [] diff --git a/python/packages/openai/agent_framework_openai/_chat_client.py b/python/packages/openai/agent_framework_openai/_chat_client.py index 963888e45a..38bf2c3e19 100644 --- a/python/packages/openai/agent_framework_openai/_chat_client.py +++ b/python/packages/openai/agent_framework_openai/_chat_client.py @@ -1353,16 +1353,17 @@ def _prepare_content_for_openai( return ret case "data" | "uri": if content.has_top_level_media_type("image"): - return { + image_item: dict[str, Any] = { "type": "input_image", "image_url": content.uri, "detail": content.additional_properties.get("detail", "auto") if content.additional_properties else "auto", - "file_id": content.additional_properties.get("file_id", None) - if content.additional_properties - else None, } + file_id = content.additional_properties.get("file_id") if content.additional_properties else None + if file_id is not None: + image_item["file_id"] = file_id + return image_item if content.has_top_level_media_type("audio"): if content.media_type and "wav" in content.media_type: format = "wav" diff --git a/python/packages/openai/tests/openai/test_openai_chat_client.py b/python/packages/openai/tests/openai/test_openai_chat_client.py index 8c91048284..fd55321238 100644 --- a/python/packages/openai/tests/openai/test_openai_chat_client.py +++ b/python/packages/openai/tests/openai/test_openai_chat_client.py @@ -2577,7 +2577,7 @@ def test_prepare_content_for_openai_image_content() -> None: result = client._prepare_content_for_openai("user", image_content_basic) assert result["type"] == "input_image" assert result["detail"] == "auto" - assert result["file_id"] is None + assert "file_id" not in result def test_prepare_content_for_openai_audio_content() -> None: From 6f6f33b99ab97b541e82795cd03b33ad5ab0e221 Mon Sep 17 00:00:00 2001 From: Sergey Borisov Date: Mon, 6 Apr 2026 21:16:39 +0200 Subject: [PATCH 2/2] test: add case for additional_properties present without file_id key --- .../openai/tests/openai/test_openai_chat_client.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/python/packages/openai/tests/openai/test_openai_chat_client.py b/python/packages/openai/tests/openai/test_openai_chat_client.py index fd55321238..e172b98a8f 100644 --- a/python/packages/openai/tests/openai/test_openai_chat_client.py +++ b/python/packages/openai/tests/openai/test_openai_chat_client.py @@ -2579,6 +2579,17 @@ def test_prepare_content_for_openai_image_content() -> None: assert result["detail"] == "auto" assert "file_id" not in result + # Test image content with additional_properties present but no file_id key + image_content_detail_only = Content.from_uri( + uri="https://example.com/basic.png", + media_type="image/png", + additional_properties={"detail": "high"}, + ) + result = client._prepare_content_for_openai("user", image_content_detail_only) + assert result["type"] == "input_image" + assert result["detail"] == "high" + assert "file_id" not in result + def test_prepare_content_for_openai_audio_content() -> None: """Test _prepare_content_for_openai with audio content variations."""