Add architecture doc and refine API compat

- Add PROJECT_ARCHITECTURE.md documenting architecture, compat surface,
  and testing notes.
- Update astrbot_sdk.api.__init__ to clarify it is a compatibility
  implementation layer, not a simple facade, and list migration targets.
- Normalize platform in AstrMessageEvent.to_payload to emit a string id
  by using get_platform_id().
This commit is contained in:
whatevertogo
2026-03-14 17:17:25 +08:00
parent 1672bc3227
commit 89d3e2f014
3 changed files with 1009 additions and 9 deletions

View File

@@ -1,9 +1,18 @@
"""过渡期 ``astrbot_sdk.api`` 兼容 facade
"""过渡期兼容实现层 ``astrbot_sdk.api``。
这个包仅用于承接旧插件的历史导入路径,方便外部插件逐步迁移到 v4 顶层 API
它不是新的推荐入口,也不应继续承载新的运行时实现逻辑。
这个包承载旧插件所需的兼容模型与逻辑实现,供 legacy 执行路径直接使用
它不是简单的重导出层,而是维护旧语义所必需的实现模块:
迁移目标:
- ``astrbot_sdk.api.event````AstrMessageEvent``、``filter``、``MessageEventResult``
- ``astrbot_sdk.api.message````MessageChain``、消息组件模型
- ``astrbot_sdk.api.provider````LLMResponse`` 兼容实体
- ``astrbot_sdk.api.basic``、``platform``、``components``:配置、平台、组件兼容面
与 ``src-new/astrbot/`` 对比:
- 此包(``astrbot_sdk.api``)是真正的兼容实现,包含运行时逻辑
- ``src-new/astrbot/`` 是薄 facade只做导入路径转发
迁移目标(仅在有明确迁移计划时移除):
- ``astrbot_sdk.context.Context``
- ``astrbot_sdk.events.MessageEvent``
@@ -12,10 +21,9 @@
维护约束:
- ``astrbot_sdk.api.*`` 保持为受控兼容面,后续会随迁移推进逐步移除
- 包内模块优先作为 facade / 重导出层存在,但允许少量必须保留行为的 compat 模块
- compat 真实行为应尽量收口到顶层 private compat 模块
- 新增运行时逻辑应优先放在 v4 主路径,由 compat 层按需转发或包装
- 新增运行时逻辑优先放在 v4 主路径,由此层按需包装
- compat 真实执行边界收口在顶层私有模块(``_legacy_runtime.py`` 等)
- 新插件应直接使用 ``astrbot_sdk`` 顶层 v4 API
"""
from loguru import logger

View File

@@ -137,7 +137,18 @@ class AstrMessageEvent(MessageEvent):
session_id=self.session_id,
)
self.unified_msg_origin = str(self.session)
self.platform = self.platform_meta or self.platform
def to_payload(self) -> dict[str, Any]:
"""Override to guarantee ``platform`` in the wire payload is always a string id.
``MessageEvent.to_payload()`` serialises ``self.platform`` verbatim.
Since ``AstrMessageEvent`` may receive a ``PlatformMetadata`` object
via ``platform_meta``, we normalise it through ``get_platform_id()``
so the wire format stays a clean ``str | None``.
"""
payload = super().to_payload()
payload["platform"] = self.get_platform_id() or None
return payload
@classmethod
def from_payload(