From 9f00bf7ad9ba445699496922d51ec45cec945087 Mon Sep 17 00:00:00 2001 From: fei <204683769+feiiiiii5@users.noreply.github.com> Date: Sun, 20 Sep 2026 13:23:58 +0800 Subject: [PATCH] fix(python): keep ChatMessageContent.to_prompt a str when encoding is set to_prompt passed encoding=self.encoding or "unicode" to ElementTree.tostring, so any message carrying an encoding returned bytes with an XML declaration instead of the prompt string, while every other tostring call site in the contents package hardcodes "unicode". jinja2/handlebars _message_to_prompt wrap the result in str(), which then embeds a b'...' literal in the rendered prompt. --- .../contents/chat_message_content.py | 6 +++++- .../unit/contents/test_chat_message_content.py | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/python/semantic_kernel/contents/chat_message_content.py b/python/semantic_kernel/contents/chat_message_content.py index 13376106e8b1..80c15defb539 100644 --- a/python/semantic_kernel/contents/chat_message_content.py +++ b/python/semantic_kernel/contents/chat_message_content.py @@ -294,11 +294,15 @@ def from_element(cls, element: Element) -> "ChatMessageContent": def to_prompt(self) -> str: """Convert the ChatMessageContent to a prompt. + The encoding attribute of the content is not used here, + this always returns a string, the encoding is only relevant + for the actual text content, not for the prompt representation. + Returns: str - The prompt from the ChatMessageContent. """ root = self.to_element() - return ElementTree.tostring(root, encoding=self.encoding or "unicode", short_empty_elements=False) + return ElementTree.tostring(root, encoding="unicode", short_empty_elements=False) def to_dict(self, role_key: str = "role", content_key: str = "content") -> dict[str, Any]: """Serialize the ChatMessageContent to a dictionary. diff --git a/python/tests/unit/contents/test_chat_message_content.py b/python/tests/unit/contents/test_chat_message_content.py index a4734dfe4614..5d409f06f073 100644 --- a/python/tests/unit/contents/test_chat_message_content.py +++ b/python/tests/unit/contents/test_chat_message_content.py @@ -152,6 +152,24 @@ def test_cmc_to_prompt(): assert prompt == 'Hello, world!' +@pytest.mark.parametrize( + "encoding", + [ + pytest.param("utf-8", id="utf8"), + pytest.param("ascii", id="ascii"), + pytest.param("latin-1", id="latin1"), + ], +) +def test_cmc_to_prompt_with_encoding(encoding: str): + """The encoding of the content should not change the type or shape of the prompt.""" + message = ChatMessageContent(role=AuthorRole.USER, content="Hello, wörld!", encoding=encoding) + prompt = message.to_prompt() + assert isinstance(prompt, str) + assert not prompt.startswith("