Skip to content

feat(feishu): add group thread isolation lists#1446

Open
luoye-fe wants to merge 1 commit into
chenhg5:mainfrom
luoye-fe:feat/feishu-thread-isolation-groups
Open

feat(feishu): add group thread isolation lists#1446
luoye-fe wants to merge 1 commit into
chenhg5:mainfrom
luoye-fe:feat/feishu-thread-isolation-groups

Conversation

@luoye-fe

Copy link
Copy Markdown

Summary

Add per-group controls for Feishu thread_isolation so deployments can opt specific regular groups in or out without changing private-chat behavior. Native Feishu topic messages are always kept in topic-thread reply mode, even when global thread_isolation is disabled.

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing behavior to change)
  • Documentation only
  • Internal refactor / chore (no user-visible change)

Testing

Automated tests added in this PR

  • TestNewFeishu_ThreadIsolationGroupLists in platform/feishu/platform_test.go — verifies the new Feishu platform options are parsed into the platform.
  • TestFeishu_MakeSessionKeyThreadIsolationGroupLists in platform/feishu/platform_test.go — verifies global-on blacklist, global-off whitelist, native topic, private chat, and shared-channel session-key behavior.
  • TestBuildReplyMessageReqBody_SetsReplyInThreadFlag in platform/feishu/platform_test.go — extended to verify blacklist/whitelist/native-topic reply-thread decisions.
  • TestMarkAndIsActiveThreadSession in platform/feishu/feishu_test.go — extended to verify active thread tracking honors blacklist/whitelist behavior.

Commands run locally:

GOTOOLCHAIN=auto /opt/homebrew/bin/go test ./platform/feishu -run 'TestNewFeishu_ThreadIsolationGroupLists|TestFeishu_MakeSessionKeyThreadIsolationGroupLists|TestBuildReplyMessageReqBody_SetsReplyInThreadFlag|TestMarkAndIsActiveThreadSession' -v
GOTOOLCHAIN=auto /opt/homebrew/bin/go test ./platform/feishu

Both commands passed.

GOTOOLCHAIN=auto /opt/homebrew/bin/go test ./... was also run. It failed on unrelated local/environment-sensitive tests outside this change:

  • core: TestCUJ_A3_ImageReachesAgent and TestCUJ_A5_FileReachesAgent failed during TempDir RemoveAll cleanup: directory not empty.
  • daemon: TestLaunchdStatusUsesUserDomainWhenGUIDomainUnavailable failed with Status().Running = false, want true.

All Feishu platform tests passed in that full-suite run.

For bug fixes only — regression test

  • Regression test name: N/A — this is a new feature.
  • Manual verification this test catches the regression:
    • Reverted the fix locally; the regression test failed as expected.

Critical User Journeys (CUJ) impact

  • No CUJ touched (small refactor, doc change, etc.)
  • A — basic conversation
  • B — session lifecycle (/new /switch /list /history etc.)
  • C — agent execution control (/mode /cancel /stop permissions)
  • D — security & permissions (allow_from admin_from banned_words rate limits)
  • E — scheduled tasks (/cron /timer)
  • F — config switching (/lang /provider /model reload)
  • G — error handling & robustness (LLM failure, ws reconnect, agent crash)
  • H — multi-platform / multi-project isolation
  • I — UI rendering correctness (cards, streaming, display modes)

If any CUJ group is touched, confirm:

  • go test ./core/ -run TestCUJ passes locally.
  • If the change alters an existing user-visible flow, the corresponding
    CUJ test was updated (or a new CUJ added) to cover the new behavior.

Manual / user-visible behavior change

Feishu platform users can now configure:

  • thread_isolation_black_group: when thread_isolation = true, listed group chat IDs keep normal non-topic replies.
  • thread_isolation_white_group: when thread_isolation = false, listed group chat IDs use topic-thread replies.

Native Feishu topic messages continue to reply in the topic thread regardless of the global thread_isolation setting. Private chat behavior is unchanged.

Checklist (reviewer will verify)

  • go build ./... passes
  • go test ./... passes (with -race if touching concurrency)
  • AGENTS.md Pre-Commit Checklist items are satisfied where applicable to this scoped Feishu platform change
  • No new hardcoded platform/agent names in core/
  • i18n strings have all-language translations (if any new user-facing text)
  • No secrets / credentials in source

Related

  • Issue:
  • Related PR:

@luoye-fe luoye-fe requested a review from chenhg5 as a code owner June 25, 2026 12:04
@luoye-fe

Copy link
Copy Markdown
Author

@chenhg5 hi,帮忙 review 下这个 pr 吧,主要是有些群聊希望按话题形式回复,有些群聊希望用同一个上下文持续对话

@chenhg5 chenhg5 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

结论: Approve

总体判断: 这是一个 well-scoped 的 Feishu platform 扩展, 给现有 thread_isolation 全局开关加上 per-group 黑白名单覆盖, 同时保证 native Feishu topic 消息始终走 topic-thread reply (跟现有 thread_isolation 设置解耦)。 实现方式正确 (helper 函数抽取 + 双重 session tracking + 完整 test 覆盖), 不破坏 backward compat, 4/4 CI green + 完整 PR 模板。 当前可合并。

Review 范围:

  • 看了 4 files / +284/-12: platform/feishu/feishu.go (+245/-11) + config.example.toml (+4/-0) + 2 个 test 文件 (+35/-1)。
  • 重点关注 correctness (per-group 覆盖逻辑) / native topic thread 解耦 / backward compat / test 覆盖 / 配置文件说明。

✅ 做得好的地方:

  • 行为变更清晰: PR 描述明确给出 3 个新行为 — thread_isolation_black_group (global-on 时 excluded 群保持普通 reply) / thread_isolation_white_group (global-off 时 included 群走 thread reply) / native topic 始终走 thread (跟 global 设置解耦)。 每个行为都有对应 test。
  • Helper 抽取合理 (platform/feishu/feishu.go:3346-3408): 5 个新 helper (shouldUseThreadIsolationForMessage / isNativeThreadMessage / shouldUseThreadIsolationForChat / configuredListContains / shouldTreatSessionAsThread) 每个职责单一, 跟核心 platform 文件的现有 helper 风格一致 (e.g. isAttachmentMsgType / stringValue)。 shouldUseThreadIsolationForMessage 把「native topic 检测」和「chat-level 配置」封装到一个函数, 主流程 makeSessionKey 调用变干净。
  • Native topic 解耦做得对 (platform/feishu/feishu.go:174 + 3342-3352): 引入 nativeThreadSessions sync.Map 单独追踪 native topic 消息, 跟 activeThreadSessions 分开, 避免跟 global thread_isolation 状态混淆。 markNativeThreadSession / isNativeThreadSession 配对使用, 跟现有 markThreadSessionActive / isActiveThreadSession 模式一致。
  • shouldUseThreadContext 集成自然 (platform/feishu/feishu.go:1438): 把 p.threadIsolation && isThreadSessionKey(sessionKey) 替换为 p.shouldUseThreadContext(sessionKey), 考虑了 native topic + chat 黑白名单两种情况, 主流程 dispatchMessage 改动最小 (只动一行)。
  • Backward compat 完整保留: markThreadSessionActive 保留为 wrapper 调用新 markThreadSessionActiveForContext(sessionKey, false), 现有调用方不需要改; isActiveThreadSession / makeSessionKey 内部逻辑替换, 但外部 contract 不变 (group + global-on 仍按 thread 隔离, group + global-off 仍按 chat-id 共享 session)。
  • Test 覆盖全面 (platform/feishu/platform_test.go + feishu_test.go):
    • TestNewFeishu_ThreadIsolationGroupLists — 验证新 option parsing
    • TestFeishu_MakeSessionKeyThreadIsolationGroupLists — 5 个 case (global-on blacklist / global-off whitelist / native topic / private chat / shared-channel)
    • TestBuildReplyMessageReqBody_SetsReplyInThreadFlag — extended 验证 blacklist/whitelist/native-topic 的 reply-thread 决策
    • TestMarkAndIsActiveThreadSession — extended 验证 active thread tracking 跟新规则一致
      每个 test 都有清晰的 case 命名, 跟前一轮 review 反馈一致 (test 应覆盖「global-on blacklist」+「global-off whitelist」两个对称 case)。
  • PR 模板完整: 包括 Summary / Type of change / Testing (4 个 test + 命令) / CUJ impact (No CUJ touched) / Manual behavior change / Checklist / Related。 报告诚实标明「go test ./... 在 pre-existing 环境敏感 test 失败 (TempDir RemoveAll cleanup / launchd status), 跟本 PR 改动无关」。
  • config.example.toml 注释完整 (config.example.toml:1008-1011): 每个新 option 都有中英双语说明 + 行为解释, 跟现有 Feishu config block 风格一致。

🔴 必须处理: 无。
🟠 建议改进:

  • 🟠 P2: configuredListContains (platform/feishu/feishu.go:3389) 跟现有 core.AllowList 都有 trim/empty 处理逻辑, 看起来 configuredListContains 等价于 strings.TrimSpace(list) != "" && core.AllowList(list, value)。 建议直接用 core.AllowList 一个函数 (假定 core.AllowList 已经处理了 trim 和 empty), 减少一层间接。 但这不阻塞本 PR, 未来 cleanup 即可。
    验证: 检查 core.AllowList 源码确认是否已处理 trim/empty。
    影响: 微, 主要是函数调用层次清晰度。

🔵 可选优化:

  • 未来考虑: 把 threadIsolationBlackGroup / threadIsolationWhiteGroup 拆成独立的 core.AllowListConfig struct 复用 (类似 allow_from), 跟 core.AllowList 配套。 但本 PR 用字符串 + 逗号分隔跟现有 allow_from 一致, 改动范围保持小是正确的取舍。

❓ 需要确认: 无。

Testing / Risk:

  • 已验证: 5/5 CI checks PASS (lint 1m58s / unit-test 16m49s / smoke 33s / regression 31s / performance 48s) + 作者本地 go test ./platform/feishu + go test ./... (Feishu 部分全 PASS, 标出 pre-existing 环境失败)。
  • 覆盖: option parsing + 5 case session-key (global-on blacklist / global-off whitelist / native topic / private / shared) + reply-thread decision + active thread tracking。
  • 未覆盖 (不在本 PR 范围, 未来 follow-up): 黑白名单同时配置时的优先级 (没在 PR 描述里说, 看起来是「black > white, native 优先」但 code 没显式处理互斥配置)。
  • 剩余风险: 低。 修改面限制在 Feishu platform 包内, 不动 core/engine/session。 backward compat 完整保留。

Next step:

  • 作者: P2 是 nit, 跟 cleanup 一起做即可。 考虑未来 cleanup configuredListContains 直接用 core.AllowList
  • owner: 这是一个 additive feature, 不破坏现有部署, 可以安全 merge 进 v1.4.x。 建议 release notes 加一条 「Feishu: per-group thread_isolation 黑白名单 + native topic 始终 thread」, 方便运营根据具体群配置 reply 行为。
  • QA: 本次 review 后会 pr set --workflow-state ready-to-merge + render

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