From 5ceeae2f5a4fae5754917b82152e545938a7c68c Mon Sep 17 00:00:00 2001 From: CRYPTONIKAV <29835619+CRYPTONIKAV@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:08:36 -0400 Subject: [PATCH] fix: write enum value in annotation XML type attribute --- .../contents/annotation_content.py | 2 +- .../contents/streaming_annotation_content.py | 2 +- .../unit/contents/test_annotation_content.py | 17 +++++++++++++++++ .../test_streaming_annotation_content.py | 17 +++++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/python/semantic_kernel/contents/annotation_content.py b/python/semantic_kernel/contents/annotation_content.py index e1a7854450e8..01a9fe57a7ab 100644 --- a/python/semantic_kernel/contents/annotation_content.py +++ b/python/semantic_kernel/contents/annotation_content.py @@ -56,7 +56,7 @@ def to_element(self) -> Element: """Convert the annotation content to an Element.""" element = Element(self.tag) if self.citation_type: - element.set("type", self.citation_type) + element.set("type", self.citation_type.value) if self.file_id: element.set("file_id", self.file_id) if self.quote: diff --git a/python/semantic_kernel/contents/streaming_annotation_content.py b/python/semantic_kernel/contents/streaming_annotation_content.py index 9100ef8489b8..c4af2fd44bcc 100644 --- a/python/semantic_kernel/contents/streaming_annotation_content.py +++ b/python/semantic_kernel/contents/streaming_annotation_content.py @@ -47,7 +47,7 @@ def to_element(self) -> Element: """Convert the annotation content to an Element.""" element = Element(self.tag) if self.citation_type: - element.set("type", self.citation_type) + element.set("type", self.citation_type.value) if self.file_id: element.set("file_id", self.file_id) if self.quote: diff --git a/python/tests/unit/contents/test_annotation_content.py b/python/tests/unit/contents/test_annotation_content.py index d80ffe293898..08a57ec6c935 100644 --- a/python/tests/unit/contents/test_annotation_content.py +++ b/python/tests/unit/contents/test_annotation_content.py @@ -141,3 +141,20 @@ def test_to_dict_call(annotation): "text": expected_text, } assert annotation.to_dict() == expected_dict + + +def test_element_roundtrip_through_serialized_xml(): + """Citation types must survive serialize -> parse, not just memory (#14590).""" + from xml.etree.ElementTree import fromstring, tostring + + annotation = AnnotationContent( + file_id="file-1", + quote="q", + start_index=4, + end_index=7, + type=CitationType.FILE_CITATION.value, + ) + element = annotation.to_element() + assert element.get("type") == "file_citation" + reparsed = AnnotationContent.from_element(fromstring(tostring(element))) + assert reparsed == annotation diff --git a/python/tests/unit/contents/test_streaming_annotation_content.py b/python/tests/unit/contents/test_streaming_annotation_content.py index 0513a7e172d0..b57a6f15f1a3 100644 --- a/python/tests/unit/contents/test_streaming_annotation_content.py +++ b/python/tests/unit/contents/test_streaming_annotation_content.py @@ -144,3 +144,20 @@ def test_to_dict_call(annotation): "text": expected_text, } assert annotation.to_dict() == expected_dict + + +def test_element_roundtrip_through_serialized_xml(): + """Citation types must survive serialize -> parse, not just memory (#14590).""" + from xml.etree.ElementTree import fromstring, tostring + + annotation = StreamingAnnotationContent( + file_id="file-1", + quote="q", + start_index=4, + end_index=7, + citation_type=CitationType.FILE_CITATION.value, + ) + element = annotation.to_element() + assert element.get("type") == "file_citation" + reparsed = StreamingAnnotationContent.from_element(fromstring(tostring(element))) + assert reparsed == annotation