fix: poll first变量修复 + KB添加安装动词 + 绿色气泡OCR拦截\n\n1. Poll first变量修复: first=True初始化但循环体内从未设为False→\n 所有new_items都被当作第一条处理。加first=False只处理首条。\n2. KB action_verbs_all添加"安装": "云背包插件怎么安装"\n verb+obj提取安装+云背包插件→优先匹配"安装方法"section\n3. 绿色气泡OCR拦截三层:\n - OCR级: |管道符+CJK混合过滤(正常聊天从不混用|和中文)\n - Poll级: 同|管道符+CJK过滤兜底\n - _is_reply_fragment阈值降低: raw 8→6, CJK 6→5\n - OCR line filter阈值同步降低: raw 8→6, CJK 6→5\n 绿色气泡被OCR啃成"GU |进行配置..."的乱码现在pipe过滤\n 即可拦截或SequenceMatcher阈值降低后匹配replied_texts\n- 提交git.ypshidifu.cn

This commit is contained in:
youpaishidifu
2026-07-29 12:42:23 +08:00
parent 3b8117977b
commit afbcd109f0
2 changed files with 20 additions and 8 deletions
+1 -1
View File
@@ -346,7 +346,7 @@ class KnowledgeBase:
# 动作查询:提取动词+对象,对不含两者的文档降权
# 防止"圈地工具"匹配到含"工具"但不含"圈地"的文档(如寻宝插件)
action_verbs_all = {"打印", "查看", "设置", "创建", "使用", "查询", "导出", "执行", "改", "修改", "更改", "更换", "重置"}
action_verbs_all = {"打印", "查看", "设置", "创建", "使用", "查询", "导出", "执行", "安装", "改", "修改", "更改", "更换", "重置"}
verb_obj_pairs = self._extract_verb_object(query_stripped, action_verbs_all)
if verb_obj_pairs:
adjusted = []
+19 -7
View File
@@ -1493,6 +1493,13 @@ class MessageMonitor:
logger.debug(f"[{platform}] OCR 过滤: 游戏UI乱码(CJK+大写英文) line={line!r}")
continue
# —— 绿色气泡 OCR 乱码:| 管道符混中文 ——
# bot 的绿色气泡/蓝色气泡文字经过 OCR 后常把 :; 识别为 |,
# 正常中文聊天从不混用 | 与中文。如 "GU |进行配置" "SMTP | 设置"
if '|' in line and re.search(r'[\u4e00-\u9fff]', line) and len(line) > 5:
logger.debug(f"[{platform}] OCR 过滤: 管道符碎片(绿色气泡) line={line!r}")
continue
# —— JSON/YAML 碎片兜底:OCR 截屏混入配置面板 ——
# 行首是 "key": value 或 key: value(YAML)→ 配置面板碎片
if re.match(r'^["\']?[a-zA-Z_][\w]*["\']?\s*:\s*["\d\[\{tfn]', line):
@@ -1538,19 +1545,19 @@ class MessageMonitor:
if len(r) < 5:
continue
sm = difflib.SequenceMatcher(None, line, r)
if sm.find_longest_match(0, len(line), 0, len(r)).size >= 8:
if sm.find_longest_match(0, len(line), 0, len(r)).size >= 6:
is_match = True
break
# 第二轮:CJK-only 降阈值匹配(OCR 碎片字母被啃掉时)
if not is_match:
cjk_line = ''.join(c for c in line if '\u4e00' <= c <= '\u9fff')
if len(cjk_line) >= 6:
if len(cjk_line) >= 5:
for r in self._replied_texts:
r_cjk = ''.join(c for c in r if '\u4e00' <= c <= '\u9fff')
if len(r_cjk) < 5:
continue
sm = difflib.SequenceMatcher(None, cjk_line, r_cjk)
if sm.find_longest_match(0, len(cjk_line), 0, len(r_cjk)).size >= 6:
if sm.find_longest_match(0, len(cjk_line), 0, len(r_cjk)).size >= 5:
is_match = True
break
if is_match:
@@ -2020,17 +2027,17 @@ class MessageMonitor:
if len(r) < 5:
continue
sm = difflib.SequenceMatcher(None, text, r)
if sm.find_longest_match(0, len(text), 0, len(r)).size >= 8:
if sm.find_longest_match(0, len(text), 0, len(r)).size >= 6:
return True
# CJK-only 降阈值
cjk_t = ''.join(c for c in text if '\u4e00' <= c <= '\u9fff')
if len(cjk_t) >= 6:
if len(cjk_t) >= 5:
for r in self._replied_texts:
r_cjk = ''.join(c for c in r if '\u4e00' <= c <= '\u9fff')
if len(r_cjk) < 5:
continue
sm = difflib.SequenceMatcher(None, cjk_t, r_cjk)
if sm.find_longest_match(0, len(cjk_t), 0, len(r_cjk)).size >= 6:
if sm.find_longest_match(0, len(cjk_t), 0, len(r_cjk)).size >= 5:
return True
return False
@@ -2955,6 +2962,10 @@ class MessageMonitor:
if re.search(r'[\u4e00-\u9fff][A-Z][a-z]{1,}', ts):
logger.debug(f"[{platform}] Poll过滤: 游戏UI乱码(CJK+大写英文) ts={ts!r}")
continue
# === 绿色气泡 OCR 乱码:| 管道符混中文(正常聊天从不混用)===
if '|' in ts and re.search(r'[\u4e00-\u9fff]', ts) and len(ts) > 5:
logger.debug(f"[{platform}] Poll过滤: 管道符碎片(绿色气泡) ts={ts!r}")
continue
# === JSON/YAML 碎片兜底:OCR 截屏混入配置面板 ===
if re.match(r'^["\']?[a-zA-Z_][\w]*["\']?\s*:\s*["\d\[\{tfn]', ts):
logger.debug(f"[{platform}] Poll过滤: JSON行 ts={ts!r}")
@@ -3083,8 +3094,9 @@ class MessageMonitor:
first = True
for item in new_items:
if not first:
logger.debug(f"[{platform}] 同poll第{new_items.index(item)+1}条,跳过防多发: {item[:40]}")
logger.debug(f"[{platform}] 同poll第条,跳过防多发: {item[:40]}")
continue
first = False # 只处理第一条
self._last_new_msg_time[platform] = time.time()
self._last_msg[platform] = item
engine_tag = self._last_chosen_engine.get(platform, "")