From 37b5d5c43182a58f04ecb0cf9735bfe2ce07a4ec Mon Sep 17 00:00:00 2001 From: HuangHai <10402852@qq.com> Date: Mon, 26 Jan 2026 20:07:58 +0800 Subject: [PATCH] 'commit' --- WeiXin/T2_ChatMonitor.py | 70 ++++++++++++++---- .../T2_ChatMonitor.cpython-310.pyc | Bin 8846 -> 11057 bytes 2 files changed, 54 insertions(+), 16 deletions(-) diff --git a/WeiXin/T2_ChatMonitor.py b/WeiXin/T2_ChatMonitor.py index ba51a2e..7cca277 100644 --- a/WeiXin/T2_ChatMonitor.py +++ b/WeiXin/T2_ChatMonitor.py @@ -63,7 +63,7 @@ class ChatMonitorBot: self.input_pos = None self.last_screen_hash = None self.last_processed_msg_hash = None - self.check_interval = 5 # 检查频率 (秒) + self.check_interval = 3 # 检查频率 (秒) self.persona = ( "你是一名1999年毕业、拥有27年一线教学经验的小学高级女教师,名叫‘大张老师’。你目前在‘长春市少惠林作文素养培养中心’工作。" @@ -222,15 +222,51 @@ class ChatMonitorBot: # 初始化最后处理的消息哈希,避免重复回复第一条 last_msg = self.dialogue_log[-1] - # last_msg 是字典,需要转字符串再 encode - msg_str = json.dumps(last_msg, sort_keys=True, ensure_ascii=False, default=numpy_serializer) - self.last_processed_msg_hash = hashlib.md5(msg_str.encode('utf-8')).hexdigest() + + # --- 初始回复逻辑 (Added) --- + # 如果最后一条是对方发的消息,说明可能需要回复 + sender = last_msg.get('sender', '') + # 判断逻辑:只要不是"我",就认为是对方 (可能是 "对方", "糖豆爸爸" 等) + if sender != "我": + logger.info(f"💡 [首屏] 最后一条消息来自 '{sender}',尝试生成回复...") + + # 构建上下文 + context_text = "\n".join([f"{m.get('sender')}: {m.get('content')}" for m in self.dialogue_log[:-1]]) + last_content = last_msg.get('content', '') + + reply = await self.get_reply(last_content, context_text) + if reply: + logger.info(f"🤖 [首屏] LLM 建议回复: {reply}") + + # 检查输入框位置 + if self.input_pos: + logger.info(f"⚡ [首屏] 执行自动回复...") + perform_input_action(self.device, self.input_pos, reply) + + # 发送后更新 hash,避免进入循环后重复回复 + # 发送后,界面会变,但我们需要标记当前这条已经回过了 + msg_str = json.dumps(last_msg, sort_keys=True, ensure_ascii=False, default=numpy_serializer) + self.last_processed_msg_hash = hashlib.md5(msg_str.encode('utf-8')).hexdigest() + + logger.info("✅ [首屏] 回复已发送") + else: + logger.warning("❌ [首屏] 未找到输入框位置,无法发送") + else: + logger.info("⚪ [首屏] LLM 认为无需回复") + else: + logger.info("⚪ [首屏] 最后一条是自己发的,无需回复") + + # 更新 Hash (如果刚才没发回复,也需要记录当前最后一条,防止循环里重复处理) + if not self.last_processed_msg_hash: + msg_str = json.dumps(last_msg, sort_keys=True, ensure_ascii=False, default=numpy_serializer) + self.last_processed_msg_hash = hashlib.md5(msg_str.encode('utf-8')).hexdigest() + self.last_screen_hash = self.get_image_hash(self.screenshot_path) else: logger.warning("⚠️ 首次运行未识别到有效对话") - logger.info("🛑 测试结束:已完成所有语音的转换与读取。停止进入监控循环。") - return # 测试模式:直接退出,不进入监控循环 + # logger.info("🛑 测试结束:已完成所有语音的转换与读取。停止进入监控循环。") + # return # 测试模式:直接退出,不进入监控循环 # 3. 进入循环阶段 logger.info("🔄 进入实时监控阶段...") @@ -275,40 +311,42 @@ class ChatMonitorBot: # E. 判断是否需要回复 (对方发送且非重复消息) sender = last_msg.get('sender', '') - if sender == "对方": + if sender != "我": if current_msg_hash != self.last_processed_msg_hash: event_shot = WxUtil.get_next_debug_path("event_new_msg") self.device.screenshot(event_shot) - logger.info(f"💡 发现新消息: {last_msg},保存现场截图: {event_shot}") + logger.info(f"💡 [监控] 发现新消息: {last_msg},保存现场截图: {event_shot}") - # 获取上下文文本 - context_text = "\n".join(dialogue_log[:-1]) + # 获取上下文文本 (格式化为 Sender: Content) + context_text = "\n".join([f"{m.get('sender')}: {m.get('content')}" for m in dialogue_log[:-1]]) + last_content = last_msg.get('content', '') # 生成回复 - reply = await self.get_reply(last_msg, context_text) + reply = await self.get_reply(last_content, context_text) if reply: - logger.info(f"🤖 LLM 回复: {reply}") + logger.info(f"🤖 [监控] LLM 建议回复: {reply}") if self.input_pos: + logger.info(f"⚡ [监控] 执行自动回复...") perform_input_action(self.device, self.input_pos, reply) # 发送后截图留存 reply_sent_shot = WxUtil.get_next_debug_path("event_reply_sent") self.device.screenshot(reply_sent_shot) - logger.info(f"✅ 回复已发送,保存发送后截图: {reply_sent_shot}") + logger.info(f"✅ [监控] 回复已发送,保存发送后截图: {reply_sent_shot}") self.last_processed_msg_hash = current_msg_hash else: - logger.warning("❌ 未找到输入框位置,无法发送") + logger.warning("❌ [监控] 未找到输入框位置,无法发送") else: - logger.warning("⚠️ LLM 未生成有效回复") + logger.warning("⚠️ [监控] LLM 未生成有效回复") else: # 消息已处理过 pass else: # 最后一条是我发送的 if current_msg_hash != self.last_processed_msg_hash: - logger.info(f"⚪ 最后一条消息非对方发送,跳过回复: {last_msg}") + logger.info(f"⚪ [监控] 最后一条消息是自己发的,跳过回复: {last_msg}") self.last_processed_msg_hash = current_msg_hash await asyncio.sleep(self.check_interval) diff --git a/WeiXin/__pycache__/T2_ChatMonitor.cpython-310.pyc b/WeiXin/__pycache__/T2_ChatMonitor.cpython-310.pyc index 234ca5ea712c0314b18acfd152f4d4daeb0d39ec..623eeffc4ee8a740bf6447a122ec2bc4c4659a37 100644 GIT binary patch delta 3824 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 delta 1551 zcmZWpZA@EL81Cr@{a7ibrZPSHr5Cg>&`4mUF=Q~Ytc>pg8RwD&gWUIryK zpuuE|j)^Dk$JnGSF(!)}K|(Z{ABiUZ^3UQAlk-<8b$|5F;$lqneQ$}7(4VN}2pPZZ47LKfkzIPG9@44cnp8xGSP8v5}bZ>fqdg$i|>OseB zXxO+KSaOm$k5_lsbtCNt5FXQFT288By?ng-=w3a)Q+*Gr%!iu8J^xqPDRnCpBS)S@ zwjaTXl|l(a*J;9%ReC{7P}Yp3hcad`wy!`iTqaQbLG3u;XynAOUF;dyBKcS^?(`?M z43%?=l@=~7n-V0+>VRiHfUyG!X5?~ImF*0z{KHCbd^?h>X#x?R(GT!7i%y4@pZgorek{Ls>G(9Ce_Db-Nnx(y` zyYXZ54HAe$f9x!P;MtaKGRt3YeLy6BvTe0yNOB3kX)sHkq2 zvb@w$+I+vf_VM;zUb?aJ$Jf`kzWieA&IhH7AC@l7m#$wbuigHAWn=r=LiwA|OP6o{ z_SIr}?e5lb$i6D9Tgn_qRLE9Sz3mLkf}j<4rzD7$mLlp#%&n8GE^5XsAfBm z4PgQ&FWeKRp$m^XmCc!K5a}0?uA+LvP$@f#OtcH}Btj=9z0(TQ@tpa??v}Ynkcud} zlF83fIgwT@aEOwk;vhD!(;0N<`KgrcD|QI0Jb~Z>keY1cu~DoMpfF8Vv7bMgQFeBW zW6qT|Q|uh9*c%x7Ae60qj*ivxg`V2D@L?dsy<(4{=y8O@2rt|6i~4OA1sRE&MzRDdTY?fb%zxo#J^3j=utm#QZ8n9g{V2$S_e*C-gm>iharxNrnK5t1NXa0r_|2D9CMiT_Wxx^K z>WBG{7%8})w!wwZgqU8S8Q~s2HFR3=pQWy+M9?muR&+H37dZ%;A%kTV3#=ggyUT#0 zswZ|tT{^=PRda|DbMb9()BxfPRrm!0iJZp(Gv-n(JW4rBt jw1#~N_6>z^_R+>*!0U55oe^gcrW__+#5eE!*ZtRjLrBMw