83 lines
2.4 KiB
Python
83 lines
2.4 KiB
Python
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
import logging
|
|||
|
|
from dataclasses import dataclass, field
|
|||
|
|
|
|||
|
|
from yuxi.channel.sdk.actions.names import MessageAction
|
|||
|
|
|
|||
|
|
logger = logging.getLogger(__name__)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class DispatchContext:
|
|||
|
|
"""动作调度上下文(对齐 OpenClaw ChannelMessageActionContext)。"""
|
|||
|
|
|
|||
|
|
channel_type: str
|
|||
|
|
action: str
|
|||
|
|
params: dict = field(default_factory=dict)
|
|||
|
|
account_id: str = "default"
|
|||
|
|
requester_sender_id: str | None = None
|
|||
|
|
sender_is_owner: bool = False
|
|||
|
|
session_key: str | None = None
|
|||
|
|
agent_id: str | None = None
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def dispatch_message_action(ctx: DispatchContext) -> dict:
|
|||
|
|
"""统一消息动作调度入口。
|
|||
|
|
|
|||
|
|
执行流程(对齐 OpenClaw dispatchChannelMessageAction):
|
|||
|
|
1. 获取插件 → 失败则返回
|
|||
|
|
2. 获取 actions adapter → 失败则返回
|
|||
|
|
3. 信任发送者检查 → 失败则返回
|
|||
|
|
4. supports_action 检查 → 不支持则返回
|
|||
|
|
5. 执行
|
|||
|
|
"""
|
|||
|
|
from yuxi.channel.plugins.registry import ChannelPluginRegistry
|
|||
|
|
|
|||
|
|
plugin = ChannelPluginRegistry.get(ctx.channel_type)
|
|||
|
|
if plugin is None:
|
|||
|
|
return {
|
|||
|
|
"success": False,
|
|||
|
|
"error": f"渠道 {ctx.channel_type} 未注册",
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
adapter = getattr(plugin, "actions", None)
|
|||
|
|
if adapter is None:
|
|||
|
|
return {
|
|||
|
|
"success": False,
|
|||
|
|
"error": f"渠道 {ctx.channel_type} 未配置 MessageActionRegistry",
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (
|
|||
|
|
adapter.requires_trusted_sender(ctx.action)
|
|||
|
|
and not ctx.requester_sender_id
|
|||
|
|
):
|
|||
|
|
return {
|
|||
|
|
"success": False,
|
|||
|
|
"error": f"Action '{ctx.action}' requires trusted sender identity",
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if not adapter.supports_action(ctx.action):
|
|||
|
|
return {
|
|||
|
|
"success": False,
|
|||
|
|
"error": f"渠道 {ctx.channel_type} 不支持 action: {ctx.action}",
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
result = await adapter.execute_action(
|
|||
|
|
ctx.action,
|
|||
|
|
params=ctx.params,
|
|||
|
|
context={
|
|||
|
|
"channel_type": ctx.channel_type,
|
|||
|
|
"account_id": ctx.account_id,
|
|||
|
|
"requester_sender_id": ctx.requester_sender_id,
|
|||
|
|
"sender_is_owner": ctx.sender_is_owner,
|
|||
|
|
"session_key": ctx.session_key,
|
|||
|
|
"agent_id": ctx.agent_id,
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
"success": result.get("success", False),
|
|||
|
|
"message": result.get("error", ""),
|
|||
|
|
"data": result if result.get("success") else {},
|
|||
|
|
}
|