Files
AstrBot/src-new/astrbot_sdk/events.py
whatevertogo cdf72b75a4 feat: 实现 v4 API 兼容层,支持旧版插件导入路径
新增模块:
- api/basic/: AstrBotConfig, BaseConversationManager, Conversation
- api/event/: AstrMessageEvent, AstrBotMessage, EventType, MessageType,
  MessageSession, EventResult 等核心事件类型
- api/message/: MessageChain 及所有消息组件 (Plain, At, Image, File 等)
- api/platform/: PlatformMetadata 平台元数据类型
- api/provider/: LLMResponse 提供者响应实体
- api/star/star.py: StarMetadata 插件元数据类型

更新模块:
- api/__init__.py: 导出所有子模块
- api/components/: 扩展 Command 兼容性
- api/event/filter.py: 增强 filter 装饰器兼容性
- context.py, decorators.py, events.py: 顶层兼容入口

测试更新:
- test_api_event_filter.py: 验证 filter 兼容性
- test_api_modules.py: 验证新模块可导入
- test_handler_dispatcher.py: 验证处理器分发

文档更新:
- AGENTS.md/CLAUDE.md: 添加兼容层设计说明,避免重复造轮子

设计原则:
- 兼容层通过 thin re-export 方式暴露旧版 API
- 不复制独立运行时逻辑,保持架构清晰
- 新版推荐使用顶层模块导入路径
2026-03-13 03:17:03 +08:00

89 lines
2.6 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.
"""v4 原生事件对象。
顶层 ``MessageEvent`` 保持精简,只承载 v4 运行时真正需要的基础能力。
旧版 ``AstrMessageEvent`` 的便捷方法与结果对象由
``astrbot_sdk.api.event`` 兼容层承接,而不是继续塞回顶层事件类型。
"""
from __future__ import annotations
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
from .context import Context
@dataclass(slots=True)
class PlainTextResult:
text: str
ReplyHandler = Callable[[str], Awaitable[None]]
class MessageEvent:
def __init__(
self,
*,
text: str = "",
user_id: str | None = None,
group_id: str | None = None,
platform: str | None = None,
session_id: str | None = None,
raw: dict[str, Any] | None = None,
context: "Context | None" = None,
reply_handler: ReplyHandler | None = None,
) -> None:
self.text = text
self.user_id = user_id
self.group_id = group_id
self.platform = platform
self.session_id = session_id or group_id or user_id or ""
self.raw = raw or {}
self._reply_handler = reply_handler
if self._reply_handler is None and context is not None:
self._reply_handler = lambda text: context.platform.send(
self.session_id, text
)
@classmethod
def from_payload(
cls,
payload: dict[str, Any],
*,
context: "Context | None" = None,
reply_handler: ReplyHandler | None = None,
) -> "MessageEvent":
return cls(
text=str(payload.get("text", "")),
user_id=payload.get("user_id"),
group_id=payload.get("group_id"),
platform=payload.get("platform"),
session_id=payload.get("session_id"),
raw=payload,
context=context,
reply_handler=reply_handler,
)
def to_payload(self) -> dict[str, Any]:
return {
"text": self.text,
"user_id": self.user_id,
"group_id": self.group_id,
"platform": self.platform,
"session_id": self.session_id,
}
async def reply(self, text: str) -> None:
if self._reply_handler is None:
raise RuntimeError("MessageEvent 未绑定 reply handler无法 reply")
await self._reply_handler(text)
def bind_reply_handler(self, reply_handler: ReplyHandler) -> None:
self._reply_handler = reply_handler
def plain_result(self, text: str) -> PlainTextResult:
return PlainTextResult(text=text)