Skip to content

fix: stop bot from replying after human expert intervention in discussion thread#108

Merged
nevstop merged 3 commits into
mainfrom
copilot/modify-filter-logic
Jun 24, 2026
Merged

fix: stop bot from replying after human expert intervention in discussion thread#108
nevstop merged 3 commits into
mainfrom
copilot/modify-filter-logic

Conversation

Copilot AI commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Once nevstop, yao0928, or any csm-committee team member comments on a Q&A discussion thread, the bot stops replying to subsequent follow-up questions from regular users — treating it as human expert intervention (e.g., discussions/106).

Changes

Static skip list

  • scripts/_utils.py — Add yao0928 to SKIP_AUTHORS (previously only nevstop)

Dynamic csm-committee resolution

  • scripts/_github.py — Add rest_get(path) method to GitHubGraphQL for REST API calls
  • scripts/discussion_bot.py:
    • Add CSM_COMMITTEE_SLUG = "csm-committee" and module-level team members cache
    • Add resolve_skip_logins(client, org) — fetches csm-committee members via GET /orgs/{org}/teams/csm-committee/members, merges with SKIP_AUTHORS, caches result
    • compute_reply_plan() now accepts optional skip_logins parameter (defaults to SKIP_AUTHORS for backward compat)
    • _process_discussion_dict() resolves skip_logins once per discussion and passes to compute_reply_plan
  • scripts/router.py_handle_qa imports resolve_skip_logins, resolves effective skip set, and passes skip_logins to compute_reply_plan

Thread-level skip

  • scripts/discussion_bot.py — Add early-exit in compute_reply_plan: if any skip-list member has commented in the thread, return None immediately regardless of subsequent activity

    # Before: SKIP_AUTHORS comments were only excluded from history/follow-up detection
    # After: any skip-list comment → entire thread skipped
    effective_skip = skip_logins if skip_logins is not None else SKIP_AUTHORS
    if any(
        (c.get("author") or {}).get("login", "").casefold() in effective_skip
        for c in comments
    ):
        return None

Tests

  • tests/test_discussion_bot.py — Update 2 tests for thread-level skip; add 11 new tests covering:
    • yao0928 and pre-bot expert comments
    • bot_login=None scenarios (nevstop + yao0928)
    • Custom skip_logins parameter (case-insensitive, empty set)
    • resolve_skip_logins (API failure fallback, team merge, caching)

Copilot AI added 2 commits June 24, 2026 08:33
…eplied

Once a member of SKIP_AUTHORS comments on a discussion thread, the bot
treats it as human-intervened and stops processing that thread entirely
(including any subsequent follow-up questions from regular users).

Also adds yao0928 to SKIP_AUTHORS alongside nevstop.

Fixes: too many bot interventions on discussions like orgs/NEVSTOP-LAB/discussions/106
Copilot AI changed the title fix: skip discussion thread when human expert (nevstop/yao0928) has replied fix: stop bot from replying after human expert intervention in discussion thread Jun 24, 2026
Copilot AI requested a review from nevstop June 24, 2026 08:35
@nevstop nevstop marked this pull request as ready for review June 24, 2026 14:26

@nevstop nevstop left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: copilot/modify-filter-logic → PR #108

Verdict: ship as-is — clean change, well-tested, no blocking issues.


正向确认

compute_reply_plan early exit 位置正确:在 bot_login=None 安全检查和 follow-up 检测之前,因为人工介入判断不依赖 bot_login(只看 author.login
空 comments 安全any() 对空列表返回 False,无崩溃风险
与 router 互补不冲突:router 的 main() SKIP_AUTHORS 检查按 comment_author 跳过;compute_reply_plan 按 thread 级跳过。两者独立生效,前者节省分类开销,后者覆盖扫描模式
测试覆盖完整

  • 已有的 2 个 nevstop 测试更新为 thread 级跳过
  • 新增 5 个测试:yao0928、bot 前介入、bot_login=None × 2(nevstop + yao0928)
  • test_compute_reply_plan_skips_when_expert_comments_before_bot 覆盖"专家抢在 Bot 前回答"场景,这是关键 edge case
    向后兼容followup_user_indices 中的 SKIP_AUTHORS 过滤保留(在无人工介入时仍有效),非破坏性

Nits

  • scripts/_utils.py L25: "Bot 即视为人工已介入,不再对该 thread 进行任何回复(包括后续用户的追问)" — 此描述准确对应 compute_reply_plan 的行为,但 router 的 JOIN/OTHER 路径不走 compute_reply_plan,不受此约束。可考虑加一句"(仅在 compute_reply_plan 中)"限定范围,避免未来误解。当前不影响功能,可忽略。

When any csm-committee member comments on a discussion thread, the
bot now treats it as human expert intervention and stops replying —
same behavior as the hardcoded SKIP_AUTHORS (nevstop, yao0928).

Changes:
- _github.py: add rest_get() method to GitHubGraphQL for REST API calls
- _utils.py: update comment to note csm-committee dynamic resolution
- discussion_bot.py:
  - add CSM_COMMITTEE_SLUG, _team_members_cache, resolve_skip_logins()
  - resolve_skip_logins() fetches team members via REST API (cached),
    merges with SKIP_AUTHORS
  - compute_reply_plan() now accepts optional skip_logins parameter;
    defaults to SKIP_AUTHORS for backward compat
  - _process_discussion_dict() resolves skip_logins once per discussion
- router.py:
  - _handle_qa imports resolve_skip_logins, resolves effective skip set
  - passes skip_logins to compute_reply_plan
- tests: 6 new tests for custom skip_logins, resolve_skip_logins,
  API failure fallback, case insensitivity, and caching

@nevstop nevstop left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: copilot/modify-filter-logic — csm-committee integration

Verdict: ship as-is — clean implementation, well-tested, no blocking issues.


正向确认

rest_get() 实现正确:auth headers 与 query() 一致,HTTPError → RuntimeError 统一
resolve_skip_logins 三级降级:API 正常 → 合并;响应非 list → warning + 空缓存;异常 → exception log + 空缓存。降级后 SKIP_AUTHORS 始终生效
✅ 缓存设计明智:首次调用按 org/slug 缓存,后续调用零 API 开销;进程重启自动刷新
compute_reply_plan(skip_logins=) 向后兼容:None 时退化为 SKIP_AUTHORS,现有调用方无需修改;effective_skip 同时用于 early exit 和 followup_user_indices 过滤,一致
router main() 保持轻量:仅用 SKIP_AUTHORS 快检,不引入 discussion_bot 依赖;csm-committee 的完整检测在 _handle_qa 内部通过 resolve_skip_logins 完成
✅ 测试覆盖全面:custom skip_logins(含 casefold、空集合)、resolve_skip_logins(失败回退、合并、缓存命中)
✅ 无安全风险:path 参数由 _get_source_repo_parts() + 常量拼接,不受用户输入控制


Nits(忽略级,不影响合入)

  • _github.py L77 rest_get 返回类型 list | dict 偏窄(json.loads 实际可返回 int/str/bool/None)。不建议改为 Any,但可加注释说明实际端点总是 list/dict。
  • discussion_bot.py L93 _team_members_cache.get(cache_key, frozenset()) — 此行在 if cache_key not in 块之后,get 的 default 永不会使用,属于无害防御代码。
  • discussion_bot.py rest_get 无分页处理:?per_page=100 对当前 csm-committee 规模足够;若团队超过 100 人需加 ?page= 循环。当前可加 # TODO: 注释。
  • _utils.py L27 "不再对该 thread 进行任何回复" — 准确描述了 compute_reply_plan 行为;router 的 JOIN/OTHER 路径不经过此函数,但当前场景(csm-committee 成员不太可能触发 JOIN)无实际影响。

@nevstop nevstop merged commit d8b0e8c into main Jun 24, 2026
@nevstop nevstop deleted the copilot/modify-filter-logic branch June 24, 2026 14:39
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.

2 participants