迁移:69a855d(feat:保存关键词到message数据库)
This commit is contained in:
@@ -159,19 +159,12 @@ class CycleProcessor:
|
|||||||
self.context.last_action = action_type
|
self.context.last_action = action_type
|
||||||
|
|
||||||
# 处理no_reply相关的逻辑
|
# 处理no_reply相关的逻辑
|
||||||
if action_type != "no_reply" and action_type != "no_action":
|
if action_type != "no_reply":
|
||||||
# 导入NoReplyAction并重置计数器
|
|
||||||
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
|
||||||
NoReplyAction.reset_consecutive_count()
|
|
||||||
self.context.no_reply_consecutive = 0
|
self.context.no_reply_consecutive = 0
|
||||||
logger.info(f"{self.context.log_prefix} 执行了{action_type}动作,重置no_reply计数器")
|
if hasattr(self.context, 'chat_instance') and self.context.chat_instance:
|
||||||
elif action_type == "no_action":
|
self.context.chat_instance.recent_interest_records.clear()
|
||||||
# 当执行回复动作时,也重置no_reply计数
|
logger.info(f"{self.context.log_prefix} 执行了{action_type}动作,重置no_reply计数器和兴趣度记录")
|
||||||
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
|
||||||
NoReplyAction.reset_consecutive_count()
|
|
||||||
self.context.no_reply_consecutive = 0
|
|
||||||
logger.info(f"{self.context.log_prefix} 执行了回复动作,重置no_reply计数器")
|
|
||||||
|
|
||||||
if action_type == "no_reply":
|
if action_type == "no_reply":
|
||||||
self.context.no_reply_consecutive += 1
|
self.context.no_reply_consecutive += 1
|
||||||
# 调用HeartFChatting中的_determine_form_type方法
|
# 调用HeartFChatting中的_determine_form_type方法
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import time
|
|||||||
import traceback
|
import traceback
|
||||||
import random
|
import random
|
||||||
from typing import Optional, List, Dict, Any, Tuple
|
from typing import Optional, List, Dict, Any, Tuple
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
@@ -55,6 +56,9 @@ class HeartFChatting:
|
|||||||
self.context.chat_instance = self
|
self.context.chat_instance = self
|
||||||
|
|
||||||
self._loop_task: Optional[asyncio.Task] = None
|
self._loop_task: Optional[asyncio.Task] = None
|
||||||
|
|
||||||
|
# 记录最近3次的兴趣度
|
||||||
|
self.recent_interest_records: deque = deque(maxlen=3)
|
||||||
|
|
||||||
self._initialize_chat_mode()
|
self._initialize_chat_mode()
|
||||||
logger.info(f"{self.context.log_prefix} HeartFChatting 初始化完成")
|
logger.info(f"{self.context.log_prefix} HeartFChatting 初始化完成")
|
||||||
@@ -242,23 +246,20 @@ class HeartFChatting:
|
|||||||
logger.info(f"{self.context.log_prefix} 从睡眠中被唤醒,将处理积压的消息。")
|
logger.info(f"{self.context.log_prefix} 从睡眠中被唤醒,将处理积压的消息。")
|
||||||
|
|
||||||
# 根据聊天模式处理新消息
|
# 根据聊天模式处理新消息
|
||||||
if self.context.loop_mode == ChatMode.FOCUS:
|
# 统一使用 _should_process_messages 判断是否应该处理
|
||||||
# 如果上一个动作是no_reply,则执行no_reply逻辑
|
if not self._should_process_messages(recent_messages if has_new_messages else None):
|
||||||
if self.context.last_action == "no_reply":
|
return has_new_messages
|
||||||
if not await self._execute_no_reply(recent_messages):
|
|
||||||
self.context.energy_value -= 0.3 / global_config.chat.focus_value
|
|
||||||
logger.info(f"{self.context.log_prefix} 能量值减少,当前能量值:{self.context.energy_value:.1f}")
|
|
||||||
return has_new_messages
|
|
||||||
|
|
||||||
|
if self.context.loop_mode == ChatMode.FOCUS:
|
||||||
# 处理新消息
|
# 处理新消息
|
||||||
for message in recent_messages:
|
for message in recent_messages:
|
||||||
await self.cycle_processor.observe(message)
|
await self.cycle_processor.observe(message)
|
||||||
|
|
||||||
# 如果成功观察,增加能量值
|
# 如果成功观察,增加能量值
|
||||||
if has_new_messages:
|
if has_new_messages:
|
||||||
self.context.energy_value += 1 / global_config.chat.focus_value
|
self.context.energy_value += 1 / global_config.chat.focus_value
|
||||||
logger.info(f"{self.context.log_prefix} 能量值增加,当前能量值:{self.context.energy_value:.1f}")
|
logger.info(f"{self.context.log_prefix} 能量值增加,当前能量值:{self.context.energy_value:.1f}")
|
||||||
|
|
||||||
self._check_focus_exit()
|
self._check_focus_exit()
|
||||||
elif self.context.loop_mode == ChatMode.NORMAL:
|
elif self.context.loop_mode == ChatMode.NORMAL:
|
||||||
self._check_focus_entry(len(recent_messages))
|
self._check_focus_entry(len(recent_messages))
|
||||||
@@ -399,9 +400,8 @@ class HeartFChatting:
|
|||||||
self.context.focus_energy = 1
|
self.context.focus_energy = 1
|
||||||
else:
|
else:
|
||||||
# 计算最近三次记录的兴趣度总和
|
# 计算最近三次记录的兴趣度总和
|
||||||
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
total_recent_interest = sum(self.recent_interest_records)
|
||||||
total_recent_interest = sum(NoReplyAction._recent_interest_records)
|
|
||||||
|
|
||||||
# 获取当前聊天频率和意愿系数
|
# 获取当前聊天频率和意愿系数
|
||||||
talk_frequency = global_config.chat.get_current_talk_frequency(self.context.stream_id)
|
talk_frequency = global_config.chat.get_current_talk_frequency(self.context.stream_id)
|
||||||
|
|
||||||
@@ -417,6 +417,22 @@ class HeartFChatting:
|
|||||||
else:
|
else:
|
||||||
logger.info(f"{self.context.log_prefix} 兴趣度充足")
|
logger.info(f"{self.context.log_prefix} 兴趣度充足")
|
||||||
self.context.focus_energy = 1
|
self.context.focus_energy = 1
|
||||||
|
|
||||||
|
def _should_process_messages(self, messages: List[Dict[str, Any]] = None) -> bool:
|
||||||
|
"""
|
||||||
|
统一判断是否应该处理消息的函数
|
||||||
|
根据当前循环模式和消息内容决定是否继续处理
|
||||||
|
"""
|
||||||
|
from src.chat.utils.utils_image import is_image_message
|
||||||
|
|
||||||
|
if self.context.loop_mode == ChatMode.FOCUS:
|
||||||
|
if self.context.last_action == "no_reply":
|
||||||
|
if messages:
|
||||||
|
return self._execute_no_reply(messages)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
async def _execute_no_reply(self, new_message: List[Dict[str, Any]]) -> bool:
|
async def _execute_no_reply(self, new_message: List[Dict[str, Any]]) -> bool:
|
||||||
"""执行breaking形式的no_reply(原有逻辑)"""
|
"""执行breaking形式的no_reply(原有逻辑)"""
|
||||||
@@ -427,14 +443,13 @@ class HeartFChatting:
|
|||||||
|
|
||||||
if new_message_count >= modified_exit_count_threshold:
|
if new_message_count >= modified_exit_count_threshold:
|
||||||
# 记录兴趣度到列表
|
# 记录兴趣度到列表
|
||||||
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
|
||||||
total_interest = 0.0
|
total_interest = 0.0
|
||||||
for msg_dict in new_message:
|
for msg_dict in new_message:
|
||||||
interest_value = msg_dict.get("interest_value", 0.0)
|
interest_value = msg_dict.get("interest_value", 0.0)
|
||||||
if msg_dict.get("processed_plain_text", ""):
|
if msg_dict.get("processed_plain_text", ""):
|
||||||
total_interest += interest_value
|
total_interest += interest_value
|
||||||
|
|
||||||
NoReplyAction._recent_interest_records.append(total_interest)
|
self.recent_interest_records.append(total_interest)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"{self.context.log_prefix} 累计消息数量达到{new_message_count}条(>{modified_exit_count_threshold}),结束等待"
|
f"{self.context.log_prefix} 累计消息数量达到{new_message_count}条(>{modified_exit_count_threshold}),结束等待"
|
||||||
@@ -458,11 +473,10 @@ class HeartFChatting:
|
|||||||
|
|
||||||
if accumulated_interest >= 3 / talk_frequency:
|
if accumulated_interest >= 3 / talk_frequency:
|
||||||
# 记录兴趣度到列表
|
# 记录兴趣度到列表
|
||||||
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
self.recent_interest_records.append(accumulated_interest)
|
||||||
NoReplyAction._recent_interest_records.append(accumulated_interest)
|
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"{self.context.log_prefix} 累计兴趣值达到{accumulated_interest:.2f}(>{5 / talk_frequency}),结束等待"
|
f"{self.context.log_prefix} 累计兴趣值达到{accumulated_interest:.2f}(>{3 / talk_frequency}),结束等待"
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ async def _calculate_interest(message: MessageRecv) -> Tuple[float, bool, list[s
|
|||||||
with Timer("记忆激活"):
|
with Timer("记忆激活"):
|
||||||
interested_rate, keywords = await hippocampus_manager.get_activate_from_text(
|
interested_rate, keywords = await hippocampus_manager.get_activate_from_text(
|
||||||
message.processed_plain_text,
|
message.processed_plain_text,
|
||||||
max_depth=5,
|
max_depth=4,
|
||||||
fast_retrieval=False,
|
fast_retrieval=False,
|
||||||
)
|
)
|
||||||
message.key_words = keywords
|
message.key_words = keywords
|
||||||
|
|||||||
@@ -120,6 +120,9 @@ class MessageRecv(Message):
|
|||||||
self.priority_mode = "interest"
|
self.priority_mode = "interest"
|
||||||
self.priority_info = None
|
self.priority_info = None
|
||||||
self.interest_value: float = 0.0
|
self.interest_value: float = 0.0
|
||||||
|
|
||||||
|
self.key_words = []
|
||||||
|
self.key_words_lite = []
|
||||||
|
|
||||||
def update_chat_stream(self, chat_stream: "ChatStream"):
|
def update_chat_stream(self, chat_stream: "ChatStream"):
|
||||||
self.chat_stream = chat_stream
|
self.chat_stream = chat_stream
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class MessageStorage:
|
|||||||
def _serialize_keywords(keywords) -> str:
|
def _serialize_keywords(keywords) -> str:
|
||||||
"""将关键词列表序列化为JSON字符串"""
|
"""将关键词列表序列化为JSON字符串"""
|
||||||
if isinstance(keywords, list):
|
if isinstance(keywords, list):
|
||||||
return json.dumps(keywords, ensure_ascii=False)
|
return orjson.dumps(keywords).decode("utf-8")
|
||||||
return "[]"
|
return "[]"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -28,8 +28,8 @@ class MessageStorage:
|
|||||||
if not keywords_str:
|
if not keywords_str:
|
||||||
return []
|
return []
|
||||||
try:
|
try:
|
||||||
return json.loads(keywords_str)
|
return orjson.loads(keywords_str)
|
||||||
except (json.JSONDecodeError, TypeError):
|
except (orjson.JSONDecodeError, TypeError):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -64,7 +64,6 @@ class MessageStorage:
|
|||||||
is_command = False
|
is_command = False
|
||||||
key_words = ""
|
key_words = ""
|
||||||
key_words_lite = ""
|
key_words_lite = ""
|
||||||
selected_expressions = message.selected_expressions
|
|
||||||
else:
|
else:
|
||||||
filtered_display_message = ""
|
filtered_display_message = ""
|
||||||
interest_value = message.interest_value
|
interest_value = message.interest_value
|
||||||
@@ -79,8 +78,7 @@ class MessageStorage:
|
|||||||
# 序列化关键词列表为JSON字符串
|
# 序列化关键词列表为JSON字符串
|
||||||
key_words = MessageStorage._serialize_keywords(message.key_words)
|
key_words = MessageStorage._serialize_keywords(message.key_words)
|
||||||
key_words_lite = MessageStorage._serialize_keywords(message.key_words_lite)
|
key_words_lite = MessageStorage._serialize_keywords(message.key_words_lite)
|
||||||
selected_expressions = ""
|
|
||||||
|
|
||||||
chat_info_dict = chat_stream.to_dict()
|
chat_info_dict = chat_stream.to_dict()
|
||||||
user_info_dict = message.message_info.user_info.to_dict() # type: ignore
|
user_info_dict = message.message_info.user_info.to_dict() # type: ignore
|
||||||
|
|
||||||
@@ -130,7 +128,6 @@ class MessageStorage:
|
|||||||
is_command=is_command,
|
is_command=is_command,
|
||||||
key_words=key_words,
|
key_words=key_words,
|
||||||
key_words_lite=key_words_lite,
|
key_words_lite=key_words_lite,
|
||||||
selected_expressions=selected_expressions,
|
|
||||||
)
|
)
|
||||||
with get_db_session() as session:
|
with get_db_session() as session:
|
||||||
session.add(new_message)
|
session.add(new_message)
|
||||||
|
|||||||
@@ -128,6 +128,8 @@ class Messages(Base):
|
|||||||
chat_id = Column(get_string_field(64), nullable=False, index=True)
|
chat_id = Column(get_string_field(64), nullable=False, index=True)
|
||||||
reply_to = Column(Text, nullable=True)
|
reply_to = Column(Text, nullable=True)
|
||||||
interest_value = Column(Float, nullable=True)
|
interest_value = Column(Float, nullable=True)
|
||||||
|
key_words = Column(Text, nullable=True)
|
||||||
|
key_words_lite = Column(Text, nullable=True)
|
||||||
is_mentioned = Column(Boolean, nullable=True)
|
is_mentioned = Column(Boolean, nullable=True)
|
||||||
|
|
||||||
# 从 chat_info 扁平化而来的字段
|
# 从 chat_info 扁平化而来的字段
|
||||||
|
|||||||
@@ -114,11 +114,7 @@ class ChatConfig(ValidatedConfigBase):
|
|||||||
|
|
||||||
# 检查全局时段配置(第一个元素为空字符串的配置)
|
# 检查全局时段配置(第一个元素为空字符串的配置)
|
||||||
global_frequency = self._get_global_frequency()
|
global_frequency = self._get_global_frequency()
|
||||||
if global_frequency is not None:
|
return self.talk_frequency if global_frequency is None else global_frequency
|
||||||
return global_frequency
|
|
||||||
|
|
||||||
# 如果都没有匹配,返回默认值
|
|
||||||
return self.talk_frequency
|
|
||||||
|
|
||||||
def _get_time_based_frequency(self, time_freq_list: list[str]) -> Optional[float]:
|
def _get_time_based_frequency(self, time_freq_list: list[str]) -> Optional[float]:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
from typing import Tuple, List
|
from typing import Tuple
|
||||||
from collections import deque
|
|
||||||
|
|
||||||
# 导入新插件系统
|
# 导入新插件系统
|
||||||
from src.plugin_system import BaseAction, ActionActivationType, ChatMode
|
from src.plugin_system import BaseAction, ActionActivationType, ChatMode
|
||||||
@@ -23,11 +22,10 @@ class NoReplyAction(BaseAction):
|
|||||||
action_name = "no_reply"
|
action_name = "no_reply"
|
||||||
action_description = "暂时不回复消息"
|
action_description = "暂时不回复消息"
|
||||||
|
|
||||||
# 最近三次no_reply的新消息兴趣度记录
|
|
||||||
_recent_interest_records: deque = deque(maxlen=3)
|
|
||||||
|
|
||||||
# 动作参数定义
|
# 动作参数定义
|
||||||
action_parameters = {}
|
action_parameters = {
|
||||||
|
"reason": "不回复的原因",
|
||||||
|
}
|
||||||
|
|
||||||
# 动作使用场景
|
# 动作使用场景
|
||||||
action_require = [""]
|
action_require = [""]
|
||||||
@@ -60,14 +58,3 @@ class NoReplyAction(BaseAction):
|
|||||||
action_done=True,
|
action_done=True,
|
||||||
)
|
)
|
||||||
return False, f"不回复动作执行失败: {e}"
|
return False, f"不回复动作执行失败: {e}"
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def reset_consecutive_count(cls):
|
|
||||||
"""重置连续计数器和兴趣度记录"""
|
|
||||||
cls._recent_interest_records.clear()
|
|
||||||
logger.debug("NoReplyAction连续计数器和兴趣度记录已重置")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_recent_interest_records(cls) -> List[float]:
|
|
||||||
"""获取最近的兴趣度记录"""
|
|
||||||
return list(cls._recent_interest_records)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user