Merge pull request #772 from na10xi27da/dev
改进Mxp意愿模式的基础意愿计算方式,新增疲劳机制,新增优雅的调试输出,顺便修一下message_buffer
This commit is contained in:
@@ -3,7 +3,7 @@ from src.common.logger import get_module_logger
|
|||||||
import asyncio
|
import asyncio
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from .message import MessageRecv
|
from .message import MessageRecv
|
||||||
from ..message.message_base import BaseMessageInfo, GroupInfo
|
from ..message.message_base import BaseMessageInfo, GroupInfo, Seg
|
||||||
import hashlib
|
import hashlib
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
@@ -130,22 +130,36 @@ class MessageBuffer:
|
|||||||
keep_msgs = OrderedDict()
|
keep_msgs = OrderedDict()
|
||||||
combined_text = []
|
combined_text = []
|
||||||
found = False
|
found = False
|
||||||
type = "text"
|
type = "seglist"
|
||||||
is_update = True
|
is_update = True
|
||||||
for msg_id, msg in self.buffer_pool[person_id_].items():
|
for msg_id, msg in self.buffer_pool[person_id_].items():
|
||||||
if msg_id == message.message_info.message_id:
|
if msg_id == message.message_info.message_id:
|
||||||
found = True
|
found = True
|
||||||
type = msg.message.message_segment.type
|
if msg.message.message_segment.type != "seglist":
|
||||||
|
type = msg.message.message_segment.type
|
||||||
|
else:
|
||||||
|
if (isinstance(msg.message.message_segment.data, list)
|
||||||
|
and all(isinstance(x, Seg) for x in msg.message.message_segment.data)
|
||||||
|
and len(msg.message.message_segment.data) == 1):
|
||||||
|
type = msg.message.message_segment.data[0].type
|
||||||
combined_text.append(msg.message.processed_plain_text)
|
combined_text.append(msg.message.processed_plain_text)
|
||||||
continue
|
continue
|
||||||
if found:
|
if found:
|
||||||
keep_msgs[msg_id] = msg
|
keep_msgs[msg_id] = msg
|
||||||
elif msg.result == "F":
|
elif msg.result == "F":
|
||||||
# 收集F消息的文本内容
|
# 收集F消息的文本内容
|
||||||
|
F_type = "seglist"
|
||||||
|
if msg.message.message_segment.type != "seglist":
|
||||||
|
F_type = msg.message.message_segment.type
|
||||||
|
else:
|
||||||
|
if (isinstance(msg.message.message_segment.data, list)
|
||||||
|
and all(isinstance(x, Seg) for x in msg.message.message_segment.data)
|
||||||
|
and len(msg.message.message_segment.data) == 1):
|
||||||
|
F_type = msg.message.message_segment.data[0].type
|
||||||
if hasattr(msg.message, "processed_plain_text") and msg.message.processed_plain_text:
|
if hasattr(msg.message, "processed_plain_text") and msg.message.processed_plain_text:
|
||||||
if msg.message.message_segment.type == "text":
|
if F_type == "text":
|
||||||
combined_text.append(msg.message.processed_plain_text)
|
combined_text.append(msg.message.processed_plain_text)
|
||||||
elif msg.message.message_segment.type != "text":
|
elif F_type != "text":
|
||||||
is_update = False
|
is_update = False
|
||||||
elif msg.result == "U":
|
elif msg.result == "U":
|
||||||
logger.debug(f"异常未处理信息id: {msg.message.message_info.message_id}")
|
logger.debug(f"异常未处理信息id: {msg.message.message_info.message_id}")
|
||||||
|
|||||||
@@ -192,11 +192,19 @@ class ReasoningChat:
|
|||||||
if not buffer_result:
|
if not buffer_result:
|
||||||
await willing_manager.bombing_buffer_message_handle(message.message_info.message_id)
|
await willing_manager.bombing_buffer_message_handle(message.message_info.message_id)
|
||||||
willing_manager.delete(message.message_info.message_id)
|
willing_manager.delete(message.message_info.message_id)
|
||||||
if message.message_segment.type == "text":
|
F_type = "seglist"
|
||||||
|
if message.message_segment.type != "seglist":
|
||||||
|
F_type =message.message_segment.type
|
||||||
|
else:
|
||||||
|
if (isinstance(message.message_segment.data, list)
|
||||||
|
and all(isinstance(x, Seg) for x in message.message_segment.data)
|
||||||
|
and len(message.message_segment.data) == 1):
|
||||||
|
F_type = message.message_segment.data[0].type
|
||||||
|
if F_type == "text":
|
||||||
logger.info(f"触发缓冲,已炸飞消息:{message.processed_plain_text}")
|
logger.info(f"触发缓冲,已炸飞消息:{message.processed_plain_text}")
|
||||||
elif message.message_segment.type == "image":
|
elif F_type == "image":
|
||||||
logger.info("触发缓冲,已炸飞表情包/图片")
|
logger.info("触发缓冲,已炸飞表情包/图片")
|
||||||
elif message.message_segment.type == "seglist":
|
elif F_type == "seglist":
|
||||||
logger.info("触发缓冲,已炸飞消息列")
|
logger.info("触发缓冲,已炸飞消息列")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -204,11 +204,19 @@ class ThinkFlowChat:
|
|||||||
if not buffer_result:
|
if not buffer_result:
|
||||||
await willing_manager.bombing_buffer_message_handle(message.message_info.message_id)
|
await willing_manager.bombing_buffer_message_handle(message.message_info.message_id)
|
||||||
willing_manager.delete(message.message_info.message_id)
|
willing_manager.delete(message.message_info.message_id)
|
||||||
if message.message_segment.type == "text":
|
F_type = "seglist"
|
||||||
|
if message.message_segment.type != "seglist":
|
||||||
|
F_type =message.message_segment.type
|
||||||
|
else:
|
||||||
|
if (isinstance(message.message_segment.data, list)
|
||||||
|
and all(isinstance(x, Seg) for x in message.message_segment.data)
|
||||||
|
and len(message.message_segment.data) == 1):
|
||||||
|
F_type = message.message_segment.data[0].type
|
||||||
|
if F_type == "text":
|
||||||
logger.info(f"触发缓冲,已炸飞消息:{message.processed_plain_text}")
|
logger.info(f"触发缓冲,已炸飞消息:{message.processed_plain_text}")
|
||||||
elif message.message_segment.type == "image":
|
elif F_type == "image":
|
||||||
logger.info("触发缓冲,已炸飞表情包/图片")
|
logger.info("触发缓冲,已炸飞表情包/图片")
|
||||||
elif message.message_segment.type == "seglist":
|
elif F_type == "seglist":
|
||||||
logger.info("触发缓冲,已炸飞消息列")
|
logger.info("触发缓冲,已炸飞消息列")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -75,8 +75,3 @@ class ClassicalWillingManager(BaseWillingManager):
|
|||||||
async def not_reply_handle(self, message_id):
|
async def not_reply_handle(self, message_id):
|
||||||
return await super().not_reply_handle(message_id)
|
return await super().not_reply_handle(message_id)
|
||||||
|
|
||||||
async def get_variable_parameters(self):
|
|
||||||
return await super().get_variable_parameters()
|
|
||||||
|
|
||||||
async def set_variable_parameters(self, parameters):
|
|
||||||
return await super().set_variable_parameters(parameters)
|
|
||||||
|
|||||||
@@ -235,8 +235,3 @@ class DynamicWillingManager(BaseWillingManager):
|
|||||||
async def after_generate_reply_handle(self, message_id):
|
async def after_generate_reply_handle(self, message_id):
|
||||||
return await super().after_generate_reply_handle(message_id)
|
return await super().after_generate_reply_handle(message_id)
|
||||||
|
|
||||||
async def get_variable_parameters(self):
|
|
||||||
return await super().get_variable_parameters()
|
|
||||||
|
|
||||||
async def set_variable_parameters(self, parameters):
|
|
||||||
return await super().set_variable_parameters(parameters)
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ Mxp 模式:梦溪畔独家赞助
|
|||||||
4.限制同时思考的消息数量,防止喷射
|
4.限制同时思考的消息数量,防止喷射
|
||||||
5.拥有单聊增益,无论在群里还是私聊,只要bot一直和你聊,就会增加意愿值
|
5.拥有单聊增益,无论在群里还是私聊,只要bot一直和你聊,就会增加意愿值
|
||||||
6.意愿分为衰减意愿+临时意愿
|
6.意愿分为衰减意愿+临时意愿
|
||||||
|
7.疲劳机制
|
||||||
|
|
||||||
如果你发现本模式出现了bug
|
如果你发现本模式出现了bug
|
||||||
上上策是询问智慧的小草神()
|
上上策是询问智慧的小草神()
|
||||||
@@ -34,26 +35,47 @@ class MxpWillingManager(BaseWillingManager):
|
|||||||
self.chat_new_message_time: Dict[str, list[float]] = {} # 聊天流ID: 消息时间
|
self.chat_new_message_time: Dict[str, list[float]] = {} # 聊天流ID: 消息时间
|
||||||
self.last_response_person: Dict[str, tuple[str, int]] = {} # 上次回复的用户信息
|
self.last_response_person: Dict[str, tuple[str, int]] = {} # 上次回复的用户信息
|
||||||
self.temporary_willing: float = 0 # 临时意愿值
|
self.temporary_willing: float = 0 # 临时意愿值
|
||||||
|
self.chat_bot_message_time: Dict[str, list[float]] = {} # 聊天流ID: bot已回复消息时间
|
||||||
|
self.chat_fatigue_punishment_list: Dict[str, list[tuple[float, float]]] = {} # 聊天流疲劳惩罚列, 聊天流ID: 惩罚时间列(开始时间,持续时间)
|
||||||
|
self.chat_fatigue_willing_attenuation: Dict[str, float] = {} # 聊天流疲劳意愿衰减值
|
||||||
|
|
||||||
# 可变参数
|
# 可变参数
|
||||||
self.intention_decay_rate = 0.93 # 意愿衰减率
|
self.intention_decay_rate = 0.93 # 意愿衰减率
|
||||||
self.message_expiration_time = 120 # 消息过期时间(秒)
|
|
||||||
self.number_of_message_storage = 10 # 消息存储数量
|
self.number_of_message_storage = 12 # 消息存储数量
|
||||||
|
self.expected_replies_per_min = 3 # 每分钟预期回复数
|
||||||
self.basic_maximum_willing = 0.5 # 基础最大意愿值
|
self.basic_maximum_willing = 0.5 # 基础最大意愿值
|
||||||
|
|
||||||
self.mention_willing_gain = 0.6 # 提及意愿增益
|
self.mention_willing_gain = 0.6 # 提及意愿增益
|
||||||
self.interest_willing_gain = 0.3 # 兴趣意愿增益
|
self.interest_willing_gain = 0.3 # 兴趣意愿增益
|
||||||
self.emoji_response_penalty = self.global_config.emoji_response_penalty # 表情包回复惩罚
|
self.emoji_response_penalty = self.global_config.emoji_response_penalty # 表情包回复惩罚
|
||||||
self.down_frequency_rate = self.global_config.down_frequency_rate # 降低回复频率的群组惩罚系数
|
self.down_frequency_rate = self.global_config.down_frequency_rate # 降低回复频率的群组惩罚系数
|
||||||
self.single_chat_gain = 0.12 # 单聊增益
|
self.single_chat_gain = 0.12 # 单聊增益
|
||||||
|
|
||||||
|
self.fatigue_messages_triggered_num = self.expected_replies_per_min # 疲劳消息触发数量(int)
|
||||||
|
self.fatigue_coefficient = 1.0 # 疲劳系数
|
||||||
|
|
||||||
|
self.is_debug = False # 是否开启调试模式
|
||||||
|
|
||||||
async def async_task_starter(self) -> None:
|
async def async_task_starter(self) -> None:
|
||||||
"""异步任务启动器"""
|
"""异步任务启动器"""
|
||||||
asyncio.create_task(self._return_to_basic_willing())
|
asyncio.create_task(self._return_to_basic_willing())
|
||||||
asyncio.create_task(self._chat_new_message_to_change_basic_willing())
|
asyncio.create_task(self._chat_new_message_to_change_basic_willing())
|
||||||
|
asyncio.create_task(self._fatigue_attenuation())
|
||||||
|
|
||||||
async def before_generate_reply_handle(self, message_id: str):
|
async def before_generate_reply_handle(self, message_id: str):
|
||||||
"""回复前处理"""
|
"""回复前处理"""
|
||||||
pass
|
current_time = time.time()
|
||||||
|
async with self.lock:
|
||||||
|
w_info = self.ongoing_messages[message_id]
|
||||||
|
if w_info.chat_id not in self.chat_bot_message_time:
|
||||||
|
self.chat_bot_message_time[w_info.chat_id] = []
|
||||||
|
self.chat_bot_message_time[w_info.chat_id] = \
|
||||||
|
[t for t in self.chat_bot_message_time[w_info.chat_id] if current_time - t < 60]
|
||||||
|
self.chat_bot_message_time[w_info.chat_id].append(current_time)
|
||||||
|
if len(self.chat_bot_message_time[w_info.chat_id]) == int(self.fatigue_messages_triggered_num):
|
||||||
|
time_interval = 60 - (current_time - self.chat_bot_message_time[w_info.chat_id].pop(0))
|
||||||
|
self.chat_fatigue_punishment_list[w_info.chat_id].append([current_time, time_interval * 2])
|
||||||
|
|
||||||
async def after_generate_reply_handle(self, message_id: str):
|
async def after_generate_reply_handle(self, message_id: str):
|
||||||
"""回复后处理"""
|
"""回复后处理"""
|
||||||
@@ -63,9 +85,9 @@ class MxpWillingManager(BaseWillingManager):
|
|||||||
rel_level = self._get_relationship_level_num(rel_value)
|
rel_level = self._get_relationship_level_num(rel_value)
|
||||||
self.chat_person_reply_willing[w_info.chat_id][w_info.person_id] += rel_level * 0.05
|
self.chat_person_reply_willing[w_info.chat_id][w_info.person_id] += rel_level * 0.05
|
||||||
|
|
||||||
now_chat_new_person = self.last_response_person.get(w_info.chat_id, ["", 0])
|
now_chat_new_person = self.last_response_person.get(w_info.chat_id, [w_info.person_id, 0])
|
||||||
if now_chat_new_person[0] == w_info.person_id:
|
if now_chat_new_person[0] == w_info.person_id:
|
||||||
if now_chat_new_person[1] < 2:
|
if now_chat_new_person[1] < 3:
|
||||||
now_chat_new_person[1] += 1
|
now_chat_new_person[1] += 1
|
||||||
else:
|
else:
|
||||||
self.last_response_person[w_info.chat_id] = [w_info.person_id, 0]
|
self.last_response_person[w_info.chat_id] = [w_info.person_id, 0]
|
||||||
@@ -75,13 +97,14 @@ class MxpWillingManager(BaseWillingManager):
|
|||||||
async with self.lock:
|
async with self.lock:
|
||||||
w_info = self.ongoing_messages[message_id]
|
w_info = self.ongoing_messages[message_id]
|
||||||
if w_info.is_mentioned_bot:
|
if w_info.is_mentioned_bot:
|
||||||
self.chat_person_reply_willing[w_info.chat_id][w_info.person_id] += 0.2
|
self.chat_person_reply_willing[w_info.chat_id][w_info.person_id] += self.mention_willing_gain / 2.5
|
||||||
if (
|
if (
|
||||||
w_info.chat_id in self.last_response_person
|
w_info.chat_id in self.last_response_person
|
||||||
and self.last_response_person[w_info.chat_id][0] == w_info.person_id
|
and self.last_response_person[w_info.chat_id][0] == w_info.person_id
|
||||||
|
and self.last_response_person[w_info.chat_id][1]
|
||||||
):
|
):
|
||||||
self.chat_person_reply_willing[w_info.chat_id][w_info.person_id] += self.single_chat_gain * (
|
self.chat_person_reply_willing[w_info.chat_id][w_info.person_id] += self.single_chat_gain * (
|
||||||
2 * self.last_response_person[w_info.chat_id][1] + 1
|
2 * self.last_response_person[w_info.chat_id][1] - 1
|
||||||
)
|
)
|
||||||
now_chat_new_person = self.last_response_person.get(w_info.chat_id, ["", 0])
|
now_chat_new_person = self.last_response_person.get(w_info.chat_id, ["", 0])
|
||||||
if now_chat_new_person[0] != w_info.person_id:
|
if now_chat_new_person[0] != w_info.person_id:
|
||||||
@@ -92,35 +115,60 @@ class MxpWillingManager(BaseWillingManager):
|
|||||||
async with self.lock:
|
async with self.lock:
|
||||||
w_info = self.ongoing_messages[message_id]
|
w_info = self.ongoing_messages[message_id]
|
||||||
current_willing = self.chat_person_reply_willing[w_info.chat_id][w_info.person_id]
|
current_willing = self.chat_person_reply_willing[w_info.chat_id][w_info.person_id]
|
||||||
|
if self.is_debug:
|
||||||
|
self.logger.debug(f"基础意愿值:{current_willing}")
|
||||||
|
|
||||||
if w_info.is_mentioned_bot:
|
if w_info.is_mentioned_bot:
|
||||||
current_willing += self.mention_willing_gain / (int(current_willing) + 1)
|
current_willing_ = self.mention_willing_gain / (int(current_willing) + 1)
|
||||||
|
current_willing += current_willing_
|
||||||
|
if self.is_debug:
|
||||||
|
self.logger.debug(f"提及增益:{current_willing_}")
|
||||||
|
|
||||||
if w_info.interested_rate > 0:
|
if w_info.interested_rate > 0:
|
||||||
current_willing += math.atan(w_info.interested_rate / 2) / math.pi * 2 * self.interest_willing_gain
|
current_willing += math.atan(w_info.interested_rate / 2) / math.pi * 2 * self.interest_willing_gain
|
||||||
|
if self.is_debug:
|
||||||
|
self.logger.debug(f"兴趣增益:{math.atan(w_info.interested_rate / 2) / math.pi * 2 * self.interest_willing_gain}")
|
||||||
|
|
||||||
self.chat_person_reply_willing[w_info.chat_id][w_info.person_id] = current_willing
|
self.chat_person_reply_willing[w_info.chat_id][w_info.person_id] = current_willing
|
||||||
|
|
||||||
rel_value = await w_info.person_info_manager.get_value(w_info.person_id, "relationship_value")
|
rel_value = await w_info.person_info_manager.get_value(w_info.person_id, "relationship_value")
|
||||||
rel_level = self._get_relationship_level_num(rel_value)
|
rel_level = self._get_relationship_level_num(rel_value)
|
||||||
current_willing += rel_level * 0.1
|
current_willing += rel_level * 0.1
|
||||||
|
if self.is_debug and rel_level != 0:
|
||||||
|
self.logger.debug(f"关系增益:{rel_level * 0.1}")
|
||||||
|
|
||||||
if (
|
if (
|
||||||
w_info.chat_id in self.last_response_person
|
w_info.chat_id in self.last_response_person
|
||||||
and self.last_response_person[w_info.chat_id][0] == w_info.person_id
|
and self.last_response_person[w_info.chat_id][0] == w_info.person_id
|
||||||
|
and self.last_response_person[w_info.chat_id][1]
|
||||||
):
|
):
|
||||||
current_willing += self.single_chat_gain * (2 * self.last_response_person[w_info.chat_id][1] + 1)
|
current_willing += self.single_chat_gain * (2 * self.last_response_person[w_info.chat_id][1] + 1)
|
||||||
|
if self.is_debug:
|
||||||
|
self.logger.debug(f"单聊增益:{self.single_chat_gain * (2 * self.last_response_person[w_info.chat_id][1] - 1)}")
|
||||||
|
|
||||||
|
current_willing += self.chat_fatigue_willing_attenuation.get(w_info.chat_id, 0)
|
||||||
|
if self.is_debug:
|
||||||
|
self.logger.debug(f"疲劳衰减:{self.chat_fatigue_willing_attenuation.get(w_info.chat_id, 0)}")
|
||||||
|
|
||||||
chat_ongoing_messages = [msg for msg in self.ongoing_messages.values() if msg.chat_id == w_info.chat_id]
|
chat_ongoing_messages = [msg for msg in self.ongoing_messages.values() if msg.chat_id == w_info.chat_id]
|
||||||
chat_person_ogoing_messages = [msg for msg in chat_ongoing_messages if msg.person_id == w_info.person_id]
|
chat_person_ogoing_messages = [msg for msg in chat_ongoing_messages if msg.person_id == w_info.person_id]
|
||||||
if len(chat_person_ogoing_messages) >= 2:
|
if len(chat_person_ogoing_messages) >= 2:
|
||||||
current_willing = 0
|
current_willing = 0
|
||||||
|
if self.is_debug:
|
||||||
|
self.logger.debug("进行中消息惩罚:归0")
|
||||||
elif len(chat_ongoing_messages) == 2:
|
elif len(chat_ongoing_messages) == 2:
|
||||||
current_willing -= 0.5
|
current_willing -= 0.5
|
||||||
|
if self.is_debug:
|
||||||
|
self.logger.debug("进行中消息惩罚:-0.5")
|
||||||
elif len(chat_ongoing_messages) == 3:
|
elif len(chat_ongoing_messages) == 3:
|
||||||
current_willing -= 1.5
|
current_willing -= 1.5
|
||||||
|
if self.is_debug:
|
||||||
|
self.logger.debug("进行中消息惩罚:-1.5")
|
||||||
elif len(chat_ongoing_messages) >= 4:
|
elif len(chat_ongoing_messages) >= 4:
|
||||||
current_willing = 0
|
current_willing = 0
|
||||||
|
if self.is_debug:
|
||||||
|
self.logger.debug("进行中消息惩罚:归0")
|
||||||
|
|
||||||
|
|
||||||
probability = self._willing_to_probability(current_willing)
|
probability = self._willing_to_probability(current_willing)
|
||||||
|
|
||||||
@@ -168,32 +216,44 @@ class MxpWillingManager(BaseWillingManager):
|
|||||||
self.ongoing_messages[message.message_info.message_id].person_id, self.chat_reply_willing[chat.stream_id]
|
self.ongoing_messages[message.message_info.message_id].person_id, self.chat_reply_willing[chat.stream_id]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
current_time = time.time()
|
||||||
if chat.stream_id not in self.chat_new_message_time:
|
if chat.stream_id not in self.chat_new_message_time:
|
||||||
self.chat_new_message_time[chat.stream_id] = []
|
self.chat_new_message_time[chat.stream_id] = []
|
||||||
self.chat_new_message_time[chat.stream_id].append(time.time())
|
self.chat_new_message_time[chat.stream_id].append(current_time)
|
||||||
if len(self.chat_new_message_time[chat.stream_id]) > self.number_of_message_storage:
|
if len(self.chat_new_message_time[chat.stream_id]) > self.number_of_message_storage:
|
||||||
self.chat_new_message_time[chat.stream_id].pop(0)
|
self.chat_new_message_time[chat.stream_id].pop(0)
|
||||||
|
|
||||||
|
if chat.stream_id not in self.chat_fatigue_punishment_list:
|
||||||
|
self.chat_fatigue_punishment_list[chat.stream_id] = [
|
||||||
|
(current_time, self.number_of_message_storage * self.basic_maximum_willing / self.expected_replies_per_min * 60)
|
||||||
|
]
|
||||||
|
self.chat_fatigue_willing_attenuation[chat.stream_id] = - 2 * self.basic_maximum_willing * self.fatigue_coefficient
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _willing_to_probability(self, willing: float) -> float:
|
def _willing_to_probability(self, willing: float) -> float:
|
||||||
"""意愿值转化为概率"""
|
"""意愿值转化为概率"""
|
||||||
willing = max(0, willing)
|
willing = max(0, willing)
|
||||||
if willing < 2:
|
if willing < 2:
|
||||||
probability = math.atan(willing * 2) / math.pi * 2
|
probability = math.atan(willing * 2) / math.pi * 2
|
||||||
else:
|
elif willing <2.5:
|
||||||
probability = math.atan(willing * 4) / math.pi * 2
|
probability = math.atan(willing * 4) / math.pi * 2
|
||||||
|
else:
|
||||||
|
probability = 1
|
||||||
return probability
|
return probability
|
||||||
|
|
||||||
async def _chat_new_message_to_change_basic_willing(self):
|
async def _chat_new_message_to_change_basic_willing(self):
|
||||||
"""聊天流新消息改变基础意愿"""
|
"""聊天流新消息改变基础意愿"""
|
||||||
|
update_time = 20
|
||||||
while True:
|
while True:
|
||||||
update_time = 20
|
|
||||||
await asyncio.sleep(update_time)
|
await asyncio.sleep(update_time)
|
||||||
async with self.lock:
|
async with self.lock:
|
||||||
for chat_id, message_times in self.chat_new_message_time.items():
|
for chat_id, message_times in self.chat_new_message_time.items():
|
||||||
# 清理过期消息
|
# 清理过期消息
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
message_times = [
|
message_times = [
|
||||||
msg_time for msg_time in message_times if current_time - msg_time < self.message_expiration_time
|
msg_time for msg_time in message_times if current_time - msg_time <
|
||||||
|
self.number_of_message_storage * self.basic_maximum_willing / self.expected_replies_per_min * 60
|
||||||
]
|
]
|
||||||
self.chat_new_message_time[chat_id] = message_times
|
self.chat_new_message_time[chat_id] = message_times
|
||||||
|
|
||||||
@@ -202,38 +262,15 @@ class MxpWillingManager(BaseWillingManager):
|
|||||||
update_time = 20
|
update_time = 20
|
||||||
elif len(message_times) == self.number_of_message_storage:
|
elif len(message_times) == self.number_of_message_storage:
|
||||||
time_interval = current_time - message_times[0]
|
time_interval = current_time - message_times[0]
|
||||||
basic_willing = self.basic_maximum_willing * math.sqrt(
|
basic_willing = self._basic_willing_culculate(time_interval)
|
||||||
time_interval / self.message_expiration_time
|
|
||||||
)
|
|
||||||
self.chat_reply_willing[chat_id] = basic_willing
|
self.chat_reply_willing[chat_id] = basic_willing
|
||||||
update_time = 17 * math.sqrt(time_interval / self.message_expiration_time) + 3
|
update_time = 17 * basic_willing / self.basic_maximum_willing + 3
|
||||||
else:
|
else:
|
||||||
self.logger.debug(f"聊天流{chat_id}消息时间数量异常,数量:{len(message_times)}")
|
self.logger.debug(f"聊天流{chat_id}消息时间数量异常,数量:{len(message_times)}")
|
||||||
self.chat_reply_willing[chat_id] = 0
|
self.chat_reply_willing[chat_id] = 0
|
||||||
|
if self.is_debug:
|
||||||
|
self.logger.debug(f"聊天流意愿值更新:{self.chat_reply_willing}")
|
||||||
|
|
||||||
async def get_variable_parameters(self) -> Dict[str, str]:
|
|
||||||
"""获取可变参数"""
|
|
||||||
return {
|
|
||||||
"intention_decay_rate": "意愿衰减率",
|
|
||||||
"message_expiration_time": "消息过期时间(秒)",
|
|
||||||
"number_of_message_storage": "消息存储数量",
|
|
||||||
"basic_maximum_willing": "基础最大意愿值",
|
|
||||||
"mention_willing_gain": "提及意愿增益",
|
|
||||||
"interest_willing_gain": "兴趣意愿增益",
|
|
||||||
"emoji_response_penalty": "表情包回复惩罚",
|
|
||||||
"down_frequency_rate": "降低回复频率的群组惩罚系数",
|
|
||||||
"single_chat_gain": "单聊增益(不仅是私聊)",
|
|
||||||
}
|
|
||||||
|
|
||||||
async def set_variable_parameters(self, parameters: Dict[str, any]):
|
|
||||||
"""设置可变参数"""
|
|
||||||
async with self.lock:
|
|
||||||
for key, value in parameters.items():
|
|
||||||
if hasattr(self, key):
|
|
||||||
setattr(self, key, value)
|
|
||||||
self.logger.debug(f"参数 {key} 已更新为 {value}")
|
|
||||||
else:
|
|
||||||
self.logger.debug(f"尝试设置未知参数 {key}")
|
|
||||||
|
|
||||||
def _get_relationship_level_num(self, relationship_value) -> int:
|
def _get_relationship_level_num(self, relationship_value) -> int:
|
||||||
"""关系等级计算"""
|
"""关系等级计算"""
|
||||||
@@ -253,5 +290,25 @@ class MxpWillingManager(BaseWillingManager):
|
|||||||
level_num = 5 if relationship_value > 1000 else 0
|
level_num = 5 if relationship_value > 1000 else 0
|
||||||
return level_num - 2
|
return level_num - 2
|
||||||
|
|
||||||
|
def _basic_willing_culculate(self, t: float) -> float:
|
||||||
|
"""基础意愿值计算"""
|
||||||
|
return math.tan(t * self.expected_replies_per_min * math.pi
|
||||||
|
/ 120 / self.number_of_message_storage) / 2
|
||||||
|
|
||||||
|
async def _fatigue_attenuation(self):
|
||||||
|
"""疲劳衰减"""
|
||||||
|
while True:
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
current_time = time.time()
|
||||||
|
async with self.lock:
|
||||||
|
for chat_id, fatigue_list in self.chat_fatigue_punishment_list.items():
|
||||||
|
fatigue_list = [z for z in fatigue_list if current_time - z[0] < z[1]]
|
||||||
|
self.chat_fatigue_willing_attenuation[chat_id] = 0
|
||||||
|
for start_time, duration in fatigue_list:
|
||||||
|
self.chat_fatigue_willing_attenuation[chat_id] += \
|
||||||
|
(self.chat_reply_willing[chat_id] * 2 / math.pi * math.asin(
|
||||||
|
2 * (current_time - start_time) / duration - 1
|
||||||
|
) - self.chat_reply_willing[chat_id]) * self.fatigue_coefficient
|
||||||
|
|
||||||
async def get_willing(self, chat_id):
|
async def get_willing(self, chat_id):
|
||||||
return self.temporary_willing
|
return self.temporary_willing
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ after_generate_reply_handle 确定要回复后,在生成回复后的处理
|
|||||||
not_reply_handle 确定不回复后的处理
|
not_reply_handle 确定不回复后的处理
|
||||||
get_reply_probability 获取回复概率
|
get_reply_probability 获取回复概率
|
||||||
bombing_buffer_message_handle 缓冲器炸飞消息后的处理
|
bombing_buffer_message_handle 缓冲器炸飞消息后的处理
|
||||||
get_variable_parameters 获取可变参数组,返回一个字典,key为参数名称,value为参数描述(此方法是为拆分全局设置准备)
|
get_variable_parameters 暂不确定
|
||||||
set_variable_parameters 设置可变参数组,你需要传入一个字典,key为参数名称,value为参数值(此方法是为拆分全局设置准备)
|
set_variable_parameters 暂不确定
|
||||||
以下2个方法根据你的实现可以做调整:
|
以下2个方法根据你的实现可以做调整:
|
||||||
get_willing 获取某聊天流意愿
|
get_willing 获取某聊天流意愿
|
||||||
set_willing 设置某聊天流意愿
|
set_willing 设置某聊天流意愿
|
||||||
@@ -152,15 +152,15 @@ class BaseWillingManager(ABC):
|
|||||||
async with self.lock:
|
async with self.lock:
|
||||||
self.chat_reply_willing[chat_id] = willing
|
self.chat_reply_willing[chat_id] = willing
|
||||||
|
|
||||||
@abstractmethod
|
# @abstractmethod
|
||||||
async def get_variable_parameters(self) -> Dict[str, str]:
|
# async def get_variable_parameters(self) -> Dict[str, str]:
|
||||||
"""抽象方法:获取可变参数"""
|
# """抽象方法:获取可变参数"""
|
||||||
pass
|
# pass
|
||||||
|
|
||||||
@abstractmethod
|
# @abstractmethod
|
||||||
async def set_variable_parameters(self, parameters: Dict[str, any]):
|
# async def set_variable_parameters(self, parameters: Dict[str, any]):
|
||||||
"""抽象方法:设置可变参数"""
|
# """抽象方法:设置可变参数"""
|
||||||
pass
|
# pass
|
||||||
|
|
||||||
|
|
||||||
def init_willing_manager() -> BaseWillingManager:
|
def init_willing_manager() -> BaseWillingManager:
|
||||||
|
|||||||
Reference in New Issue
Block a user