Repository navigation
[Bug] 开启 active_reply 后必崩:'ToolLoopAgentRunner' object has no attribute 'stats' #10698
Description
问题描述
打开 active_reply 后,任何没有 @ bot 的群消息都会让 bot 回一句报错,而不是按预期主动接话。移出全部第三方插件后仍稳定复现。
触发范围补充(重要)
这条路径不是唯一入口。如果某个插件的 handler filter 命中、把 is_wake 顶成 true
(waking_check/stage.py 215-216 行,另见功能建议「拆开唤醒与插件匹配」),
那么非唤醒的群消息同样会进 agent,一样会踩到同一个 stats 缺失。
也就是说:关掉 active_reply 只是避开最省事的复现方式,并不是修复。
定位分析(v4.29.1 源码行号)
astrbot/core/agent/runners/tool_loop_agent_runner.py(v4.29.1):
self.stats = AgentStats()只出现在reset()的末尾(第 331-332 行,
self.run_context.messages = messages之后)- 这个类没有
__init__,基类BaseAgentRunner也没有(直接继承object),
所以不存在"构造时就初始化好"的时机 - 但
self.stats在 187、879、884、909、1380、1591 行被直接使用
(_complete_with_assistant_response、step等) - 报错说明存在一条运行路径:runner 已经进入
step(),但reset()没有执行完
最小修复(我本地验证过,不崩了):
# step() 开头
if not hasattr(self, "stats") or self.stats is None:
self.stats = AgentStats()
self.stats.start_time = time.time()更干净的做法是把 self.stats = AgentStats() 提到 reset() 开头(第 205 行附近,
self.req = request 之前),这样任何走到 step() 的路径都保证有 stats。
如果维护者倾向后者,我可以按那个方向改。
如何复现?
- 先在目标群里建立会话:在该群发一次
/new(或之前已经在群里聊过)。
⚠️ 没有活动会话时,主动回复会在进入 agent 前直接 return,复现不了。 data/cmd_config.json中设置:
"provider_ltm_settings": {
"active_reply": {
"enable": true,
"method": "possibility_reply",
"possibility_reply": 1.0 // 默认 0.1,不改的话要发十条才中一次
}
}- 移出
data/plugins/下所有第三方插件(内置插件保留),重启 AstrBot - 在群里用另一个账号发一条普通消息(不 @ bot、不是指令)
- bot 回复报错,控制台出现 AttributeError
触发路径说明(有助于排除"插件导致"的疑虑)
主动回复是内置插件 astrbot/builtin_stars/astrbot 实现的,不是第三方插件:
# builtin_stars/astrbot/group_chat_context.py
async def need_active_reply(self, event) -> bool:
if not cfg["enable_active_reply"]: return False
if event.get_message_type() != MessageType.GROUP_MESSAGE: return False
if event.is_at_or_wake_command: return False # @ 过就不算主动
...
match cfg["ar_method"]:
case "possibility_reply":
return random.random() < cfg["ar_possibility"]
# builtin_stars/astrbot/main.py on_message
if need_active:
...
yield event.request_llm(prompt=prompt, session_id=event.session_id,
image_urls=image_urls, conversation=conv)request_llm 会绕过唤醒判定,把这条没人 @ bot 的群消息直接送进 agent,于是走到
ToolLoopAgentRunner 并触发 stats 缺失。
也就是说:把第三方插件全部移除后问题依旧存在,触发者是内置插件。
AstrBot 版本
4.29.1
操作系统
Windows
部署方式
源码/命令行(venv 内 pip 安装,astrbot run 启动)
使用的消息平台适配器
OneBot v11(aiocqhttp,ws-reverse 对接 LLOneBot)
错误日志
[20:41:03] [v4.29.1] [core.event_bus:116]: [default] [xxx(aiocqhttp)] 群友A/123456: 今天好累
[20:41:18] [v4.29.1] [agent_sub_stages.internal:482]: Error occurred while processing agent:
'ToolLoopAgentRunner' object has no attribute 'stats'
[20:41:18] [v4.29.1] [respond.stage:233]: Prepare to send - 123456/123456: Error occurred during AI execution.
Error Type: AttributeError
Error Message: 'ToolLoopAgentRunner' object has no attribute 'stats'
辅助信息
No response
Activity