ForcePilot/backend/package/yuxi/channels/mixins.py
Kris 7a972055b7 feat: 新增渠道服务基础框架与核心工具类
新增大量渠道适配器相关的协议、策略、工具类与基础设施代码,包括:
1.  多协议定义:认证、消息、配置、网关等核心接口
2.  策略模块:上下文、群聊、去重、防抖等业务策略
3.  工具集:重试、去重、文本分块、消息格式化等SDK工具
4.  基础设施:外部进程管理、事件广播、熔断机制等
5.  账户与管道系统:账户管理、消息处理管道实现
6.  运行时服务:状态收集、维护任务、日志等后台服务
2026-05-12 00:53:57 +08:00

113 lines
3.4 KiB
Python

from __future__ import annotations
from typing import Any
from yuxi.channels.models import ChannelResponse, DeliveryResult
class OutboundMixin:
"""出站消息能力 Mixin — 提供 send_text/send_media_url 等默认实现"""
async def send_text(self, chat_id: str, content: str) -> DeliveryResult:
identity = self._build_simple_identity(chat_id)
response = ChannelResponse(identity=identity, content=content)
return await self.send(response)
async def send_media_url(self, chat_id: str, media_url: str, media_type: str = "image") -> DeliveryResult:
identity = self._build_simple_identity(chat_id)
response = ChannelResponse(identity=identity, content=media_url, message_type=media_type) # type: ignore[arg-type]
return await self.send(response)
def _build_simple_identity(self, chat_id: str) -> Any:
from yuxi.channels.models import ChannelIdentity
return ChannelIdentity(
channel_id=getattr(self, "channel_id", ""),
channel_type=getattr(self, "channel_type", None),
channel_user_id="",
channel_chat_id=chat_id,
)
def sanitize_text(self, text: str) -> str:
return text
def chunker(self, text: str, limit: int) -> list[str]:
if len(text) <= limit:
return [text]
chunks = []
for i in range(0, len(text), limit):
chunks.append(text[i : i + limit])
return chunks
class MediaMixin:
"""媒体发送能力 Mixin"""
async def send_media(self, chat_id: str, media_type: str, data: Any) -> DeliveryResult:
raise NotImplementedError
class ReactionMixin:
"""表情回应能力 Mixin"""
async def send_reaction(self, chat_id: str, msg_id: str, emoji: str) -> DeliveryResult:
raise NotImplementedError
async def remove_reaction(self, chat_id: str, msg_id: str, emoji: str) -> DeliveryResult:
raise NotImplementedError
class EditDeleteMixin:
"""消息编辑/删除能力 Mixin"""
async def edit_message(self, chat_id: str, msg_id: str, content: str) -> DeliveryResult:
raise NotImplementedError
async def delete_message(self, chat_id: str, msg_id: str) -> DeliveryResult:
raise NotImplementedError
class PinMixin:
"""消息置顶/取消置顶能力 Mixin"""
async def pin_message(self, chat_id: str, msg_id: str) -> DeliveryResult:
raise NotImplementedError
async def unpin_message(self, chat_id: str, msg_id: str) -> DeliveryResult:
raise NotImplementedError
async def list_pins(self, chat_id: str) -> list[dict]:
raise NotImplementedError
class UserInfoMixin:
"""用户信息获取能力 Mixin"""
async def get_user_info(self, channel_user_id: str) -> dict[str, Any]:
raise NotImplementedError
async def download_media(self, file_id: str) -> bytes:
raise NotImplementedError
class PollMixin:
"""投票能力 Mixin"""
async def create_poll(self, chat_id: str, question: str, options: list[str]) -> DeliveryResult:
raise NotImplementedError
class StreamingMixin:
"""流式输出能力 Mixin"""
async def send_stream_chunk(self, chat_id: str, msg_id: str, chunk: str, finished: bool) -> DeliveryResult:
raise NotImplementedError
@property
def streaming_modes(self) -> list[str]:
return ["off"]
@property
def block_streaming(self) -> bool:
return False