@@ -789,8 +789,9 @@ class TextReasoningContent(BaseContent):
789789
790790 def __init__ (
791791 self ,
792- text : str ,
792+ text : str | None ,
793793 * ,
794+ protected_data : str | None = None ,
794795 additional_properties : dict [str , Any ] | None = None ,
795796 raw_representation : Any | None = None ,
796797 annotations : Sequence [Annotations | MutableMapping [str , Any ]] | None = None ,
@@ -802,6 +803,16 @@ def __init__(
802803 text: The text content represented by this instance.
803804
804805 Keyword Args:
806+ protected_data: This property is used to store data from a provider that should be roundtripped back to the
807+ provider but that is not intended for human consumption. It is often encrypted or otherwise redacted
808+ information that is only intended to be sent back to the provider and not displayed to the user. It's
809+ possible for a TextReasoningContent to contain only `protected_data` and have an empty `text` property.
810+ This data also may be associated with the corresponding `text`, acting as a validation signature for it.
811+
812+ Note that whereas `text` can be provider agnostic, `protected_data` is provider-specific, and is likely
813+ to only be understood by the provider that created it. The data is often represented as a more complex
814+ object, so it should be serialized to a string before storing so that the whole object is easily
815+ serializable without loss.
805816 additional_properties: Optional additional properties associated with the content.
806817 raw_representation: Optional raw representation of the content.
807818 annotations: Optional annotations associated with the content.
@@ -814,6 +825,7 @@ def __init__(
814825 ** kwargs ,
815826 )
816827 self .text = text
828+ self .protected_data = protected_data
817829 self .type : Literal ["text_reasoning" ] = "text_reasoning"
818830
819831 def __add__ (self , other : "TextReasoningContent" ) -> "TextReasoningContent" :
@@ -846,13 +858,18 @@ def __add__(self, other: "TextReasoningContent") -> "TextReasoningContent":
846858 else :
847859 annotations = self .annotations + other .annotations
848860
861+ # Replace protected data.
862+ # Discussion: https://github.com/microsoft/agent-framework/pull/2950#discussion_r2634345613
863+ protected_data = other .protected_data or self .protected_data
864+
849865 # Create new instance using from_dict for proper deserialization
850866 result_dict = {
851- "text" : self .text + other .text ,
867+ "text" : ( self .text or "" ) + ( other .text or "" ) if self . text is not None or other . text is not None else None ,
852868 "type" : "text_reasoning" ,
853869 "annotations" : [ann .to_dict (exclude_none = False ) for ann in annotations ] if annotations else None ,
854870 "additional_properties" : {** (self .additional_properties or {}), ** (other .additional_properties or {})},
855871 "raw_representation" : raw_representation ,
872+ "protected_data" : protected_data ,
856873 }
857874 return TextReasoningContent .from_dict (result_dict )
858875
@@ -869,7 +886,9 @@ def __iadd__(self, other: "TextReasoningContent") -> Self:
869886 raise TypeError ("Incompatible type" )
870887
871888 # Concatenate text
872- self .text += other .text
889+ if self .text is not None or other .text is not None :
890+ self .text = (self .text or "" ) + (other .text or "" )
891+ # if both are None, should keep as None
873892
874893 # Merge additional properties (self takes precedence)
875894 if self .additional_properties is None :
@@ -888,6 +907,11 @@ def __iadd__(self, other: "TextReasoningContent") -> Self:
888907 self .raw_representation if isinstance (self .raw_representation , list ) else [self .raw_representation ]
889908 ) + (other .raw_representation if isinstance (other .raw_representation , list ) else [other .raw_representation ])
890909
910+ # Replace protected data.
911+ # Discussion: https://github.com/microsoft/agent-framework/pull/2950#discussion_r2634345613
912+ if other .protected_data is not None :
913+ self .protected_data = other .protected_data
914+
891915 # Merge annotations
892916 if other .annotations :
893917 if self .annotations is None :
0 commit comments