Skip to content

[Bug] 开启 active_reply 后必崩:'ToolLoopAgentRunner' object has no attribute 'stats' #10698

Open

Description

@820552750

fix-stats-init.patch

问题描述

打开 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。
如果维护者倾向后者,我可以按那个方向改。

如何复现?

  1. 先在目标群里建立会话:在该群发一次 /new(或之前已经在群里聊过)。
    ⚠️ 没有活动会话时,主动回复会在进入 agent 前直接 return,复现不了。
  2. data/cmd_config.json 中设置:
"provider_ltm_settings": {
  "active_reply": {
    "enable": true,
    "method": "possibility_reply",
    "possibility_reply": 1.0      // 默认 0.1,不改的话要发十条才中一次
  }
}
  1. 移出 data/plugins/ 下所有第三方插件(内置插件保留),重启 AstrBot
  2. 在群里用另一个账号发一条普通消息(不 @ bot、不是指令)
  3. 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

检查清单

  • 我已在 Issue 列表中搜索过相关问题仍无法解决,或该问题从未被报告过。
  • 我已尝试过禁用所有插件,排除了可能是因插件导致的问题。
  • 我报告的问题与 AstrBot 本体相关,而非在报告某一插件的问题。
  • 我已阅读并同意本项目的贡献者行为准则。
  • (可选)我愿意提交 PR 以帮助修复该问题。

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions