diff --git a/python/semantic_kernel/contents/function_result_content.py b/python/semantic_kernel/contents/function_result_content.py index 4da3162936..301bc53b64 100644 --- a/python/semantic_kernel/contents/function_result_content.py +++ b/python/semantic_kernel/contents/function_result_content.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any, ClassVar, Literal, TypeVar from xml.etree.ElementTree import Element # nosec -from pydantic import Field +from pydantic import Field, field_serializer from typing_extensions import deprecated from semantic_kernel.contents.const import FUNCTION_RESULT_CONTENT_TAG, TEXT_CONTENT_TAG, ContentTypes @@ -169,3 +169,8 @@ class FunctionResultContent(KernelContent): def split_name(self) -> list[str]: """Split the name into a plugin and function name.""" return [self.plugin_name or "", self.function_name] + + @field_serializer("result") + def serialize_result(self, value: Any) -> str: + """Serialize the result.""" + return str(value) diff --git a/python/tests/unit/contents/test_chat_history.py b/python/tests/unit/contents/test_chat_history.py index d4b4a3bd07..ac69ee5ef9 100644 --- a/python/tests/unit/contents/test_chat_history.py +++ b/python/tests/unit/contents/test_chat_history.py @@ -572,3 +572,21 @@ def test_to_from_file(chat_history: ChatHistory, tmp_path): assert chat_history_2.messages[2] == chat_history.messages[2] assert chat_history_2.messages[3] == chat_history.messages[3] assert chat_history_2.messages[4] == chat_history.messages[4] + + +def test_chat_history_serialize(chat_history: ChatHistory): + class CustomResultClass: + def __init__(self, result): + self.result = result + + def __str__(self) -> str: + return self.result + + custom_result = CustomResultClass(result="CustomResultTestValue") + chat_history.add_system_message("You are an AI assistant") + chat_history.add_user_message("What is the weather in Seattle?") + chat_history.add_assistant_message( + [FunctionCallContent(id="test1", name="WeatherPlugin-GetWeather", arguments='{{ "location": "Seattle" }}')] + ) + chat_history.add_tool_message([FunctionResultContent(id="test1", result=custom_result)]) + assert "CustomResultTestValue" in chat_history.serialize() diff --git a/python/tests/unit/contents/test_function_result_content.py b/python/tests/unit/contents/test_function_result_content.py index e7d86a1578..a745c6c255 100644 --- a/python/tests/unit/contents/test_function_result_content.py +++ b/python/tests/unit/contents/test_function_result_content.py @@ -83,3 +83,19 @@ def test_to_cmc(unwrap: bool): assert cmc.items[0].text == "test-result" else: assert cmc.items[0].result == "test-result" + + +def test_serialize(): + class CustomResultClass: + def __init__(self, result): + self.result = result + + def __str__(self) -> str: + return self.result + + custom_result = CustomResultClass(result="test") + frc = FunctionResultContent(id="test", name="test-function", result=custom_result) + assert ( + frc.model_dump_json(exclude_none=True) + == """{"metadata":{},"content_type":"function_result","id":"test","result":"test","name":"test-function","function_name":"function","plugin_name":"test"}""" # noqa: E501 + )