mirror of
https://github.com/Zippland/Bubbles.git
synced 2026-01-19 01:21:15 +08:00
主动开聊
This commit is contained in:
16
README.MD
16
README.MD
@@ -170,6 +170,22 @@ GROUP_MODELS:
|
||||
max_history: 50 # 回顾最近50条消息
|
||||
```
|
||||
|
||||
#### 群聊随机闲聊回复
|
||||
|
||||
如果希望机器人在群聊中偶尔主动开聊,可在 `groups.models.mapping` 中为群添加 `random_chitchat_probability`:
|
||||
|
||||
```yaml
|
||||
groups:
|
||||
models:
|
||||
mapping:
|
||||
- room_id: "12345678@chatroom"
|
||||
model: 2
|
||||
max_history: 30
|
||||
random_chitchat_probability: 0.3 # 0-1,0 表示关闭
|
||||
```
|
||||
|
||||
未设置该字段的群默认关闭;写入 0 可以显式禁用。
|
||||
|
||||
#### 功能开关
|
||||
|
||||
您可以启用或禁用各种功能:
|
||||
|
||||
@@ -62,9 +62,11 @@ groups:
|
||||
- room_id: example12345@chatroom
|
||||
model: 2
|
||||
max_history: 30 # 回顾最近30条消息
|
||||
random_chitchat_probability: 0.2 # 群聊随机闲聊概率(0-1),0 表示关闭
|
||||
- room_id: example12345@chatroom
|
||||
model: 7
|
||||
max_history: 30 # 回顾最近30条消息
|
||||
random_chitchat_probability: 0.0 # 可单独覆盖默认概率
|
||||
# 私聊映射
|
||||
private_mapping:
|
||||
- wxid: filehelper
|
||||
|
||||
@@ -13,6 +13,21 @@ class Config(object):
|
||||
def __init__(self) -> None:
|
||||
self.reload()
|
||||
|
||||
@staticmethod
|
||||
def _normalize_random_chitchat_probability(entry, fallback_probability=0.0):
|
||||
if isinstance(entry, (int, float)):
|
||||
probability = entry
|
||||
elif isinstance(entry, dict):
|
||||
probability = entry.get("probability", fallback_probability)
|
||||
else:
|
||||
probability = fallback_probability
|
||||
try:
|
||||
probability = float(probability)
|
||||
except (TypeError, ValueError):
|
||||
probability = fallback_probability
|
||||
probability = max(0.0, min(1.0, probability))
|
||||
return probability
|
||||
|
||||
def _load_config(self) -> dict:
|
||||
pwd = os.path.dirname(os.path.abspath(__file__))
|
||||
try:
|
||||
@@ -33,6 +48,42 @@ class Config(object):
|
||||
self.GROUPS = yconfig["groups"]["enable"]
|
||||
self.WELCOME_MSG = yconfig["groups"].get("welcome_msg", "欢迎 {new_member} 加入群聊!")
|
||||
self.GROUP_MODELS = yconfig["groups"].get("models", {"default": 0, "mapping": []})
|
||||
legacy_random_conf = yconfig["groups"].get("random_chitchat", {})
|
||||
legacy_default = self._normalize_random_chitchat_probability(
|
||||
legacy_random_conf.get("default", 0.0) if isinstance(legacy_random_conf, dict) else 0.0,
|
||||
fallback_probability=0.0,
|
||||
)
|
||||
legacy_mapping = {}
|
||||
if isinstance(legacy_random_conf, dict):
|
||||
for item in legacy_random_conf.get("mapping", []) or []:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
room_id = item.get("room_id")
|
||||
if not room_id:
|
||||
continue
|
||||
legacy_mapping[room_id] = self._normalize_random_chitchat_probability(
|
||||
item,
|
||||
fallback_probability=legacy_default,
|
||||
)
|
||||
|
||||
random_chitchat_mapping = {}
|
||||
for item in self.GROUP_MODELS.get("mapping", []) or []:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
room_id = item.get("room_id")
|
||||
if not room_id:
|
||||
continue
|
||||
if "random_chitchat_probability" in item:
|
||||
rate = self._normalize_random_chitchat_probability(
|
||||
item["random_chitchat_probability"],
|
||||
fallback_probability=legacy_default,
|
||||
)
|
||||
random_chitchat_mapping[room_id] = rate
|
||||
elif room_id in legacy_mapping:
|
||||
random_chitchat_mapping[room_id] = legacy_mapping[room_id]
|
||||
|
||||
self.GROUP_RANDOM_CHITCHAT_DEFAULT = legacy_default
|
||||
self.GROUP_RANDOM_CHITCHAT = random_chitchat_mapping
|
||||
self.NEWS = yconfig["news"]["receivers"]
|
||||
self.CHATGPT = yconfig.get("chatgpt", {})
|
||||
self.DEEPSEEK = yconfig.get("deepseek", {})
|
||||
|
||||
59
robot.py
59
robot.py
@@ -52,7 +52,32 @@ class Robot(Job):
|
||||
self.wxid = self.wcf.get_self_wxid() # 获取机器人自己的wxid
|
||||
self.allContacts = self.getAllContacts()
|
||||
self._msg_timestamps = []
|
||||
self.group_random_reply_rate = 0.3
|
||||
default_random_prob = getattr(self.config, "GROUP_RANDOM_CHITCHAT_DEFAULT", 0.0)
|
||||
try:
|
||||
self.group_random_reply_default = float(default_random_prob)
|
||||
except (TypeError, ValueError):
|
||||
self.group_random_reply_default = 0.0
|
||||
self.group_random_reply_default = max(0.0, min(1.0, self.group_random_reply_default))
|
||||
|
||||
mapping_random_prob = getattr(self.config, "GROUP_RANDOM_CHITCHAT", {})
|
||||
self.group_random_reply_mapping = {}
|
||||
if isinstance(mapping_random_prob, dict):
|
||||
for room_id, rate in mapping_random_prob.items():
|
||||
try:
|
||||
numeric_rate = float(rate)
|
||||
except (TypeError, ValueError):
|
||||
numeric_rate = self.group_random_reply_default
|
||||
numeric_rate = max(0.0, min(1.0, numeric_rate))
|
||||
self.group_random_reply_mapping[room_id] = numeric_rate
|
||||
|
||||
if self.group_random_reply_default > 0:
|
||||
self.LOG.info(
|
||||
f"群聊随机闲聊默认开启,概率={self.group_random_reply_default}"
|
||||
)
|
||||
for room_id, rate in self.group_random_reply_mapping.items():
|
||||
self.LOG.info(
|
||||
f"群聊随机闲聊设置: 群={room_id}, 概率={rate}"
|
||||
)
|
||||
|
||||
try:
|
||||
db_path = "data/message_history.db"
|
||||
@@ -335,18 +360,20 @@ class Robot(Job):
|
||||
# 调用handle_chitchat函数处理闲聊,传递完整的上下文
|
||||
self._handle_chitchat(ctx, None)
|
||||
else:
|
||||
can_auto_reply = (
|
||||
not msg.from_self()
|
||||
and ctx.text
|
||||
and (msg.type == 1 or (msg.type == 49 and ctx.text))
|
||||
)
|
||||
if can_auto_reply:
|
||||
rand_val = random.random()
|
||||
if rand_val < self.group_random_reply_rate:
|
||||
self.LOG.info(
|
||||
f"触发群聊主动闲聊回复: 概率阈值={self.group_random_reply_rate}, 随机值={rand_val:.2f}"
|
||||
)
|
||||
self._handle_chitchat(ctx, None)
|
||||
rate = self._get_group_random_reply_rate(msg.roomid)
|
||||
if rate > 0:
|
||||
can_auto_reply = (
|
||||
not msg.from_self()
|
||||
and ctx.text
|
||||
and (msg.type == 1 or (msg.type == 49 and ctx.text))
|
||||
)
|
||||
if can_auto_reply:
|
||||
rand_val = random.random()
|
||||
if rand_val < rate:
|
||||
self.LOG.info(
|
||||
f"触发群聊主动闲聊回复: 群={msg.roomid}, 概率阈值={rate}, 随机值={rand_val:.2f}"
|
||||
)
|
||||
self._handle_chitchat(ctx, None)
|
||||
|
||||
# 7.4 私聊消息,未被命令处理,进行闲聊
|
||||
elif not msg.from_group() and not msg.from_self():
|
||||
@@ -618,6 +645,12 @@ class Robot(Job):
|
||||
}
|
||||
return mapping.get(model_id)
|
||||
|
||||
def _get_group_random_reply_rate(self, room_id: str) -> float:
|
||||
mapping = getattr(self, 'group_random_reply_mapping', {})
|
||||
if room_id and isinstance(mapping, dict) and room_id in mapping:
|
||||
return mapping[room_id]
|
||||
return getattr(self, 'group_random_reply_default', 0.0)
|
||||
|
||||
|
||||
def _select_model_for_message(self, msg: WxMsg) -> None:
|
||||
"""根据消息来源选择对应的AI模型
|
||||
|
||||
Reference in New Issue
Block a user