Skip to content

bug: 仅 @bot(无文字内容)会从全库随机抽取回答 #39

@dragon-fish

Description

@dragon-fish

复现

任意 dialogue 库(条目数 ≥ 1,且至少一条 probA > 0),用户发送一条仅有 @bot、没有任何文字的消息:

用户: @bot
bot: <从所有 probA > 0 的条目里随机抽一条 answer>

无论这些条目的 question 是什么,都会被卷入候选池按 probA 加权抽签。

代码路径

  1. packages/core/src/receiver.ts:275

    if (!content && !appel) return true

    这里只在「内容为空 @bot」时 short-circuit;意味着「内容为空 + @bot」是被刻意放行的。

  2. 同一个 hook 接着把 test 写空:

    const { original, parsed, appellative, activated } = ctx.root.dialogue.stripQuestion(content)
    test.question = parsed       // = ''
    test.original = original     // = ''
    test.appellative = appellative || appel  // = true
  3. packages/core/src/internal.ts:185-202dialogue/query hook:

    ctx.on('dialogue/query', ({ regexp, answer, question, original }, query) => {
      if (regexp) { ... return }
      if (answer) query.answer = answer
      if (regexp === false) {
        if (question) query.question = question         // question='' falsy → 不加条件
      } else if (original) {                             // original='' falsy → 整个分支跳过
        ...
      }
    })

    question / original 都是空字符串(falsy),所有 if 分支都不进入,query 没有附加任何 question 维度的条件,等价于「查全表」。

  4. 结果:receiver.ts 拉到全表 dialogue → probability.tstest.appellative=true 走 probA 加权 → 任何 probA > 0 的条目都成为候选 → 随机抽。

期望

@bot 不带文字时不应该触发与具体 question 完全无关的回答。匹配应当仅基于 stripped.content 推导出的 question 进行;content 空就没有匹配依据。

修复方向(请 maintainer 定夺)

A. 在 receiver.ts:275 把守卫放宽为 if (!content) return true,不再放行「空内容 + appel」。最小改动,但属于行为变更。

B. 在 internal.tsdialogue/query hook 里,当 question/original 都为空字符串时显式塞一个不可能命中的条件让 query 返回空集。等价于 A,位置不同。

C. 如果「@bot 空内容 → 随机回答」是有意保留的功能,引入一个新 flag(如 Flag.appellativeOnly)显式标记参与该路径的条目,避免无差别全表卷入。

我们在自己的项目里临时用了类似 A 的 dialogue/receive 守卫规避,工作正常(补丁见评论区)。

环境

  • koishi-plugin-dialogue 4.1.3(main 分支当前代码 path 一致,未修复)
  • koishi 4.18.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions