feat: Enhance context handling and notifications for sensitive messages#2
Open
rurudo-ruo wants to merge 19 commits into
Open
feat: Enhance context handling and notifications for sensitive messages#2rurudo-ruo wants to merge 19 commits into
rurudo-ruo wants to merge 19 commits into
Conversation
…isplay Decouple context-for-LLM from append_context config flag so the LLM always receives conversation context for sensitivity judgment regardless of whether notifications include it. Move truncation logic into _notify where display formatting belongs.
Use event.message (MessageArray) instead of event.raw_message to avoid passing CQ code strings like [CQ:image,...] to the LLM and notifications. Non-text segments are replaced with summaries ([图片], [文件], [语音] etc.) and pure attachment messages are skipped entirely.
There was a problem hiding this comment.
Hey - 我发现了 1 个问题,并给出了一些整体建议:
- 在将
group_id作为LAST_NOTIFY_TIME的键使用时,建议统一其类型(例如像 config 和RECENT_*中那样始终使用str(group_id)),以避免由于同一个 ID 使用了不同类型而产生多个独立条目的隐性 bug。 LAST_NOTIFY_TIME是一个按群组分组的、未做上界限制的全局字典;如果这个插件会在很多群里长期运行,建议定期清理非常久远的条目(例如在清空RECENT_*时或通过定时任务),以避免无界增长。
给 AI Agent 的提示
Please address the comments from this code review:
## Overall Comments
- Consider normalizing the type of `group_id` when using it as a key in `LAST_NOTIFY_TIME` (e.g., always `str(group_id)` as you do for config and `RECENT_*`) to avoid subtle bugs where different types for the same ID create separate entries.
- `LAST_NOTIFY_TIME` is an unbounded global dict keyed by group; if this plugin runs in many groups over time, you may want to periodically prune very old entries (e.g., when clearing `RECENT_*` or on a timer) to avoid unbounded growth.
## Individual Comments
### Comment 1
<location path="plugins/_ai/llm.py" line_range="258-267" />
<code_context>
- is_sensitive = reply.strip().startswith("是")
- reason = reply.strip()
- return is_sensitive, reason
+ cleaned = reply.strip()
+ # Match the first 「是」/「否」 or bare 是/否 at the start
+ m = re.search(r'[「((]?\s*([是否])\s*[」))]?', cleaned)
+ if m:
+ is_sensitive = m.group(1) == "是"
+ else:
+ # Fallback: check first non-whitespace character
+ first_char = cleaned.lstrip()[:1] if cleaned else ""
+ is_sensitive = first_char == "是"
+ return is_sensitive, cleaned[:200]
async def judge_question(self, project: str, message_text: str, context: str = "") -> bool:
</code_context>
<issue_to_address>
**issue (bug_risk):** 用于抽取开头「是/否」的正则没有锚定到字符串开头,可能会被后面的文本误导而产生错误分类。
由于这里使用的是 `re.search`,它可能会匹配到后面位置的「是/否」,而不是真正的开头回答,这与“匹配开头”这一意图相违背。比如:`"否,你这条不是敏感消息,但前面那条是敏感内容"` 会因为后面的「是」而被判断为敏感。为了只匹配最前面的回答,应当锚定正则并使用 `re.match`,例如 `m = re.match(r'^\s*[「((]?\s*([是否])\s*[」))]?', cleaned)`,只有在这个匹配失败时再回退到“检查第一个非空白字符”的启发式逻辑。
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的评审。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- Consider normalizing the type of
group_idwhen using it as a key inLAST_NOTIFY_TIME(e.g., alwaysstr(group_id)as you do for config andRECENT_*) to avoid subtle bugs where different types for the same ID create separate entries. LAST_NOTIFY_TIMEis an unbounded global dict keyed by group; if this plugin runs in many groups over time, you may want to periodically prune very old entries (e.g., when clearingRECENT_*or on a timer) to avoid unbounded growth.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider normalizing the type of `group_id` when using it as a key in `LAST_NOTIFY_TIME` (e.g., always `str(group_id)` as you do for config and `RECENT_*`) to avoid subtle bugs where different types for the same ID create separate entries.
- `LAST_NOTIFY_TIME` is an unbounded global dict keyed by group; if this plugin runs in many groups over time, you may want to periodically prune very old entries (e.g., when clearing `RECENT_*` or on a timer) to avoid unbounded growth.
## Individual Comments
### Comment 1
<location path="plugins/_ai/llm.py" line_range="258-267" />
<code_context>
- is_sensitive = reply.strip().startswith("是")
- reason = reply.strip()
- return is_sensitive, reason
+ cleaned = reply.strip()
+ # Match the first 「是」/「否」 or bare 是/否 at the start
+ m = re.search(r'[「((]?\s*([是否])\s*[」))]?', cleaned)
+ if m:
+ is_sensitive = m.group(1) == "是"
+ else:
+ # Fallback: check first non-whitespace character
+ first_char = cleaned.lstrip()[:1] if cleaned else ""
+ is_sensitive = first_char == "是"
+ return is_sensitive, cleaned[:200]
async def judge_question(self, project: str, message_text: str, context: str = "") -> bool:
</code_context>
<issue_to_address>
**issue (bug_risk):** The regex for extracting the leading 「是/否」 is not anchored and can misclassify based on later text.
Because this uses `re.search`, it may pick up a later 「是/否」 instead of the leading answer, contradicting the intent of matching “at the start”. For example, `"否,你这条不是敏感消息,但前面那条是敏感内容"` would be treated as sensitive due to the later "是". To match only the leading answer, anchor the regex and use `re.match`, e.g. `m = re.match(r'^\s*[「((]?\s*([是否])\s*[」))]?', cleaned)`, and fall back to the first-character heuristic only if this fails.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
- Implemented Skland sign-in functionality with account management. - Added commands for immediate sign-in, status check, and configuration management. - Integrated SMS login with verification code handling. - Included QR login placeholder with a warning about current limitations. - Enhanced error handling and notification for authentication failures. - Updated project dependencies in pyproject.toml. - Refactored sensitive monitor plugin to prune stale notification cooldown entries. - Cleaned up unused imports and improved code readability in various plugins.
…n and notification features - Added SensitiveMonitorPlugin to monitor and handle sensitive messages in group chats. - Implemented configuration loading and saving for group-specific settings. - Introduced commands for enabling/disabling monitoring, managing notification recipients, and setting cooldowns. - Integrated LLM for sensitive content detection with timeout handling. - Enhanced message processing to build clean message context for better detection accuracy.
…notification features
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary by Sourcery
增强敏感消息监控插件,对可配置的上下文处理进行丰富升级,提升 LLM 判定结果解析的健壮性,并支持按群组设置通知冷却时间,以减少通知噪音。
新功能:
功能增强:
raw_message,并将消息 ID 规范化为字符串,用于近期处理的跟踪。Original summary in English
Summary by Sourcery
Enhance the sensitive message monitoring plugin with richer configurable context handling, more robust LLM judgment parsing, and per-group notification cooldowns to reduce noise.
New Features:
Enhancements: