From f32502536563802d8b352a18d91c37128a3cabc9 Mon Sep 17 00:00:00 2001 From: jesxion Date: Mon, 13 Apr 2026 12:08:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E6=94=B9=E8=BF=9BVL?= =?UTF-8?q?M=E6=9C=AA=E8=AF=BB=E5=88=A4=E6=96=AD=20+=20=E4=BF=AE=E5=A4=8Dc?= =?UTF-8?q?allback=E6=98=BE=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. VLM prompt: has_new_message 改为检查左侧边栏红点,而非右上角 2. engine.py: callback 显示最新消息,清晰标注 has_new 3. main.py: on_message 回调更新以显示 has_new 状态 --- src/__pycache__/main.cpython-311.pyc | Bin 9986 -> 10448 bytes src/core/__pycache__/engine.cpython-311.pyc | Bin 19013 -> 19944 bytes src/core/engine.py | 17 ++++++++++++++--- src/main.py | 10 ++++++++-- src/vlm/__pycache__/qwen_vl.cpython-311.pyc | Bin 20759 -> 21058 bytes src/vlm/qwen_vl.py | 12 ++++++++---- 6 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/__pycache__/main.cpython-311.pyc b/src/__pycache__/main.cpython-311.pyc index ea78181c88229ee0eefcc141db776f7428dbb89b..f01c583291f0ff6909f25c887fefb21f22a6c6e0 100644 GIT binary patch delta 939 zcmZ`$OK1~87@pZ=lTFeFvrX+LtuYo-nx+pZdQhlh5$!?x(4vN-%Qm|)k#tjb*H^ox zRS;r52pMYvMTj13!9$f|vEa>%#{{+z7V&1i7JAW(IFqENv^dOs^Z)<%@y+9ZJX{=e zuQWC~0Uj->Z%Kyx;GS*qHsG`guiYCEfF+m%Iw+tMl$Qe{6sflq0PpasjyYH-ElF^I zr0S$qqz{l5o!Yat9kR97N&6v^u8}?#Q@3Jt={AfFx&>pS zPA`L3PPE`_o_7zMj#xs_cv+Z|ln8#6=}rlnq-y+>q^iPg$+RZ~m6xUa7fqWg$)cnv z=ZMUnRC!fO#qYXtw*6w`N9O(ZMrQlbT5w{uje9L?%DzL0psFG~qsqdxnn-KtOW+h-T>l+-V+q*lIk*G0N$k0(1JOK74@8j?Ta6*ADRj delta 588 zcmcZ**yP8zoR^o20SJUs?qq%u+sIcfF3b+%0`cbpATgD3IzuPpWCaOvd&U}uEJmOZ z7|do!VFL1*VEiIpWL^rhBus)Kk1>U1Hp5(&$rrdqm^E4bCL2nM*f7UhDZKm-1Xav_ z`i`2+w^%as((-R{CTAp;#OEdErWRQO4bWt|#ZjD>SWujiUsB`(6etGSH+h$&k(V2g z@uPv^1_xh1cNg~sk>UjrS5(b`Gzf*pUI|URU{komg+Cnw2yi#;Q;I6g16 ze6o(*J)rU2@_X3gL1rdSJ}W;>vlL_$Yhrq8UP%#>eINx8RUlRnkeEDC!IZIM^Kpem z%yNvZrHmgKaFA@9+f~w-7}F=eQ&SKq1R2i}AD@<)lNujils8#UJ;1aIWF{!0i#R}p z5Qyji5w1XDB|{M?{)+^G#4iq;-29Z%oK(A_$&(kWe-;X6VwCy7fJEj@UZJ4@0JdX!}w9>TOPN#*j)7grxJKeFDBnG6Da@xDKLZx)TkSq!Eph8(+BZjmM5?(!$We8VXX zS;u~9T0*MWH>S;`E?6G-M3b=&jA$`HNb72IDj|JMuS@Duyq$hp#hMapNJH>UVun~; z2PzE?9bJL?8xZOdHX?ivz@eq3NH0TZM5tpAEZ%bk`Zkbs#{*P(B)?*xzIlE6_{j8!R~+%Q1C2}wsR&g7q39kb^?Usu`VRJV zE}!J2l%lwknQf^KKWEE|lPV!yi`3y&=q8l*0>}iwPBXAS7;Lm{6&Jr^_Q7*ApZ=)9 z5v$IiktK!t*;jU3GI!?y8lxxSVS^;=8X;|LG&|kF-S_}y-068pz1rw;_FgpdFAN*) zduqg2`f8)=3mU9*)0)5owK7J#e)u-n6Xxj*=(V}it* zfrtEm|4A1tTsA_;4Esw?S)5`4Uicf1Wm&l?bqdZA{sOwo5SC9cH2ga&xQ*vEb9qEi z(j#&~2*Jbkp+CXeT13GEvUYLOh0bviG8vYHNLEpmKbCZaLoyf}~R_0ukMB>@q zJR5M$G5yAXkv1t@n42Cjf`b`z9dyrsdDFp>Bpf&;V4UlHzbWElnk`_OyLKYDW10k* zDlI>2LFQb$h%Dl_AV5OEN{OBQBQHI3=`;R9fiCEun>s0|smTh&vGV-1__%#>J)}qI z)od4fh$EXx`5VdmY%Je4(47dw%-lFMGdMDR==6h&S03IzG<|Ta8@GAp{Kbd2kIwvH zG%P=NW%}^3hqn)}?$g-q&3*b^c3JYfC0b6)K%1^bC|4Li>@4>jM)K5m#YTTUBJ8ivZIvX)LQDwxV#G_^2iRUlh6^4yDn!9@2#>JYui*-QLZ9&`em862WR~Mvm7kH0bMga2I_B4h*m-RefNoh@FIzj-f?rVrn@lAGe)8H%OdK1ptIb$0s|M-0DZ zLpr#%yCr_sDFY?-YDaZ?5upU3m;Gc-5ouymYla4JWIBj&7~u%QF@*gHA0yxnsvCL< zsc3{T1YQARkkTXEMzA8_{i-gp6)6N9Sgs{_P9wi5ZOS-%Sa!j@RtI_X6e>k_zWg|8 z4d$)gLdXgBUPUeGWp^ry$lL6H6}3@KIOIXLp>kE~K^#;Bh&&!n0o|9u{#=pFu2n`8 z54%xWoBj(lc=5@Go70!YHFK(rWKVEa)ezbJ8{mcv9!XK8jxM*ChBS>EHqkrC)%c~J zkXClSEAb6+M5}TB5(obZf!k`koJw2Rz}w-GakF^DBOYD=#>v`L*09b%I@tDgXQD7E zT_PJ@WnsqZO{H6)+ovlmSY2GSh5j5m4v~HV4INc!o?U1&XW>`bN7V~R4+~ZwFrhXW zamD-W^_unM`|L=~n^C{UQF_@-&6>=85D3`>{r$p}HS>`6X#64g@whn%ZDN(Rd9}Eg zY7X%PK*#A-fRF~BhZIwp{vP2E2rq>FbL1iHVxQH1myVRfN|TX$0w5Ia>-2c=;oZr; ztaD{np#a@c?;HnG`3O9HK4%-&&nJHkde--ng3TIYm=#`)k2wGF^HMj9uV3+hO@}lF delta 2393 zcmZvedrVVT7{KqLEst9(g|>nPc_=}yIw(cOH!@yD7(PIqiLrL&%EQt&=U$$o;$su% zjNma2pD|9+X_V>Bd_+uUbkpn)C!5aY#w9ab873Mr)5I($+xbobAMrqcJ?DJickb8k zeBaj&96;aiL8DI?3_M52PqhzfQf%i&n|VVEKP9O~a!R6S&D<6xgWsb;x#Wf+4dsw0 zhJ~m=nLGMlO?)mj!dVom)?MwA)rf*7x9FE^d|sSG%A*TVsj@FRJ|wGvs+0*jJRS6l z01iMgpoBuu;%t~t29yB`$bk8YH4mn#fQ5ikKqz39^3;;AMJ{EkH4&k;N<|zFS+Ism z>LV#~t3+&$ zf`z%$2FBpY(6I_iK8w&A^3C`-fw{32WX$PUn7!ZV`S@lq@}>+KwT>9EPx^kN^C{0Y z86wpz6U=xjSX5D{2EWhaan^Wc5jVIzL9atu7RcC7?xiKVn7ivhH_YwxdPTRa@=j*u z^SVX+F&q^IU~Z3v*=rBrA_YzGrgws9C55D+NJ<)tJc$aoMC)6_yF)ncG<^jJB7ekBAY(I3$Vy7aC8JTqm1@%Khs8%CshOF| zjp6GfS|f0|%+z8Gtr3;sm7_lm0Z)VD09P4F`Z6rY2qt4%Bf9BTpN8vZV?96Y#8_i1 z|Be$}Wq3J9kNzMdnOM^!iO&|sTZb(<(lId>MH83JOwQQCOc0Hsk;35#>-E$y$Cj)y zwd%>k*=F*eO&6)(pl?KtT$5%6*N6l&F=dvZ&BU3Rpu=uzOUB!aP$j9g$8EIHe;BesB&ZoWYv;+ovuJm7M@88tZ-@bQX+o{0CbAer*kJ>gp?cH8)rbYu- z&kpn)4IJD0cgJUe-pzqamu4jimS8^ck{gSnSE}~OxSHy!F)pvm)7&CDq1v5qNLR5= zunTmw)h?+zShNyd;{-q(pccSN`gPVrU8}q#dMlk+^n02yBp03!7)d5!6j_{ARH0)E zYA6<^dXF4To>5ehCeO$SRwSXjEn}98dDKhR3({Zb=nE>7KBS4$#tmvS$*Zh8qpXId zs4MLm2k+$9srJmlXfDd~CBK{RnsYL?&uG7EwBIq>2SYh??4Eh|P3b?I(oZ(^nP%KI z%^2kPC~DO?{j0?CK6AxgbH$zE|G{Z+;2=Bp<%=1lJUf32xgm#hCyh7AK>hkPpDLIl?7`hk?w~)tqGo!cAsRSKtIBvU1c78HiNmk?+ zj_C!x2GDrpo2HX|o1coD%7gqa6my*lRlZ7;WwFj*S%X#0qT*6~gX}1b8*>e;ZvmK= z*6)(5si?QmiuRNHg(>J0@~UtjT1NI3iP=l2UW+c%HY>|sfv?bo5Q49Q?bpFMyLU*j zx12pr?2ZY@LzX!<8$g>HF~vR-a5#{kq!%v@{f_R_TiISbTY!%t!IwfC_nS4bUHe63 zJN;u36%b}o$)r-jNX}WTi&DUFB49V5695U1_XCbos2ch;g(30qFMxZ1cP{BN>;aaL z_(AUd Qe8%>lzbP#v=RcbMKf)VnfdBvi diff --git a/src/core/engine.py b/src/core/engine.py index b1ed841..45aa280 100644 --- a/src/core/engine.py +++ b/src/core/engine.py @@ -275,8 +275,19 @@ class WeChatAgent: has_new=has_new ) - # 触发消息回调 - self._emit("on_message", snapshot) + # 详细日志:打印所有消息(按VLM返回顺序) + logger.debug(f"消息列表(共{len(messages)}条,新消息在前):") + for i, msg in enumerate(messages[:5]): + logger.debug(f" [{i}] sender={msg.get('sender')}, is_self={msg.get('is_self')}, time={msg.get('time')}, content={msg.get('content', '')[:30]}") + + # 触发消息回调(传入最新消息用于显示) + latest_msg = messages[0] if messages else {} + self._emit("on_message", { + "chat_name": chat_name, + "latest_message": latest_msg, + "has_new": has_new, + "all_messages": messages + }) # 判断是否需要回复 if self.processor.should_reply(snapshot): @@ -289,7 +300,7 @@ class WeChatAgent: else: logger.warning("生成回复为空") else: - logger.debug("不需要回复(已读消息或自己发送)") + logger.debug("不需要回复") except Exception as e: logger.error(f"轮询处理异常: {e}") diff --git a/src/main.py b/src/main.py index 915092d..aeec5b1 100644 --- a/src/main.py +++ b/src/main.py @@ -121,8 +121,14 @@ def main(): ) # 注册回调 - def on_message(snapshot): - logger.info(f"收到消息 [{snapshot.chat_name}]: {snapshot.messages[-1] if snapshot.messages else 'N/A'}") + def on_message(data): + chat_name = data.get("chat_name", "") + latest = data.get("latest_message", {}) + has_new = data.get("has_new", False) + sender = latest.get("sender", "") + content = latest.get("content", "") + is_self = latest.get("is_self", False) + logger.info(f"收到消息 [{chat_name}]: sender={sender}, is_self={is_self}, has_new={has_new}, content={content}") def on_reply(result): if result.success: diff --git a/src/vlm/__pycache__/qwen_vl.cpython-311.pyc b/src/vlm/__pycache__/qwen_vl.cpython-311.pyc index ed1e7613ea9152dc2ca7351c77e439c07ef12ab7..85275b3617f6b035cbd7a42bcc51615de57b1cc0 100644 GIT binary patch delta 679 zcmbQfi1E-8M!w~|yj%=Gpq_IlbG!XUzQcM<0j!%Z>s@86=X%^QAtSLkJ}XcsWpZR1*!;6JI&!#tm z)XZ4_bi%S{b2^{zTJ)mRa?{f}ZO@x_>OY&h;py7xKzp7pYkD?s4p9EtoK-K@?|!zR z{l&TsKudtiLF#}MMCoK5L)Ch?@=Xgdbo8Km>&cE?3TcTs#i=0QY+muK1?bpWPkT2% z*}MPg-pNlpd!Mac{B+I=pf7>W2fKO|#JfNbL0tv52I!2Z?Ym#>pZ!#!Z}+op9WQ4t zfjADR?#b@n=PlcwubU2W{p0|{Mq5b8AqUcn_0WI>g$h!5pm-2!!ec{U9Z(qeZw7|( z(}k;*o^?!A0=Wnr=svw{pYR1;*%Yot4x!J%dkBMDcNVJ3PgVpAxCNEhTBRBV3 zH8C+(Z5Fbf!^GIOdA+?klYtu}tMZ284-6oBN67)_6T$~P_S8Z6Sjd3QVonWAjI$?C zcUi_bb+etTAS2_N%>i!tER35rAMmnfX1uWZkFOe&K^iNg)dvRb$w2`} E0gM86T>t<8 delta 334 zcmX@KgmL;JM!w~|yj%=GV4QU)v&(KH-(fu_RhG?{^{z7Nnd&LLZ0~*EwDbL*Ss97N z@p-A`@wutR#fj;u3Qzl|J#E|kWLMwQ{>@KzbiG(UX|klDjMB3O?Jw4C;4;%wc)G0V z*}OSV_fCG=+54ig>*2bG3Uu3*)-Yuf46A8P9B1 c_g7;wNMdEQ`oMsl{0J8Rf-LJbxi;`905wvG5C8xG diff --git a/src/vlm/qwen_vl.py b/src/vlm/qwen_vl.py index a5edb4f..8f28a2b 100644 --- a/src/vlm/qwen_vl.py +++ b/src/vlm/qwen_vl.py @@ -301,16 +301,20 @@ class BailianVLMClient: 2. is_self 的判断只看消息位置(右侧=true,左侧=false),与 sender 名字无关 3. 右侧消息的 sender 应该是"我",左侧消息的 sender 是对方昵称 4. current_chat 是聊天窗口顶部的标题,如"尾巴~" -5. 重点:has_new_message 取决于右上角是否有红色圆点/数字标记 -6. 如果当前聊天窗口有未读标记(红点),has_new_message 必须为 true + +【has_new_message 判断方法】: +- 检查聊天列表区域(左侧边栏),看"尾巴~"这一行旁边是否有红色圆点/数字 +- 如果有未读标记(红点/红数字),has_new_message 必须为 true +- 如果没有未读标记,has_new_message 为 false +- 注意:即使当前正在查看这个聊天,如果没有点击进去消除红点,仍然算未读 返回 JSON: { "current_chat": "聊天窗口标题(顶部标题栏)", - "has_new_message": true或false(重点:看右上角红色标记), + "has_new_message": true或false(重点:检查左侧边栏该聊天行是否有红点/红数字未读标记), "messages": [ { - "sender": "发送者昵称", + "sender": "发送者昵称(右侧填\"我\",左侧填对方昵称)", "content": "消息内容", "time": "时间", "is_self": true(右侧气泡=我发的)或false(左侧气泡=对方发的)