ForcePilot/backend/package/yuxi/channel/extensions/slack/actions.py
Kris bfc7755137 feat(channel): 添加 Slack 渠道扩展
新增 Slack 渠道扩展,支持在 Yuxi 平台中集成 Slack 团队协作平台。

包含以下功能模块:
- config: 渠道配置管理
- gateway: SSE/WebSocket 网关接入
- outbound: 外发消息管理
- streaming: 流式消息处理
- pairing: 用户配对与绑定
- security: 安全校验
- monitor: 渠道状态监控
- status: 会话状态管理
- actions: 交互动作处理
- interactive: 交互式消息
- commands: 斜杠指令
- threading: 线程管理
- mentions: @提及
- constants: 常量定义
- types: 类型定义
2026-05-21 11:43:23 +08:00

126 lines
5.7 KiB
Python

import logging
from yuxi.channel.extensions.slack.outbound import SlackOutbound
from yuxi.channel.protocols import MessageActionCapability, AgentToolParam
logger = logging.getLogger(__name__)
_SUPPORTED_ACTIONS = frozenset({"send", "edit", "unsend", "react", "pin", "member_info"})
class SlackActions:
def __init__(self):
self._outbound = SlackOutbound()
def get_message_actions(self) -> list[MessageActionCapability]:
return [
MessageActionCapability(
action="send",
description="Send a message to a Slack channel or user",
parameters=[
AgentToolParam(name="target_id", type="string", description="Channel ID or user ID", required=True),
AgentToolParam(name="content", type="string", description="Message text to send", required=True),
],
),
MessageActionCapability(
action="edit",
description="Edit a previously sent message",
parameters=[
AgentToolParam(name="target_id", type="string", description="Channel ID", required=True),
AgentToolParam(
name="message_id", type="string", description="Message timestamp (ts)", required=True
),
AgentToolParam(name="content", type="string", description="Updated message text", required=True),
],
),
MessageActionCapability(
action="unsend",
description="Delete a previously sent message",
parameters=[
AgentToolParam(name="target_id", type="string", description="Channel ID", required=True),
AgentToolParam(
name="message_id", type="string", description="Message timestamp (ts)", required=True
),
],
),
MessageActionCapability(
action="react",
description="Add an emoji reaction to a message",
parameters=[
AgentToolParam(name="target_id", type="string", description="Channel ID", required=True),
AgentToolParam(
name="message_id", type="string", description="Message timestamp (ts)", required=True
),
AgentToolParam(name="emoji", type="string", description="Emoji name without colons", required=True),
],
),
MessageActionCapability(
action="pin",
description="Pin a message to a channel",
parameters=[
AgentToolParam(name="target_id", type="string", description="Channel ID", required=True),
AgentToolParam(
name="message_id", type="string", description="Message timestamp (ts)", required=True
),
],
),
MessageActionCapability(
action="member_info",
description="Get information about a Slack user",
parameters=[
AgentToolParam(name="target_id", type="string", description="User ID", required=True),
],
),
]
async def execute_message_action(self, action: str, params: dict, context: dict) -> dict:
account_id = context.get("account_id")
try:
match action:
case "send":
await self._outbound.send_text(params["target_id"], params["content"], account_id=account_id)
return {"success": True, "result": None, "error": None}
case "edit":
result = await self._outbound.edit_message(
params["target_id"],
params["message_id"],
params["content"],
account_id=account_id,
)
return {"success": True, "result": {"ts": result}, "error": None}
case "unsend":
await self._outbound.delete_message(
params["target_id"], params["message_id"], account_id=account_id
)
return {"success": True, "result": None, "error": None}
case "react":
await self._outbound.send_reaction(
params["target_id"],
params["message_id"],
params["emoji"],
account_id=account_id,
)
return {"success": True, "result": None, "error": None}
case "pin":
await self._outbound.pin_message(params["target_id"], params["message_id"], account_id=account_id)
return {"success": True, "result": None, "error": None}
case "member_info":
client, _account = await self._outbound._get_client(account_id)
result = await client.users_info(user=params["target_id"])
return {"success": True, "result": result.data, "error": None}
case _:
return {"success": False, "result": None, "error": f"Unsupported action: {action}"}
except Exception as e:
logger.exception("Slack action '%s' failed", action)
return {"success": False, "result": None, "error": str(e)}
def supports_action(self, action: str) -> bool:
return action in _SUPPORTED_ACTIONS
def resolve_execution_mode(self, action: str) -> str:
return "direct"
def requires_trusted_requester_sender(self, action: str, tool_context=None) -> bool:
return action in ("unsend", "pin")