ForcePilot/backend/package/yuxi/channels/adapters/signal/message_actions.py
Kris b47c6126e6 refactor(signal-adapter): 整理代码结构与导入顺序,新增批量消息操作支持
1.  调整多个文件的导入顺序与格式,统一代码风格
2.  在security模块新增允许列表持久化存储逻辑
3.  新增send_sticker/send_voice/send_silent/pin/unpin等消息操作
4.  新增群组创建/删除/成员管理方法
5.  重构流式消息处理逻辑,提取为独立工具类
6.  修复配置校验与安全检查的逻辑顺序问题
7.  优化初始化流程,新增配置校验步骤
2026-05-13 16:14:06 +08:00

118 lines
4.9 KiB
Python

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"},
},
},
"send_sticker": {
"description": "Send a sticker to a Signal chat",
"params": {
"recipient": {"type": "str", "description": "Recipient E.164 number or group:ID"},
"pack_id": {"type": "str", "description": "Sticker pack ID"},
"sticker_id": {"type": "int", "description": "Sticker ID within the pack"},
},
},
"send_voice": {
"description": "Send a voice message to a Signal chat",
"params": {
"recipient": {"type": "str", "description": "Recipient E.164 number or group:ID"},
"audio_data": {"type": "bytes", "description": "Base64-encoded audio/ogg data"},
},
},
"send_silent": {
"description": "Send a silent text message without notification",
"params": {
"recipient": {"type": "str", "description": "Recipient E.164 number or group:ID"},
"message_body": {"type": "str", "description": "Message content"},
},
},
"pin": {
"description": "Pin a message to the top of a Signal chat",
"params": {
"recipient": {"type": "str", "description": "Recipient E.164 number or group:ID"},
"timestamp": {"type": "int", "description": "Timestamp of the message to pin"},
},
},
"unpin": {
"description": "Unpin a previously pinned message",
"params": {
"recipient": {"type": "str", "description": "Recipient E.164 number or group:ID"},
},
},
}
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