本次提交对频道模块进行了全面重构并新增多项核心功能: 1. 优化适配器状态获取逻辑,修复状态返回空值问题 2. 新增4种频道异常类型,完善错误处理体系 3. 大幅精简Mixin类,移除冗余的抽象方法定义 4. 重构适配器注册系统,统一注册入口并新增内置适配器加载方法 5. 扩展插件系统,新增更多元数据配置项支持 6. 新增线程类型、会话范围等模型定义,扩展事件类型枚举 7. 优化用户映射逻辑,使用PostgreSQL upsert避免重复创建 8. 新增历史消息注入模块,支持多格式历史格式化与缓存管理 9. 新增线程能力配置与各平台预置适配配置 10. 新增线程绑定管理器,支持多类型线程绑定生命周期管理 11. 重构__init__.py,整理导出模块与类型 12. 扩展基础适配器类,新增凭证解析、状态存储等核心方法 13. 重写消息路由器,支持按频道加载策略、安全校验与多命令处理 14. 新增/history、/context、/summary等交互命令实现 15. 优化消息记录与统计逻辑,完善路由调度链路
215 lines
5.9 KiB
Python
215 lines
5.9 KiB
Python
from __future__ import annotations
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class ThreadCapabilities(BaseModel):
|
|
supports_native_threads: bool = False
|
|
supports_topics: bool = False
|
|
supports_reply_chains: bool = False
|
|
supports_simulated_threads: bool = False
|
|
max_thread_depth: int = 1
|
|
supports_history_fetch: bool = False
|
|
supports_parent_injection: bool = False
|
|
supports_thread_binding: bool = False
|
|
history_max_messages: int = 50
|
|
history_max_chars: int = 4000
|
|
history_ttl_seconds: int = 300
|
|
|
|
@property
|
|
def requires_simulation(self) -> bool:
|
|
return not self.supports_native_threads and self.supports_simulated_threads
|
|
|
|
|
|
class TTSVoiceCapabilities(BaseModel):
|
|
synthesis_target: str = "voice-note"
|
|
transcodes_audio: bool = False
|
|
enabled: bool = False
|
|
|
|
|
|
class TTSCapabilities(BaseModel):
|
|
voice: TTSVoiceCapabilities = Field(default_factory=TTSVoiceCapabilities)
|
|
|
|
|
|
class ChannelCapabilities(BaseModel):
|
|
"""渠道能力声明 — 标准能力标志
|
|
|
|
BaseChannelAdapter 子类通过声明此模型来告知 Gateway 和前端
|
|
该渠道支持哪些功能。Gateway 启动时收集所有渠道的此声明,
|
|
通过 get_channel_status() 向客户端广播可用能力集合。
|
|
"""
|
|
|
|
chat_types: list[str] = Field(default_factory=lambda: ["direct"])
|
|
delivery_mode: str = "direct"
|
|
|
|
polls: bool = False
|
|
reactions: bool = False
|
|
edit: bool = False
|
|
unsend: bool = False
|
|
reply: bool = False
|
|
|
|
effects: bool = False
|
|
|
|
group_management: bool = False
|
|
|
|
threads: bool = False
|
|
|
|
thread_caps: ThreadCapabilities = Field(default_factory=ThreadCapabilities)
|
|
|
|
media: bool = False
|
|
max_media_size_mb: int = 100
|
|
|
|
tts: TTSCapabilities = Field(default_factory=TTSCapabilities)
|
|
|
|
native_commands: bool = False
|
|
|
|
block_streaming: bool = False
|
|
lane_streaming: bool = False
|
|
reasoning_streaming: bool = False
|
|
|
|
pin: bool = False
|
|
unpin: bool = False
|
|
list_pins: bool = False
|
|
|
|
send_ephemeral: bool = False
|
|
|
|
forward: bool = False
|
|
|
|
narrowcast: bool = False
|
|
|
|
vision: bool = False
|
|
approval: bool = False
|
|
typing: bool = False
|
|
|
|
text_chunk_limit: int = 4096
|
|
supports_markdown: bool = False
|
|
supports_streaming: bool = False
|
|
streaming_modes: list[str] = Field(default_factory=lambda: ["off"])
|
|
|
|
def supported_actions(self) -> list[str]:
|
|
actions: list[str] = []
|
|
if self.media:
|
|
actions.append("send_media")
|
|
if self.edit:
|
|
actions.append("edit")
|
|
if self.unsend:
|
|
actions.append("delete")
|
|
if self.reactions:
|
|
actions.append("react")
|
|
if self.pin:
|
|
actions.append("pin")
|
|
if self.unpin:
|
|
actions.append("unpin")
|
|
if self.list_pins:
|
|
actions.append("list_pins")
|
|
if self.polls:
|
|
actions.append("create_poll")
|
|
if self.threads:
|
|
actions.append("create_thread")
|
|
if self.send_ephemeral:
|
|
actions.append("send_ephemeral")
|
|
if self.group_management:
|
|
actions.extend(["kick", "ban", "mute"])
|
|
return actions
|
|
|
|
|
|
CAPS_SIMPLE_TEXT = ChannelCapabilities()
|
|
|
|
CAPS_FULL_FEATURED = ChannelCapabilities(
|
|
chat_types=["direct", "group", "thread"],
|
|
polls=True,
|
|
reactions=True,
|
|
edit=True,
|
|
unsend=True,
|
|
reply=True,
|
|
threads=True,
|
|
media=True,
|
|
supports_markdown=True,
|
|
supports_streaming=True,
|
|
streaming_modes=["chunked", "live"],
|
|
)
|
|
|
|
CAPS_GROUP_CHAT_ONLY = ChannelCapabilities(
|
|
chat_types=["direct", "group"],
|
|
reply=True,
|
|
media=True,
|
|
group_management=True,
|
|
supports_markdown=True,
|
|
supports_streaming=True,
|
|
streaming_modes=["block"],
|
|
)
|
|
|
|
THREAD_CAPABILITIES: dict[str, ThreadCapabilities] = {
|
|
"matrix": ThreadCapabilities(
|
|
supports_native_threads=True,
|
|
supports_history_fetch=True,
|
|
supports_parent_injection=True,
|
|
supports_thread_binding=True,
|
|
history_max_messages=100,
|
|
),
|
|
"discord": ThreadCapabilities(
|
|
supports_native_threads=True,
|
|
supports_history_fetch=True,
|
|
supports_thread_binding=True,
|
|
history_max_messages=100,
|
|
),
|
|
"slack": ThreadCapabilities(
|
|
supports_native_threads=True,
|
|
supports_history_fetch=True,
|
|
supports_thread_binding=True,
|
|
history_max_messages=50,
|
|
),
|
|
"feishu": ThreadCapabilities(
|
|
supports_native_threads=True,
|
|
supports_history_fetch=True,
|
|
supports_parent_injection=True,
|
|
supports_thread_binding=True,
|
|
history_max_messages=100,
|
|
),
|
|
"telegram": ThreadCapabilities(
|
|
supports_topics=True,
|
|
supports_history_fetch=True,
|
|
supports_thread_binding=True,
|
|
),
|
|
"whatsapp": ThreadCapabilities(
|
|
supports_topics=True,
|
|
supports_history_fetch=True,
|
|
),
|
|
"mattermost": ThreadCapabilities(
|
|
supports_reply_chains=True,
|
|
supports_history_fetch=True,
|
|
supports_thread_binding=True,
|
|
),
|
|
"irc": ThreadCapabilities(
|
|
supports_simulated_threads=True,
|
|
supports_history_fetch=False,
|
|
history_max_messages=0,
|
|
),
|
|
"nostr": ThreadCapabilities(
|
|
supports_simulated_threads=True,
|
|
supports_history_fetch=False,
|
|
history_max_messages=0,
|
|
),
|
|
"qqbot": ThreadCapabilities(
|
|
supports_simulated_threads=True,
|
|
supports_history_fetch=False,
|
|
history_max_messages=0,
|
|
),
|
|
"twitch": ThreadCapabilities(
|
|
supports_simulated_threads=True,
|
|
supports_history_fetch=False,
|
|
history_max_messages=0,
|
|
),
|
|
"msteams": ThreadCapabilities(
|
|
supports_native_threads=True,
|
|
supports_history_fetch=False,
|
|
supports_parent_injection=False,
|
|
supports_thread_binding=True,
|
|
),
|
|
"wechat": ThreadCapabilities(
|
|
supports_simulated_threads=True,
|
|
supports_history_fetch=False,
|
|
supports_parent_injection=False,
|
|
),
|
|
}
|