From f0530b4d29c5b756f27977eae2508e2fb794cb0b Mon Sep 17 00:00:00 2001 From: Hardik K Date: Tue, 20 Oct 2026 01:14:12 +0530 Subject: [PATCH 1/2] fix(devui): fallback to empty string when reasoning chunk has no text Fixes #9533 --- .../devui/agent_framework_devui/_mapper.py | 2 +- .../packages/devui/tests/devui/test_mapper.py | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/python/packages/devui/agent_framework_devui/_mapper.py b/python/packages/devui/agent_framework_devui/_mapper.py index 771a571e2aa..d3288463247 100644 --- a/python/packages/devui/agent_framework_devui/_mapper.py +++ b/python/packages/devui/agent_framework_devui/_mapper.py @@ -1432,7 +1432,7 @@ async def _map_reasoning_content(self, content: Any, context: dict[str, Any]) -> """Map TextReasoningContent to ResponseReasoningTextDeltaEvent.""" return ResponseReasoningTextDeltaEvent( type="response.reasoning_text.delta", - delta=content.text, + delta=content.text or "", item_id=context["item_id"], output_index=context["output_index"], content_index=context["content_index"], diff --git a/python/packages/devui/tests/devui/test_mapper.py b/python/packages/devui/tests/devui/test_mapper.py index d71a32c88ad..dade3556583 100644 --- a/python/packages/devui/tests/devui/test_mapper.py +++ b/python/packages/devui/tests/devui/test_mapper.py @@ -1179,3 +1179,34 @@ async def test_superstep_completed_event(mapper: MessageMapper, test_request: Ag # superstep_completed event (type='superstep_completed') may not emit events (internal workflow signal) # Just ensure it doesn't crash assert isinstance(events, list) + +# ============================================================================= +# Reasoning Content Tests +# ============================================================================= + + +async def test_map_reasoning_content_with_none_text(mapper: MessageMapper) -> None: + """Test that TextReasoningContent with None text falls back to empty string without raising validation error.""" + from unittest.mock import MagicMock + + context = {"item_id": "item-1", "output_index": 0, "content_index": 0, "sequence": 0} + content = MagicMock() + content.text = None + + event = await mapper._map_reasoning_content(content, context) + assert event.type == "response.reasoning_text.delta" + assert event.delta == "" + + +async def test_map_reasoning_content_with_valid_text(mapper: MessageMapper) -> None: + """Test that TextReasoningContent with valid text maps delta properly.""" + from unittest.mock import MagicMock + + context = {"item_id": "item-1", "output_index": 0, "content_index": 0, "sequence": 0} + content = MagicMock() + content.text = "Thinking through the steps..." + + event = await mapper._map_reasoning_content(content, context) + assert event.type == "response.reasoning_text.delta" + assert event.delta == "Thinking through the steps..." + From 04baa1e3c43114dc5da3aa21ef7a0ab914006ff6 Mon Sep 17 00:00:00 2001 From: Hardik Kaurani Date: Tue, 20 Oct 2026 22:17:49 +0530 Subject: [PATCH 2/2] test(devui): initialize reasoning sequence counters --- python/packages/devui/tests/devui/test_mapper.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/packages/devui/tests/devui/test_mapper.py b/python/packages/devui/tests/devui/test_mapper.py index dade3556583..0eab8ffa6dc 100644 --- a/python/packages/devui/tests/devui/test_mapper.py +++ b/python/packages/devui/tests/devui/test_mapper.py @@ -1180,6 +1180,7 @@ async def test_superstep_completed_event(mapper: MessageMapper, test_request: Ag # Just ensure it doesn't crash assert isinstance(events, list) + # ============================================================================= # Reasoning Content Tests # ============================================================================= @@ -1189,7 +1190,7 @@ async def test_map_reasoning_content_with_none_text(mapper: MessageMapper) -> No """Test that TextReasoningContent with None text falls back to empty string without raising validation error.""" from unittest.mock import MagicMock - context = {"item_id": "item-1", "output_index": 0, "content_index": 0, "sequence": 0} + context = {"item_id": "item-1", "output_index": 0, "content_index": 0, "sequence_counter": 0} content = MagicMock() content.text = None @@ -1202,11 +1203,10 @@ async def test_map_reasoning_content_with_valid_text(mapper: MessageMapper) -> N """Test that TextReasoningContent with valid text maps delta properly.""" from unittest.mock import MagicMock - context = {"item_id": "item-1", "output_index": 0, "content_index": 0, "sequence": 0} + context = {"item_id": "item-1", "output_index": 0, "content_index": 0, "sequence_counter": 0} content = MagicMock() content.text = "Thinking through the steps..." event = await mapper._map_reasoning_content(content, context) assert event.type == "response.reasoning_text.delta" assert event.delta == "Thinking through the steps..." -