feat:识别群昵称
This commit is contained in:
@@ -195,6 +195,10 @@ class AutoReply(PluginBase):
|
||||
if not content:
|
||||
return True
|
||||
|
||||
# 跳过指令类消息(避免和各插件命令冲突、也避免“命令触发后又被自动回复补一句”)
|
||||
if content.startswith("/"):
|
||||
return True
|
||||
|
||||
# 跳过机器人自己的消息
|
||||
if self._is_bot_message(message):
|
||||
return True
|
||||
@@ -297,6 +301,13 @@ class AutoReply(PluginBase):
|
||||
self._update_state(chat_id, replied=False)
|
||||
return
|
||||
|
||||
# 如果在判断期间机器人已经发过言(例如 AIChat/@回复或其他插件回复),则跳过本次主动回复
|
||||
# 避免同一条消息触发“回复两次”的观感。
|
||||
if await self._bot_replied_since(pending.from_wxid, pending.trigger_time):
|
||||
logger.info(f"[AutoReply] 检测到机器人已回复,跳过自动回复 | 群:{pending.from_wxid[:15]}...")
|
||||
self._update_state(chat_id, replied=False)
|
||||
return
|
||||
|
||||
# 触发回复
|
||||
logger.info(f"[AutoReply] 触发回复 | 群:{pending.from_wxid[:15]}... | 评分:{judge_result.overall_score:.2f} | 耗时:{elapsed_time:.1f}s | {judge_result.reasoning[:30]}")
|
||||
|
||||
@@ -320,6 +331,55 @@ class AutoReply(PluginBase):
|
||||
if chat_id in self.pending_tasks:
|
||||
del self.pending_tasks[chat_id]
|
||||
|
||||
def _parse_history_timestamp(self, ts) -> Optional[float]:
|
||||
"""将历史记录中的 timestamp 转成 epoch 秒。"""
|
||||
if ts is None:
|
||||
return None
|
||||
if isinstance(ts, (int, float)):
|
||||
return float(ts)
|
||||
if isinstance(ts, str):
|
||||
s = ts.strip()
|
||||
if not s:
|
||||
return None
|
||||
try:
|
||||
return float(s)
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
return datetime.fromisoformat(s).timestamp()
|
||||
except Exception:
|
||||
return None
|
||||
return None
|
||||
|
||||
async def _bot_replied_since(self, group_id: str, since_ts: float) -> bool:
|
||||
"""检查 group_id 在 since_ts 之后是否出现过机器人回复。"""
|
||||
try:
|
||||
history = await self._get_history(group_id)
|
||||
if not history:
|
||||
return False
|
||||
|
||||
since_ts = float(since_ts or 0)
|
||||
if since_ts <= 0:
|
||||
return False
|
||||
|
||||
# 只看最近一小段即可:如果机器人真的在这段时间回复了,必然会出现在末尾附近
|
||||
for record in reversed(history[-120:]):
|
||||
role = record.get("role")
|
||||
nickname = record.get("nickname")
|
||||
if role != "assistant" and not (self.bot_nickname and nickname == self.bot_nickname):
|
||||
continue
|
||||
|
||||
ts = record.get("timestamp") or record.get("time") or record.get("CreateTime")
|
||||
epoch = self._parse_history_timestamp(ts)
|
||||
if epoch is None:
|
||||
return False
|
||||
return epoch >= since_ts
|
||||
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.debug(f"[AutoReply] bot reply 检查失败: {e}")
|
||||
return False
|
||||
|
||||
async def _trigger_ai_reply(self, bot, from_wxid: str):
|
||||
"""触发 AIChat 生成回复(基于最新历史上下文)"""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user