流程
bot/flows 负责把规范化事件转为业务行为,bot/engine 提供限流、管道与调度。
响应管道
提及与聊天共用 ResponsePipeline.respond(),flow 只提供 generate(AI 生成)与 deliver(发送)两个回调。
- 同一用户(群聊为房间)在同一把锁内串行,
^命令先于管道处理;提示与管理回复不计轮数,只有插件与 AI 回复计入。 on_message/on_mention首个 handled 结果即为回复,followup在后台完成后二次发送。- 未被接管时,
on_context的结果合并为Augment:context前置,text改写用户原文,media作为多模态输入,tools为本次的Toolbox。
工具
ResponsePipeline.toolbox() 汇总宿主工具(add_tools() 注册)与 PluginManager.plugin_tools(),按 access 过滤成 Toolbox,并解析 /<工具> 前缀。
Toolbox.run()校验参数、限时并收集结果;文件、链接与followup随最终回复发送、追加与补发。插件工具经PluginManager包装,遵守重载与关闭状态。external工具返回后,或提及、聊天引入他人内容时,Toolbox.taint()使effect工具不再可用。- 调用循环由
OpenAIAPI.generate_chat()驱动,见 OpenAI。
提及
MentionHandler 在 reply.mention 开启时处理:
- 过滤自提及、Bot 账号与黑名单。
- 受理判定:
reply事件仅在回复机器人的帖子时受理;mention事件须mentions含机器人,且回复机器人的帖子不重复受理,避免同一帖触发两次。 - 构造提示:当前正文,附加被引用帖(
Quote)与父帖(Replying to)。 - 回复链:经
notes/conversation取最近reply.memory条祖先,保留根帖、父帖及机器人与当前用户的发言,转为多轮消息并按reply.ctx_tokens截断。
聊天
ChatHandler 在 reply.chat 开启时处理:
- 会话键:私聊为对方用户 ID,群聊为
room:{id};群聊须@机器人,正文带用户名:前缀区分发言人。 @判定:用户名带 host 时须等于本站。- 历史:首次从 Misskey 懒加载,缓存 1 小时(最多 1000 个会话),每轮增量追加并去重,请求前按
reply.memory与reply.ctx_tokens截断。 - 群聊中
^命令被忽略,私聊^仅管理员可用。
回复限制
ResponseLimiter 按用户 ID 维护 (last_reply_ts, turns, blocked_until_ts),内存 TTL 缓存 24 小时,写穿 SQLite,每日 03:00 清理过期记录。
- 自动拉黑经
SettingsReloader.update()写回settings.yaml。
自动发帖
AutoPostService 由 APScheduler 驱动,模式切换时重建任务:
| 模式 | 触发 | 说明 |
|---|---|---|
rotation | 固定间隔,启动后约 1 分钟首次执行 | 受 daily_max 约束 |
schedule | 多个 HH:MM 的 cron 组合 | 不限次数 |
每次执行:
- 调用
on_auto_post,优先发布首个带contents的插件结果(多条间隔 10 秒,逐条确认on_auto_post_published)。 - 否则取首个带
prompt的结果作为前缀,与autopost.prompt拼接后交由模型生成。 - 发帖前后检查并递增当日计数(持久化于 SQLite,跨日自动归零)。
任务 coalesce 并带 5 分钟 misfire 宽限,停机期间错过的执行不会补发多次。