Unified message structure shared by executors and providers.
| 235 | |
| 236 | @dataclass |
| 237 | class Message: |
| 238 | """Unified message structure shared by executors and providers.""" |
| 239 | |
| 240 | role: MessageRole |
| 241 | content: MessageContent |
| 242 | name: Optional[str] = None |
| 243 | tool_call_id: Optional[str] = None |
| 244 | metadata: Dict[str, Any] = field(default_factory=dict) |
| 245 | tool_calls: List[ToolCallPayload] = field(default_factory=list) |
| 246 | keep: bool = False |
| 247 | preserve_role: bool = False |
| 248 | |
| 249 | def with_content(self, content: MessageContent) -> "Message": |
| 250 | """Return a shallow copy with updated content.""" |
| 251 | return Message( |
| 252 | role=self.role, |
| 253 | content=content, |
| 254 | name=self.name, |
| 255 | tool_call_id=self.tool_call_id, |
| 256 | metadata=dict(self.metadata), |
| 257 | tool_calls=list(self.tool_calls), |
| 258 | keep=self.keep, |
| 259 | preserve_role=self.preserve_role, |
| 260 | ) |
| 261 | |
| 262 | def with_role(self, role: MessageRole) -> "Message": |
| 263 | """Return a shallow copy with updated role.""" |
| 264 | return Message( |
| 265 | role=role, |
| 266 | content=self.content, |
| 267 | name=self.name, |
| 268 | tool_call_id=self.tool_call_id, |
| 269 | metadata=dict(self.metadata), |
| 270 | tool_calls=list(self.tool_calls), |
| 271 | keep=self.keep, |
| 272 | preserve_role=self.preserve_role, |
| 273 | ) |
| 274 | |
| 275 | def text_content(self) -> str: |
| 276 | """Best-effort string representation of the content.""" |
| 277 | if self.content is None: |
| 278 | return "" |
| 279 | if isinstance(self.content, str): |
| 280 | return self.content |
| 281 | # Some providers (e.g., multimodal) return list content; join textual parts. |
| 282 | parts = [] |
| 283 | for block in self.blocks(): |
| 284 | description = block.describe() |
| 285 | if description: |
| 286 | parts.append(description) |
| 287 | return "\n".join(parts) |
| 288 | |
| 289 | def blocks(self) -> List[MessageBlock]: |
| 290 | """Return content as a list of MessageBlock items.""" |
| 291 | if self.content is None: |
| 292 | return [] |
| 293 | if isinstance(self.content, str): |
| 294 | return [MessageBlock.text_block(self.content)] |
no outgoing calls
no test coverage detected