From 11bae75ab5f44ea3c0e23a278ceeab3af843ff1b Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 7 Apr 2026 12:49:36 +0000 Subject: [PATCH 1/2] Guard against empty text in _parse_structured_response_value (#5145) When using response_format with background=True (Responses API), polling an in-progress response produces empty text. _parse_structured_response_value unconditionally passed this to model_validate_json/json.loads, causing ValidationError or JSONDecodeError. Add an early return of None when text is empty, matching the existing guard for response_format=None. This allows .value to safely return None for in-progress background responses. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../packages/core/agent_framework/_types.py | 2 ++ python/packages/core/tests/core/test_types.py | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/python/packages/core/agent_framework/_types.py b/python/packages/core/agent_framework/_types.py index 736474de60..87799d0848 100644 --- a/python/packages/core/agent_framework/_types.py +++ b/python/packages/core/agent_framework/_types.py @@ -1957,6 +1957,8 @@ class ContinuationToken(TypedDict): def _parse_structured_response_value(text: str, response_format: Any | None) -> Any | None: if response_format is None: return None + if not text: + return None if isinstance(response_format, type) and issubclass(response_format, BaseModel): return response_format.model_validate_json(text) if isinstance(response_format, Mapping): diff --git a/python/packages/core/tests/core/test_types.py b/python/packages/core/tests/core/test_types.py index 23c7dd8cd6..e8dc22acaa 100644 --- a/python/packages/core/tests/core/test_types.py +++ b/python/packages/core/tests/core/test_types.py @@ -39,6 +39,7 @@ _get_data_bytes, _get_data_bytes_as_str, _parse_content_list, + _parse_structured_response_value, _validate_uri, add_usage_details, validate_tool_mode, @@ -813,6 +814,34 @@ def test_chat_response_with_mapping_response_format() -> None: assert response.value["response"] == "Hello" + +def test_parse_structured_response_value_empty_text_with_pydantic_model() -> None: + """Empty text should return None instead of raising when response_format is a Pydantic model.""" + result = _parse_structured_response_value("", OutputModel) + assert result is None + + +def test_parse_structured_response_value_empty_text_with_mapping() -> None: + """Empty text should return None instead of raising when response_format is a mapping.""" + result = _parse_structured_response_value("", {"type": "object"}) + assert result is None + + +def test_chat_response_value_with_empty_text_and_response_format() -> None: + """ChatResponse.value should return None when text is empty and response_format is set.""" + message = Message(role="assistant", contents=[""]) + response = ChatResponse(messages=message, response_format=OutputModel) + assert response.value is None + + +def test_agent_response_value_with_empty_text_and_response_format() -> None: + """AgentResponse.value should return None when text is empty and response_format is set.""" + message = Message(role="assistant", contents=[""]) + response = AgentResponse(messages=message, response_format=OutputModel) + assert response.value is None + + + def test_chat_response_value_raises_on_invalid_schema(): """Test that value property raises ValidationError with field constraint details.""" From 85a7dc34b6e48eb1bffc60ebc23d0baaac68f9b6 Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 7 Apr 2026 12:52:29 +0000 Subject: [PATCH 2/2] Python: Fix `response_format` crash on background polling with empty text Fixes #5145 --- python/packages/core/tests/core/test_types.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/python/packages/core/tests/core/test_types.py b/python/packages/core/tests/core/test_types.py index e8dc22acaa..cf945dae0e 100644 --- a/python/packages/core/tests/core/test_types.py +++ b/python/packages/core/tests/core/test_types.py @@ -814,7 +814,6 @@ def test_chat_response_with_mapping_response_format() -> None: assert response.value["response"] == "Hello" - def test_parse_structured_response_value_empty_text_with_pydantic_model() -> None: """Empty text should return None instead of raising when response_format is a Pydantic model.""" result = _parse_structured_response_value("", OutputModel) @@ -841,7 +840,6 @@ def test_agent_response_value_with_empty_text_and_response_format() -> None: assert response.value is None - def test_chat_response_value_raises_on_invalid_schema(): """Test that value property raises ValidationError with field constraint details."""