diff --git a/python/semantic_kernel/contents/chat_message_content.py b/python/semantic_kernel/contents/chat_message_content.py index 13376106e8b1..226514e26090 100644 --- a/python/semantic_kernel/contents/chat_message_content.py +++ b/python/semantic_kernel/contents/chat_message_content.py @@ -243,9 +243,11 @@ def to_element(self) -> "Element": """ root = Element(self.tag) for field in self.model_fields_set: - if field not in ["role", "name", "encoding", "finish_reason", "ai_model_id"]: + if field not in ["role", "name", "encoding", "finish_reason", "status", "ai_model_id"]: continue value = getattr(self, field) + if value is None: + continue if isinstance(value, Enum): value = value.value root.set(field, value) diff --git a/python/tests/unit/contents/test_chat_history.py b/python/tests/unit/contents/test_chat_history.py index 3c1b92945296..0623062442a6 100644 --- a/python/tests/unit/contents/test_chat_history.py +++ b/python/tests/unit/contents/test_chat_history.py @@ -12,6 +12,7 @@ from semantic_kernel.contents.image_content import ImageContent from semantic_kernel.contents.text_content import TextContent from semantic_kernel.contents.utils.author_role import AuthorRole +from semantic_kernel.contents.utils.status import Status from semantic_kernel.exceptions import ContentInitializationError from semantic_kernel.functions.kernel_arguments import KernelArguments from semantic_kernel.kernel import Kernel @@ -33,6 +34,30 @@ def mock_chat_completion_response() -> ChatCompletion: ) +@pytest.mark.parametrize("serializer", [str, ChatHistory.to_prompt], ids=["str", "to_prompt"]) +@pytest.mark.parametrize("status", list(Status)) +def test_xml_roundtrip_preserves_message_status(status: Status, serializer): + history = ChatHistory(messages=[ChatMessageContent(role=AuthorRole.ASSISTANT, content="Working", status=status)]) + + xml = serializer(history) + restored = ChatHistory.from_rendered_prompt(xml) + + assert f'status="{status.value}"' in xml + assert restored[0].status is status + + +@pytest.mark.parametrize("serializer", [str, ChatHistory.to_prompt], ids=["str", "to_prompt"]) +def test_xml_serialization_omits_cleared_message_status(serializer): + message = ChatMessageContent(role=AuthorRole.ASSISTANT, content="Working", status=Status.IN_PROGRESS) + message.status = None + + xml = serializer(ChatHistory(messages=[message])) + restored = ChatHistory.from_rendered_prompt(xml) + + assert "status=" not in xml + assert restored[0].status is None + + def test_init_with_system_message_only(): system_msg = "test message" chat_history = ChatHistory(system_message=system_msg)