mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-16 09:40:30 +08:00
新增模块: - 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 - 不复制独立运行时逻辑,保持架构清晰 - 新版推荐使用顶层模块导入路径
77 lines
2.2 KiB
Python
77 lines
2.2 KiB
Python
"""旧版消息链兼容实现。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
|
|
from . import components as Comp
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class MessageChain:
|
|
chain: list[Comp.BaseMessageComponent] = field(default_factory=list)
|
|
use_t2i_: bool | None = None
|
|
type: str | None = None
|
|
|
|
def message(self, message: str) -> "MessageChain":
|
|
self.chain.append(Comp.Plain(text=message))
|
|
return self
|
|
|
|
def at(self, name: str, qq: str) -> "MessageChain":
|
|
self.chain.append(Comp.At(user_id=qq, user_name=name))
|
|
return self
|
|
|
|
def at_all(self) -> "MessageChain":
|
|
self.chain.append(Comp.AtAll())
|
|
return self
|
|
|
|
def error(self, message: str) -> "MessageChain":
|
|
self.chain.append(Comp.Plain(text=message))
|
|
return self
|
|
|
|
def url_image(self, url: str) -> "MessageChain":
|
|
self.chain.append(Comp.Image(file=url))
|
|
return self
|
|
|
|
def file_image(self, path: str) -> "MessageChain":
|
|
self.chain.append(Comp.Image(file=path))
|
|
return self
|
|
|
|
def base64_image(self, base64_str: str) -> "MessageChain":
|
|
self.chain.append(Comp.Image(file=base64_str))
|
|
return self
|
|
|
|
def use_t2i(self, use_t2i: bool) -> "MessageChain":
|
|
self.use_t2i_ = use_t2i
|
|
return self
|
|
|
|
def get_plain_text(self) -> str:
|
|
return " ".join(
|
|
component.text
|
|
for component in self.chain
|
|
if isinstance(component, Comp.Plain)
|
|
)
|
|
|
|
def squash_plain(self) -> "MessageChain":
|
|
if not self.chain:
|
|
return self
|
|
|
|
new_chain: list[Comp.BaseMessageComponent] = []
|
|
first_plain: Comp.Plain | None = None
|
|
plain_texts: list[str] = []
|
|
|
|
for component in self.chain:
|
|
if isinstance(component, Comp.Plain):
|
|
if first_plain is None:
|
|
first_plain = component
|
|
new_chain.append(component)
|
|
plain_texts.append(component.text)
|
|
else:
|
|
new_chain.append(component)
|
|
|
|
if first_plain is not None:
|
|
first_plain.text = "".join(plain_texts)
|
|
|
|
self.chain = new_chain
|
|
return self
|