Skip to content

feat: 话题内智能响应判断 + thinking 泄漏修复 + 空输出静默 - #121

Merged
lishuceo merged 2 commits into
mainfrom
feat/thread-relevance
Mar 9, 2026
Merged

feat: 话题内智能响应判断 + thinking 泄漏修复 + 空输出静默#121
lishuceo merged 2 commits into
mainfrom
feat/thread-relevance

Conversation

@lishuceo

@lishuceo lishuceo commented Mar 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • 新增 Qwen 语义判断:话题内无 @bot 的消息由小模型判断是否跟 bot 对话,策略为"宁可不回"
  • 修复 thinking 标签泄漏:executor resultMessage.result fallback 路径未剥离 + 未闭合标签处理
  • direct 模式空输出静默跳过(模型 thinking 后决定不回复时不发"(无输出)")
  • 话题内跳过 quick-ack,避免隐式触发时抢答"收到"

Test plan

  • npx vitest run 相关测试通过(thread-relevance 15 tests + executor 33 tests)
  • 实际群聊测试:@人类用户时土豆儿不插嘴,闲聊/感叹/自言自语不响应
  • 全量测试通过

🤖 Generated with Claude Code

- 新增 thread-relevance.ts: Qwen 语义判断话题内无 @mention 消息是否跟 bot 对话
- threadBypass 路径接入语义判断,策略为"宁可不回"
- 话题内跳过 quick-ack,避免隐式触发时抢答
- thinking 剥离: 修复 resultMessage.result fallback 路径未剥离的漏洞
- thinking 剥离: 增加未闭合标签处理
- direct 模式空输出静默跳过,不发"(无输出)"
- quick-ack 导出 getClient 供 thread-relevance 复用

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Mar 9, 2026

Copy link
Copy Markdown

Claude finished @lishuceo's task in 3m 16s —— View job


PR Review: feat: 话题内智能响应判断 + thinking 泄漏修复 + 空输出静默

  • Check previous review comments — no previous comments
  • Read changed files and understand context
  • Review code for bugs, security, and architecture issues
  • Post findings

⚠️ Issues Found

Severity File Confidence Description
🟡 warning src/feishu/event-handler.ts:558 78 Comment says "没有 @任何 bot 或人类" but guard only checks bot IDs; human mentions are handled by Qwen check, not the guard condition

Overall Assessment

Solid PR with well-scoped changes. The four features work together coherently:

  1. Thread relevance check (thread-relevance.ts): Clean implementation with proper timeout (2s), fail-safe defaults, and good separation between the API call layer ("宁可不回" on failure) and the parser layer ("宁可多回" on ambiguous responses). The two-tier fallback strategy is explicitly documented in JSDoc — intentional design.

  2. Thinking tag leak fix (executor.ts): The two-pass regex approach (closed tags first, then unclosed) is correct and handles edge cases well. Applying the same fix to the resultMessage.result fallback path closes the remaining leak vector.

  3. Empty output silent skip (event-handler.ts:sendDirectReply): Correctly catches success: true + empty output after thinking-only responses. The check aligns with executor return types (output: string, non-optional).

  4. Thread quick-ack skip: Appropriate — avoids sending "收到" for implicitly triggered responses.

Tests cover parseRelevanceResponse thoroughly (9 cases) and checkThreadRelevance integration with mocked client (6 cases). Architecture follows existing patterns (ESM imports, singleton reuse via getClient(), Pino logging).

One minor inline comment posted about a misleading code comment.

Comment thread src/feishu/event-handler.ts Outdated
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Mar 9, 2026

Copy link
Copy Markdown

Claude finished @lishuceo's task in 1m 34s —— View job


PR Review: feat/thread-relevance (re-review after sync)

  • Check and resolve previous review comments
  • Read changed files and review current diff
  • Post findings

✅ Approved

1 previous issue fixed — misleading comment about bot vs human @mention guard now accurately describes the logic.

No new issues found (confidence threshold ≥ 75).

Assessment

Clean, well-scoped PR. All four changes work together coherently:

  1. Thread relevance (thread-relevance.ts): Proper two-tier default strategy — API-level failures return false (宁可不回), parse-level ambiguity returns true (宁可多回). 2s timeout with Promise.race is appropriate. Reuses getClient() from quick-ack cleanly.

  2. Thinking tag leak fix (executor.ts:661-664): The resultMessage.result fallback path now applies the same two-pass regex (closed tags, then unclosed) as the streaming path. Correct.

  3. Empty output silent skip (event-handler.ts:1751): result.success && !result.output correctly catches thinking-only responses where output is '' after tag stripping. Avoids sending "(无输出)" for implicit thread responses.

  4. Thread quick-ack skip (event-handler.ts:1516): eventThreadId ? null : await generateQuickAck(rawPrompt) — simple and correct. Prevents premature "收到" for thread-bypass triggers.

Tests cover parseRelevanceResponse (9 cases) and checkThreadRelevance integration with mocked client (6 cases). Architecture follows existing patterns (ESM imports, singleton getClient() reuse, Pino logging).

Note: Unable to run npx vitest run or npm run typecheck due to sandbox permissions. Please verify CI passes.

@lishuceo
lishuceo merged commit 5119972 into main Mar 9, 2026
4 checks passed
@lishuceo
lishuceo deleted the feat/thread-relevance branch March 9, 2026 09:30
lishuceo added a commit that referenced this pull request Apr 8, 2026
* feat: 话题内智能响应判断 + thinking 泄漏修复 + 空输出静默

- 新增 thread-relevance.ts: Qwen 语义判断话题内无 @mention 消息是否跟 bot 对话
- threadBypass 路径接入语义判断,策略为"宁可不回"
- 话题内跳过 quick-ack,避免隐式触发时抢答
- thinking 剥离: 修复 resultMessage.result fallback 路径未剥离的漏洞
- thinking 剥离: 增加未闭合标签处理
- direct 模式空输出静默跳过,不发"(无输出)"
- quick-ack 导出 getClient 供 thread-relevance 复用

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: 修正 threadBypass 注释 — 仅 bot @mention 在 guard 中检查

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant