ForcePilot/backend/package/yuxi/channel/sdk/actions/dispatch.py
Kris b438af3ba8 feat(channel-sdk): 新增完整的渠道SDK工具链
本提交新增了全渠道SDK核心模块:
1.  异步锁、目标解析、动作调度等基础工具
2.  消息动作注册与统一调度系统
3.  测试套件与契约测试框架
4.  完整的目标解析流水线与工具函数
5.  资源依赖注入与生命周期管理
2026-05-21 10:29:12 +08:00

83 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 {},
}