复现
任意 dialogue 库(条目数 ≥ 1,且至少一条 probA > 0),用户发送一条仅有 @bot、没有任何文字的消息:
用户: @bot
bot: <从所有 probA > 0 的条目里随机抽一条 answer>
无论这些条目的 question 是什么,都会被卷入候选池按 probA 加权抽签。
代码路径
-
packages/core/src/receiver.ts:275
if (!content && !appel) return true
这里只在「内容为空 且 非 @bot」时 short-circuit;意味着「内容为空 + @bot」是被刻意放行的。
-
同一个 hook 接着把 test 写空:
const { original, parsed, appellative, activated } = ctx.root.dialogue.stripQuestion(content)
test.question = parsed // = ''
test.original = original // = ''
test.appellative = appellative || appel // = true
-
packages/core/src/internal.ts:185-202 的 dialogue/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 维度的条件,等价于「查全表」。
-
结果:receiver.ts 拉到全表 dialogue → probability.ts 按 test.appellative=true 走 probA 加权 → 任何 probA > 0 的条目都成为候选 → 随机抽。
期望
@bot 不带文字时不应该触发与具体 question 完全无关的回答。匹配应当仅基于 stripped.content 推导出的 question 进行;content 空就没有匹配依据。
修复方向(请 maintainer 定夺)
A. 在 receiver.ts:275 把守卫放宽为 if (!content) return true,不再放行「空内容 + appel」。最小改动,但属于行为变更。
B. 在 internal.ts 的 dialogue/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
复现
任意 dialogue 库(条目数 ≥ 1,且至少一条
probA > 0),用户发送一条仅有@bot、没有任何文字的消息:无论这些条目的 question 是什么,都会被卷入候选池按 probA 加权抽签。
代码路径
packages/core/src/receiver.ts:275这里只在「内容为空 且 非
@bot」时 short-circuit;意味着「内容为空 +@bot」是被刻意放行的。同一个 hook 接着把 test 写空:
packages/core/src/internal.ts:185-202的dialogue/queryhook:question/original都是空字符串(falsy),所有if分支都不进入,query 没有附加任何 question 维度的条件,等价于「查全表」。结果:
receiver.ts拉到全表 dialogue →probability.ts按test.appellative=true走 probA 加权 → 任何probA > 0的条目都成为候选 → 随机抽。期望
@bot不带文字时不应该触发与具体 question 完全无关的回答。匹配应当仅基于 stripped.content 推导出的 question 进行;content 空就没有匹配依据。修复方向(请 maintainer 定夺)
A. 在
receiver.ts:275把守卫放宽为if (!content) return true,不再放行「空内容 + appel」。最小改动,但属于行为变更。B. 在
internal.ts的dialogue/queryhook 里,当question/original都为空字符串时显式塞一个不可能命中的条件让 query 返回空集。等价于 A,位置不同。C. 如果「
@bot空内容 → 随机回答」是有意保留的功能,引入一个新 flag(如Flag.appellativeOnly)显式标记参与该路径的条目,避免无差别全表卷入。我们在自己的项目里临时用了类似 A 的
dialogue/receive守卫规避,工作正常(补丁见评论区)。环境
koishi-plugin-dialogue4.1.3(main 分支当前代码 path 一致,未修复)koishi4.18.0