# Copyright (c) Microsoft. All rights reserved. """Reasoning content model.""" from html import unescape from typing import ClassVar, Literal, TypeVar from xml.etree.ElementTree import Element # nosec from pydantic import Field from semantic_kernel.contents.const import REASONING_CONTENT_TAG, ContentTypes from semantic_kernel.contents.kernel_content import KernelContent from semantic_kernel.exceptions.content_exceptions import ContentInitializationError _T = TypeVar("_T", bound="ReasoningContent") class ReasoningContent(KernelContent): """Represents reasoning content. Exposes a human-readable reasoning ``text``. Any provider-specific fields (for example: ids, encrypted blobs, statuses, token info) must be carried in ``metadata`` on the base ``KernelContent``. Attributes: content_type: Literal identifying this instance as reasoning content. tag: XML tag name used when serializing to/from XML. text: The reasoning text to surface to callers. Methods: __str__: Return the reasoning text. to_element: Serialize to an XML Element using ``tag`` and ``text``. from_element: Deserialize from an XML Element into a ReasoningContent. to_dict: Serialize to a dict suitable for message payloads. """ content_type: Literal[ContentTypes.REASONING_CONTENT] = Field(ContentTypes.REASONING_CONTENT, init=False) tag: ClassVar[str] = REASONING_CONTENT_TAG text: str | None = None def __str__(self) -> str: """Return the text of the reasoning content.""" return self.text or "" def to_element(self) -> Element: """Convert the instance to an XML Element.""" element = Element(self.tag) element.text = self.text return element @classmethod def from_element(cls: type[_T], element: Element) -> _T: """Create an instance from an XML Element.""" if element.tag != cls.tag: raise ContentInitializationError(f"Element tag is not {cls.tag}") # pragma: no cover return cls(text=unescape(element.text) if element.text else "") def to_dict(self) -> dict[str, str]: """Convert the instance to a dictionary suitable for message serialization.""" return {"type": "reasoning", "text": self.text or ""}