from __future__ import annotations from typing import Any SIGNAL_MESSAGE_ACTIONS = { "send": { "description": "Send a text message to a Signal chat", "params": { "recipient": {"type": "str", "description": "Recipient E.164 number or group:ID"}, "message_body": {"type": "str", "description": "Message content"}, "reply_to_id": {"type": "str", "description": "Message ID to reply to"}, }, }, "react": { "description": "React to a Signal message with an emoji", "params": { "recipient": {"type": "str", "description": "Recipient E.164 number or group:ID"}, "target_sent_timestamp": {"type": "int", "description": "Timestamp of target message"}, "emoji": {"type": "str", "description": "Emoji reaction"}, "remove": {"type": "bool", "description": "Whether to remove the reaction"}, }, }, "edit": { "description": "Edit a previously sent message", "params": { "recipient": {"type": "str", "description": "Recipient E.164 number or group:ID"}, "target_sent_timestamp": {"type": "int", "description": "Timestamp of target message"}, "new_body": {"type": "str", "description": "New message content"}, }, }, "delete": { "description": "Delete a previously sent message", "params": { "recipient": {"type": "str", "description": "Recipient E.164 number or group:ID"}, "timestamps": {"type": "list[int]", "description": "Timestamps of messages to delete"}, }, }, "send_media": { "description": "Send a media file (image/video/audio/file) to a Signal chat", "params": { "recipient": {"type": "str", "description": "Recipient E.164 number or group:ID"}, "media_data": {"type": "bytes", "description": "Base64-encoded media data"}, "media_type": {"type": "str", "description": "Media type: image/video/audio/file"}, "filename": {"type": "str", "description": "Filename"}, "caption": {"type": "str", "description": "Caption text"}, }, }, "send_typing": { "description": "Send typing indicator to a Signal chat", "params": { "recipient": {"type": "str", "description": "Recipient E.164 number or group:ID"}, }, }, "send_read_receipt": { "description": "Send read receipt for messages", "params": { "recipient": {"type": "str", "description": "Recipient E.164 number or group:ID"}, "timestamps": {"type": "list[int]", "description": "Timestamps of messages to mark as read"}, }, }, "get_user_info": { "description": "Get identity info for a Signal user", "params": { "channel_user_id": {"type": "str", "description": "E.164 number of the user"}, }, }, } def describe_message_tools(actions_config: dict[str, Any] | None = None) -> list[dict[str, Any]]: enabled = actions_config or {} tools = [] for action_name, action_def in SIGNAL_MESSAGE_ACTIONS.items(): if enabled.get(action_name, True): tools.append( { "name": f"signal_{action_name}", "description": action_def["description"], "parameters": action_def["params"], } ) return tools