from __future__ import annotations from typing import Any from core.protocol import ( Attachment, IncomingCallback, IncomingCommand, IncomingEvent, IncomingMessage, ) PLATFORM = "matrix" def extract_attachments(event: Any) -> list[Attachment]: source = getattr(event, "source", {}) or {} content = source.get("content", {}) or getattr(event, "content", {}) or {} msgtype = getattr(event, "msgtype", None) if msgtype is None: msgtype = content.get("msgtype") url = content.get("url") or getattr(event, "url", None) filename = content.get("body") or getattr(event, "body", None) mime_type = content.get("mimetype") or getattr(event, "mimetype", None) if mime_type is None: info = content.get("info") or {} if isinstance(info, dict): mime_type = info.get("mimetype") if msgtype == "m.image": return [ Attachment( type="image", url=url, filename=filename, mime_type=mime_type, ) ] if msgtype == "m.file": return [ Attachment( type="document", url=url, filename=filename, mime_type=mime_type, ) ] if msgtype == "m.audio": return [ Attachment( type="audio", url=url, filename=filename, mime_type=mime_type, ) ] if msgtype == "m.video": return [ Attachment( type="video", url=url, filename=filename, mime_type=mime_type, ) ] return [] def from_command(body: str, sender: str, chat_id: str, room_id: str | None = None) -> IncomingEvent: raw = body.lstrip("!").strip() parts = raw.split() command = parts[0].lower() if parts else "" args = parts[1:] if command in {"yes", "no"}: action = "confirm" if command == "yes" else "cancel" return IncomingCallback( user_id=sender, platform=PLATFORM, chat_id=chat_id, action=action, payload={ "source": "command", "command": command, **({"room_id": room_id} if room_id is not None else {}), }, ) if command == "list" and not args: return IncomingCommand( user_id=sender, platform=PLATFORM, chat_id=chat_id, command="matrix_list_attachments", args=[], ) if command == "remove" and len(args) == 1: return IncomingCommand( user_id=sender, platform=PLATFORM, chat_id=chat_id, command="matrix_remove_attachment", args=[args[0]], ) aliases = { "skills": "settings_skills", "connectors": "settings_connectors", "soul": "settings_soul", "safety": "settings_safety", "plan": "settings_plan", "status": "settings_status", "whoami": "settings_whoami", } command = aliases.get(command, command) return IncomingCommand( user_id=sender, platform=PLATFORM, chat_id=chat_id, command=command, args=args, ) def from_room_event(event: Any, room_id: str, chat_id: str) -> IncomingEvent | None: body = (getattr(event, "body", None) or "").strip() sender = getattr(event, "sender", "") if body.startswith("!"): return from_command(body, sender=sender, chat_id=chat_id, room_id=room_id) return IncomingMessage( user_id=sender, platform=PLATFORM, chat_id=chat_id, text=body, attachments=extract_attachments(event), reply_to=getattr(event, "replyto_event_id", None), )