Single block of multimodal content.
| 102 | |
| 103 | @dataclass |
| 104 | class MessageBlock: |
| 105 | """Single block of multimodal content.""" |
| 106 | |
| 107 | type: MessageBlockType |
| 108 | text: Optional[str] = None |
| 109 | attachment: Optional[AttachmentRef] = None |
| 110 | data: Dict[str, Any] = field(default_factory=dict) |
| 111 | |
| 112 | def to_dict(self, include_data: bool = True) -> Dict[str, Any]: |
| 113 | payload: Dict[str, Any] = { |
| 114 | "type": self.type.value, |
| 115 | } |
| 116 | if self.text is not None: |
| 117 | payload["text"] = self.text |
| 118 | if self.attachment: |
| 119 | payload["attachment"] = self.attachment.to_dict(include_data=include_data) |
| 120 | if self.data: |
| 121 | payload["data"] = self.data |
| 122 | return payload |
| 123 | |
| 124 | @classmethod |
| 125 | def from_dict(cls, data: Dict[str, Any]) -> "MessageBlock": |
| 126 | raw_type = data.get("type") or MessageBlockType.TEXT.value |
| 127 | try: |
| 128 | block_type = MessageBlockType(raw_type) |
| 129 | except ValueError: |
| 130 | block_type = MessageBlockType.DATA |
| 131 | attachment_data = data.get("attachment") |
| 132 | attachment = None |
| 133 | if isinstance(attachment_data, dict): |
| 134 | attachment = AttachmentRef.from_dict(attachment_data) |
| 135 | return cls( |
| 136 | type=block_type, |
| 137 | text=data.get("text"), |
| 138 | attachment=attachment, |
| 139 | data=data.get("data") or {}, |
| 140 | ) |
| 141 | |
| 142 | @classmethod |
| 143 | def text_block(cls, text: str) -> "MessageBlock": |
| 144 | return cls(type=MessageBlockType.TEXT, text=text) |
| 145 | |
| 146 | def describe(self) -> str: |
| 147 | """Human-friendly summary for logging.""" |
| 148 | if self.type is MessageBlockType.TEXT and self.text: |
| 149 | return self.text |
| 150 | if self.attachment: |
| 151 | name = self.attachment.name or self.attachment.attachment_id |
| 152 | return f"[{self.type.value} attachment: {name}]" |
| 153 | if self.text: |
| 154 | return self.text |
| 155 | if "text" in self.data: |
| 156 | return str(self.data["text"]) |
| 157 | return f"[{self.type.value} block]" |
| 158 | |
| 159 | def copy(self) -> "MessageBlock": |
| 160 | return MessageBlock( |
| 161 | type=self.type, |
no outgoing calls
no test coverage detected