Skip to content

feat[onebot]支持 event_id传递 - #92

Open
serfend wants to merge 65 commits into
mainfrom
dev
Open

feat[onebot]支持 event_id传递#92
serfend wants to merge 65 commits into
mainfrom
dev

Conversation

@serfend

@serfend serfend commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

serfend and others added 30 commits May 24, 2026 00:55
- 为所有成员变量添加完整类型注解 (PluginManager, ModuleManager, SharedLogService 等)
- 导入优化: Callable 替代字符串类型引用, 添加 HttpServer 导入
- 代码风格统一: 引号风格/空行/注释对齐
- 消息日志: 将内联字典提取为 log_msg_item / web_log_item 命名变量
- 错误报告: 提取 ctx 上下文变量和 web_log_err_item, 减少深层嵌套
- 性能警告: 提取 frm_log_item 命名变量
- 格式调整: 条件表达式格式优化, 空格对齐
- from __future__ import annotations 延迟注解求值
- TYPE_CHECKING 条件导入 Event 类型, 避免循环引用
- 所有方法参数/返回值/局部变量添加完整类型注解
- _match_handlers 参数显式化, 明确调用契约
- _S_GROUP/_S_DIRECT/_S_CHANNEL 等常量添加类型注解
- _cached_app 类变量移入类定义内部
- _merge_by_priority 参数细化类型
- 移除内容末尾添加/删除斜杠再匹配的 alt 逻辑
- 用户不会把斜杠放在消息最后面,冗余二次匹配无实际效果
- 直接减少每次未匹配事件的处理器遍历次数
- _FACE_PATTERN 正则捕获 faceId 分组: faceId="([^"]+)"
- sanitize_content 将 face 标签转换为 [face id=X] 格式
- 保留表情ID信息便于后续日志/审计, 避免静默丢失消息语义
核心重构 (parsers.py):
- MessageParser 基类: 封装 _FACE_PATTERN / sanitize_content / extract_image_from_attachments / parse
- GroupMessageParser / DirectMessageParser / ChannelMessageParser / ChannelDirectMessageParser
- InteractionParser (交互事件, 按钮回调)
- LifecycleParser 基类 → GroupAddRobotParser / GroupDelRobotParser / FriendAddParser / FriendDelParser
- IdentityHelper 静态类包装 swap_ids

调用方适配:
- message/event.py: 导入类替代函数, _PARSERS 改为实例映射, parser(event,d) → parser.parse(event,d)
- bot/event.py: swap_ids() → IdentityHelper.swap_ids()
- 新增 _AT_PATTERN 正则匹配 <@!?id> 格式的 @ 标签
- sanitize_content 从仅处理 face 标签扩展为同时剔除 @ 圈人信息
- 调整 strip 时机: 内容级清洗完成后统一 trim, 避免中间 strip 干扰匹配
- 修复 ChannelMessageParser 空格格式 + EOF 换行
event_converter: 新增 raw_msg_id 字段透传原始 message_id, 供上层引用
adapter: 移除 _cache_msg_id 自动缓存, 职责归还应用层
send_message: msg_id_ref 从 _ctx.find_msg_id 内部查询改为 params.get('msg_id') 外部传入
Co-authored-by: Cursor <cursoragent@cursor.com>
将 core/message/parsers.py 单文件拆分为 core/message/parsers/ 包目录:

- 新增 parsers/base.py: MessageParser 基类,封装内容清洗(sanitize_content)、
  图片提取(extract_image_from_attachments)、通用消息解析(parse_generic)、
  消息场景解析(apply_message_scene)等公共逻辑
- 新增 parsers/group.py: GroupMessageParser 群聊消息解析器
- 新增 parsers/direct.py: DirectMessageParser C2C私聊解析器
- 新增 parsers/channel.py: ChannelMessageParser/ChannelDirectMessageParser 频道解析器
- 新增 parsers/interaction.py: InteractionParser 交互事件解析器
- 新增 parsers/lifecycle.py: LifecycleParser 基类及入群/退群/好友等8个生命周期解析器
- 新增 parsers/identity.py: IdentityHelper 身份标识辅助(原swap_ids函数)
- parsers.py 保留为向后兼容shim,re-export所有类和函数
- event.py: 解析器映射表从函数引用改为无状态实例引用(OO1复用)
- bot/event.py: swap_ids → IdentityHelper.swap_ids 适配新API
性能监控:
- bot/event.py: 事件处理入口添加计时(_t0/_dt),单次事件处理超过1s时
  输出warning日志并推送web_log告警,便于定位慢事件
- _dispatch.py: _run_handler 添加处理器执行计时,单个插件处理器超过3s
  时输出warning日志,暴露慢插件

逻辑修复:
- bot/event.py: 屏蔽机器人消息逻辑从配置项条件判断(non_at_message.ignore_bot_sender)
  改为始终屏蔽(author.bot=true即跳过),避免其他机器人的消息触发插件分发
- _dispatch.py: 移除slash重试逻辑(原逻辑: 无匹配时尝试去掉/或加上/重新匹配),
  消除不必要的双倍正则匹配开销

类型注解:
- _dispatch.py: 添加 from __future__ import annotations,为 dispatch/_match_handlers/
  _run_handler/_build_dispatch_index 等全部方法及局部变量补充类型标注
- _dispatch.py: 引入 TYPE_CHECKING 避免循环导入 Event 类型
- application.py: 为 _plugin_manager/_module_manager/_http_server/_config_watcher 等
  所有组件属性补充 Optional 类型标注,_error_callbacks/_framework_callbacks 标注为
  list[Callable],提升代码可维护性

代码清理:
- bot/event.py: 事件分发错误处理从多行字典字面量精简为内联构造
- _dispatch.py: _cached_app 类变量从方法间移至类顶部声明
- application.py: 导入后补充空行,统一代码风格
get_group_member_info:
- 新增成员信息缓存机制(cache_member类变量),支持get/set_member_base_info
  方法按group_id+user_id存取成员基础信息
- execute方法返回结果与缓存合并(| mbase),使后续API调用可获取缓存的
  昵称、角色等扩展字段

event_converter:
- 消息事件输出新增 raw_msg_id 字段(原始平台消息ID),保留原始消息标识
  供下游使用,与映射后的OneBot message_id区分
- 群消息 sender.role 从硬编码 'member' 改为使用 event.member_role,
  传递真实成员角色(owner/admin/member)
- 生命周期事件输出新增 real_user_id/real_group_id 字段,保留原始平台ID
  供需要原始标识的场景使用(如通知消息需要定位来源)

ws_server:
- 反向WS连接/断开/失败日志统一补充 appid 字段,便于多机器人环境下
  快速定位是哪个bot的连接问题
- 断开日志补充当前连接数信息
base.py:
- 新增 MessageUtils 不可实例化静态工具类,收拢所有无状态纯函数和正则模式
  (_FACE_PATTERN / _MSG_IDX_PATTERN / _AT_PATTERN / sanitize_content /
   extract_image_from_attachments / extract_msg_idx)
- 模块级 sanitize_content / extract_image_from_attachments / extract_msg_idx /
  apply_message_scene / parse_message_generic 保留为向后兼容包装函数,
  内部委托 MessageUtils,不再创建 MessageParser 实例
- MessageParser 基类移除 extract_msg_idx 静态方法(已迁移至 MessageUtils),
  消除基类与工具函数之间的循环委托
- parse_message_generic / apply_message_scene 改为直接操作 event 字段,
  不再经 MessageParser().parse_generic() 间接调用,减少不必要的实例化

channel.py / group.py / interaction.py:
- import 从 sanitize_content 模块级函数改为 MessageUtils 类
- 调用点 sanitize_content(...) → MessageUtils.sanitize_content(...)
  统一通过工具类访问,消除对模块级函数的直接依赖
- parsers/__init__.py: __all__ 和 import 补充 MessageUtils,
  使其可通过包级别直接导入
- parsers.py (兼容shim): 同步 re-export MessageUtils,
  保持旧导入路径完整
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
serfend added 29 commits June 30, 2026 02:38
为 GROUP_MESSAGE_CREATE 记录全量群消息标记,并通过 OneBot 消息事件的 full 字段上报,便于应用侧区分全量与艾特消息。

生命周期通知同步上报原始 event_id,使应用侧能够使用事件标识进行被动回复。
send_msg 在剥离目标与消息体参数后,将调用方提供的 msg_id 或 event_id 透传到文本、Markdown 和媒体发送链路,修复生命周期事件及媒体消息无法按事件标识回复的问题。

删除已停用且没有调用方的消息 ID 缓存,避免适配器保留过期会话引用;回复关系改由应用侧显式维护。
新增图床模块的可分发配置骨架,列出 COS、B站、QQ频道、ChatGLM、Ukaka、星野和 Nature 的开关及参数。所有图床默认关闭,敏感凭据保持为空,便于部署后按需启用。
@abstractmethod
async def execute(self, params: dict[str, Any], echo: str | None = None) -> dict[str, Any]:
"""执行 action 并返回 OneBot 11 格式响应"""
...
@@ -0,0 +1,2 @@
from .PromptException import *
@@ -0,0 +1,2 @@
from .PromptException import *
from .PromptTpl import * No newline at end of file
Comment thread core/message/media.py
import hashlib
import os
import tempfile
from ..prompt_exception import *
await cur.execute(sql, item.get('params'))
await conn.commit()
return True
except BaseException as exc:
app = get_app()
if app and app._http_server:
return app._http_server._app
except ImportError:
_libc.malloc_trim(0)


_DEFAULTS = {
'max_tasks_per_worker': 300,
}

_COMMENTS = {
import asyncio
import contextlib

_DEFAULTS = {
'decode_responses': True,
}

_COMMENTS = {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant