refactor(chat): 重构消息兴趣度计算与动作记录机制
重构聊天系统以使用集中式消息管理API,移除ChatMessageContext类,将兴趣度计算和动作记录功能整合到StreamContext中。 主要变更: - 移除ChatMessageContext类,使用StreamContext统一管理消息上下文 - 在DatabaseMessages模型中添加interest_degree、actions、should_reply字段 - 实现消息管理器API用于更新消息信息和刷新focus_energy - 重构ChatStream的focus_energy计算逻辑,基于StreamContext历史消息 - 在动作管理器中添加动作记录功能,确保动作执行后更新消息状态 BREAKING CHANGE: ChatMessageContext类已被移除,相关功能需使用StreamContext API替代
This commit is contained in:
@@ -89,6 +89,18 @@ class MessageManager:
|
||||
|
||||
logger.debug(f"添加消息到聊天流 {stream_id}: {message.message_id}")
|
||||
|
||||
def update_message_and_refresh_energy(self, stream_id: str, message_id: str, interest_degree: float = None, actions: list = None, should_reply: bool = None):
|
||||
"""更新消息信息"""
|
||||
if stream_id in self.stream_contexts:
|
||||
context = self.stream_contexts[stream_id]
|
||||
context.update_message_info(message_id, interest_degree, actions, should_reply)
|
||||
|
||||
def add_action_and_refresh_energy(self, stream_id: str, message_id: str, action: str):
|
||||
"""添加动作到消息"""
|
||||
if stream_id in self.stream_contexts:
|
||||
context = self.stream_contexts[stream_id]
|
||||
context.add_action_to_message(message_id, action)
|
||||
|
||||
async def _manager_loop(self):
|
||||
"""管理器主循环 - 独立聊天流分发周期版本"""
|
||||
while self.is_running:
|
||||
@@ -296,72 +308,6 @@ class MessageManager:
|
||||
else:
|
||||
logger.debug(f"聊天流 {stream_id} 未触发打断,打断概率: {interruption_probability:.2f}")
|
||||
|
||||
def _calculate_dynamic_distribution_interval(self) -> float:
|
||||
"""根据所有活跃聊天流的focus_energy动态计算分发周期"""
|
||||
if not global_config.chat.dynamic_distribution_enabled:
|
||||
return self.check_interval # 使用固定间隔
|
||||
|
||||
if not self.stream_contexts:
|
||||
return self.check_interval # 默认间隔
|
||||
|
||||
# 计算活跃流的平均focus_energy
|
||||
active_streams = [ctx for ctx in self.stream_contexts.values() if ctx.is_active]
|
||||
if not active_streams:
|
||||
return self.check_interval
|
||||
|
||||
total_focus_energy = 0.0
|
||||
max_focus_energy = 0.0
|
||||
stream_count = 0
|
||||
|
||||
for context in active_streams:
|
||||
from src.plugin_system.apis.chat_api import get_chat_manager
|
||||
chat_stream = get_chat_manager().get_stream(context.stream_id)
|
||||
if chat_stream:
|
||||
focus_energy = chat_stream.focus_energy
|
||||
total_focus_energy += focus_energy
|
||||
max_focus_energy = max(max_focus_energy, focus_energy)
|
||||
stream_count += 1
|
||||
|
||||
if stream_count == 0:
|
||||
return self.check_interval
|
||||
|
||||
avg_focus_energy = total_focus_energy / stream_count
|
||||
|
||||
# 使用配置参数
|
||||
base_interval = global_config.chat.dynamic_distribution_base_interval
|
||||
min_interval = global_config.chat.dynamic_distribution_min_interval
|
||||
max_interval = global_config.chat.dynamic_distribution_max_interval
|
||||
jitter_factor = global_config.chat.dynamic_distribution_jitter_factor
|
||||
|
||||
# 根据平均兴趣度调整间隔
|
||||
# 高兴趣度 -> 更频繁检查 (间隔更短)
|
||||
# 低兴趣度 -> 较少检查 (间隔更长)
|
||||
if avg_focus_energy >= 0.7:
|
||||
# 高兴趣度:1-5秒
|
||||
interval = base_interval * (1.0 - (avg_focus_energy - 0.7) * 2.0)
|
||||
elif avg_focus_energy >= 0.4:
|
||||
# 中等兴趣度:5-15秒
|
||||
interval = base_interval * (1.0 + (avg_focus_energy - 0.4) * 3.33)
|
||||
else:
|
||||
# 低兴趣度:15-30秒
|
||||
interval = base_interval * (3.0 + (0.4 - avg_focus_energy) * 5.0)
|
||||
|
||||
# 添加随机扰动避免同步
|
||||
import random
|
||||
jitter = random.uniform(1.0 - jitter_factor, 1.0 + jitter_factor)
|
||||
final_interval = interval * jitter
|
||||
|
||||
# 限制在合理范围内
|
||||
final_interval = max(min_interval, min(max_interval, final_interval))
|
||||
|
||||
logger.debug(
|
||||
f"动态分发周期: {final_interval:.2f}s | "
|
||||
f"平均兴趣度: {avg_focus_energy:.3f} | "
|
||||
f"活跃流数: {stream_count}"
|
||||
)
|
||||
|
||||
return final_interval
|
||||
|
||||
def _calculate_stream_distribution_interval(self, context: StreamContext) -> float:
|
||||
"""计算单个聊天流的分发周期 - 基于阈值感知的focus_energy"""
|
||||
if not global_config.chat.dynamic_distribution_enabled:
|
||||
|
||||
@@ -25,43 +25,6 @@ install(extra_lines=3)
|
||||
logger = get_logger("chat_stream")
|
||||
|
||||
|
||||
class ChatMessageContext:
|
||||
"""聊天消息上下文,存储消息的上下文信息"""
|
||||
|
||||
def __init__(self, message: "MessageRecv"):
|
||||
self.message = message
|
||||
|
||||
def get_template_name(self) -> Optional[str]:
|
||||
"""获取模板名称"""
|
||||
if self.message.message_info.template_info and not self.message.message_info.template_info.template_default:
|
||||
return self.message.message_info.template_info.template_name # type: ignore
|
||||
return None
|
||||
|
||||
def get_last_message(self) -> "MessageRecv":
|
||||
"""获取最后一条消息"""
|
||||
return self.message
|
||||
|
||||
def check_types(self, types: list) -> bool:
|
||||
# sourcery skip: invert-any-all, use-any, use-next
|
||||
"""检查消息类型"""
|
||||
if not self.message.message_info.format_info.accept_format: # type: ignore
|
||||
return False
|
||||
for t in types:
|
||||
if t not in self.message.message_info.format_info.accept_format: # type: ignore
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_priority_mode(self) -> str:
|
||||
"""获取优先级模式"""
|
||||
return self.message.priority_mode
|
||||
|
||||
def get_priority_info(self) -> Optional[dict]:
|
||||
"""获取优先级信息"""
|
||||
if hasattr(self.message, "priority_info") and self.message.priority_info:
|
||||
return self.message.priority_info
|
||||
return None
|
||||
|
||||
|
||||
class ChatStream:
|
||||
"""聊天流对象,存储一个完整的聊天上下文"""
|
||||
|
||||
@@ -79,24 +42,23 @@ class ChatStream:
|
||||
self.group_info = group_info
|
||||
self.create_time = data.get("create_time", time.time()) if data else time.time()
|
||||
self.last_active_time = data.get("last_active_time", self.create_time) if data else self.create_time
|
||||
self.energy_value = data.get("energy_value", 5.0) if data else 5.0
|
||||
self.sleep_pressure = data.get("sleep_pressure", 0.0) if data else 0.0
|
||||
self.saved = False
|
||||
self.context: ChatMessageContext = None # type: ignore # 用于存储该聊天的上下文信息
|
||||
|
||||
# 动态兴趣度系统 - 重构后的focus_energy
|
||||
self.base_interest_energy = data.get("base_interest_energy", 0.5) if data else 0.5
|
||||
self.message_interest_total = data.get("message_interest_total", 0.0) if data else 0.0
|
||||
self.message_count = data.get("message_count", 0) if data else 0
|
||||
self.action_count = data.get("action_count", 0) if data else 0
|
||||
self.reply_count = data.get("reply_count", 0) if data else 0
|
||||
self.last_interaction_time = data.get("last_interaction_time", time.time()) if data else time.time()
|
||||
self.consecutive_no_reply = data.get("consecutive_no_reply", 0) if data else 0
|
||||
# 使用StreamContext替代ChatMessageContext
|
||||
from src.common.data_models.message_manager_data_model import StreamContext
|
||||
from src.plugin_system.base.component_types import ChatType, ChatMode
|
||||
self.stream_context: StreamContext = StreamContext(
|
||||
stream_id=stream_id,
|
||||
chat_type=ChatType.GROUP if group_info else ChatType.PRIVATE,
|
||||
chat_mode=ChatMode.NORMAL
|
||||
)
|
||||
|
||||
# 计算动态focus_energy
|
||||
self.focus_energy = self._calculate_dynamic_focus_energy()
|
||||
# 基础参数
|
||||
self.base_interest_energy = 0.5 # 默认基础兴趣度
|
||||
self._focus_energy = 0.5 # 内部存储的focus_energy值
|
||||
self.no_reply_consecutive = 0
|
||||
self.breaking_accumulated_interest = 0.0
|
||||
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
"""转换为字典格式"""
|
||||
@@ -107,18 +69,13 @@ class ChatStream:
|
||||
"group_info": self.group_info.to_dict() if self.group_info else None,
|
||||
"create_time": self.create_time,
|
||||
"last_active_time": self.last_active_time,
|
||||
"energy_value": self.energy_value,
|
||||
"sleep_pressure": self.sleep_pressure,
|
||||
"focus_energy": self.focus_energy,
|
||||
"breaking_accumulated_interest": self.breaking_accumulated_interest,
|
||||
# 新增动态兴趣度系统字段
|
||||
# 基础兴趣度
|
||||
"base_interest_energy": self.base_interest_energy,
|
||||
"message_interest_total": self.message_interest_total,
|
||||
"message_count": self.message_count,
|
||||
"action_count": self.action_count,
|
||||
"reply_count": self.reply_count,
|
||||
"last_interaction_time": self.last_interaction_time,
|
||||
"consecutive_no_reply": self.consecutive_no_reply,
|
||||
# 新增stream_context信息
|
||||
"stream_context_chat_type": self.stream_context.chat_type.value,
|
||||
"stream_context_chat_mode": self.stream_context.chat_mode.value,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
@@ -127,7 +84,7 @@ class ChatStream:
|
||||
user_info = UserInfo.from_dict(data.get("user_info", {})) if data.get("user_info") else None
|
||||
group_info = GroupInfo.from_dict(data.get("group_info", {})) if data.get("group_info") else None
|
||||
|
||||
return cls(
|
||||
instance = cls(
|
||||
stream_id=data["stream_id"],
|
||||
platform=data["platform"],
|
||||
user_info=user_info, # type: ignore
|
||||
@@ -135,6 +92,16 @@ class ChatStream:
|
||||
data=data,
|
||||
)
|
||||
|
||||
# 恢复stream_context信息
|
||||
if "stream_context_chat_type" in data:
|
||||
from src.plugin_system.base.component_types import ChatType, ChatMode
|
||||
instance.stream_context.chat_type = ChatType(data["stream_context_chat_type"])
|
||||
if "stream_context_chat_mode" in data:
|
||||
from src.plugin_system.base.component_types import ChatType, ChatMode
|
||||
instance.stream_context.chat_mode = ChatMode(data["stream_context_chat_mode"])
|
||||
|
||||
return instance
|
||||
|
||||
def update_active_time(self):
|
||||
"""更新最后活跃时间"""
|
||||
self.last_active_time = time.time()
|
||||
@@ -142,32 +109,91 @@ class ChatStream:
|
||||
|
||||
def set_context(self, message: "MessageRecv"):
|
||||
"""设置聊天消息上下文"""
|
||||
self.context = ChatMessageContext(message)
|
||||
# 将MessageRecv转换为DatabaseMessages并设置到stream_context
|
||||
from src.common.data_models.database_data_model import DatabaseMessages
|
||||
|
||||
# 简化转换,实际可能需要更完整的转换逻辑
|
||||
db_message = DatabaseMessages(
|
||||
message_id=getattr(message, 'message_id', ''),
|
||||
time=getattr(message, 'time', time.time()),
|
||||
chat_id=getattr(message, 'chat_id', ''),
|
||||
user_id=str(getattr(message.message_info, 'user_info', {}).user_id) if hasattr(message, 'message_info') and hasattr(message.message_info, 'user_info') else '',
|
||||
user_nickname=getattr(message.message_info, 'user_info', {}).user_nickname if hasattr(message, 'message_info') and hasattr(message.message_info, 'user_info') else '',
|
||||
user_platform=getattr(message.message_info, 'user_info', {}).platform if hasattr(message, 'message_info') and hasattr(message.message_info, 'user_info') else '',
|
||||
priority_mode=getattr(message, 'priority_mode', None),
|
||||
priority_info=str(getattr(message, 'priority_info', None)) if hasattr(message, 'priority_info') and message.priority_info else None,
|
||||
)
|
||||
|
||||
self.stream_context.set_current_message(db_message)
|
||||
self.stream_context.priority_mode = getattr(message, 'priority_mode', None)
|
||||
self.stream_context.priority_info = getattr(message, 'priority_info', None)
|
||||
|
||||
@property
|
||||
def focus_energy(self) -> float:
|
||||
"""动态计算的聊天流总体兴趣度,访问时自动更新"""
|
||||
self._focus_energy = self._calculate_dynamic_focus_energy()
|
||||
return self._focus_energy
|
||||
|
||||
@focus_energy.setter
|
||||
def focus_energy(self, value: float):
|
||||
"""设置focus_energy值(主要用于初始化或特殊场景)"""
|
||||
self._focus_energy = max(0.0, min(1.0, value))
|
||||
|
||||
def _calculate_dynamic_focus_energy(self) -> float:
|
||||
"""动态计算聊天流的总体兴趣度"""
|
||||
"""动态计算聊天流的总体兴趣度,使用StreamContext历史消息"""
|
||||
try:
|
||||
# 基础分:平均消息兴趣度
|
||||
avg_message_interest = self.message_interest_total / max(self.message_count, 1)
|
||||
# 从StreamContext获取历史消息计算统计数据
|
||||
history_messages = self.stream_context.get_history_messages(limit=global_config.chat.max_context_size)
|
||||
unread_messages = self.stream_context.get_unread_messages()
|
||||
all_messages = history_messages + unread_messages
|
||||
|
||||
# 动作参与度:动作执行率
|
||||
action_rate = self.action_count / max(self.message_count, 1)
|
||||
# 计算基于历史消息的统计数据
|
||||
if all_messages:
|
||||
# 基础分:平均消息兴趣度
|
||||
message_interests = [msg.interest_degree for msg in all_messages if hasattr(msg, 'interest_degree')]
|
||||
avg_message_interest = sum(message_interests) / len(message_interests) if message_interests else 0.3
|
||||
|
||||
# 回复活跃度:回复率
|
||||
reply_rate = self.reply_count / max(self.message_count, 1)
|
||||
# 动作参与度:有动作的消息比例
|
||||
messages_with_actions = [msg for msg in all_messages if hasattr(msg, 'actions') and msg.actions]
|
||||
action_rate = len(messages_with_actions) / len(all_messages)
|
||||
|
||||
# 回复活跃度:应该回复且已回复的消息比例
|
||||
should_reply_messages = [msg for msg in all_messages if hasattr(msg, 'should_reply') and msg.should_reply]
|
||||
replied_messages = [msg for msg in should_reply_messages if hasattr(msg, 'actions') and 'reply' in (msg.actions or [])]
|
||||
reply_rate = len(replied_messages) / len(should_reply_messages) if should_reply_messages else 0.0
|
||||
|
||||
# 获取最后交互时间
|
||||
if all_messages:
|
||||
self.last_interaction_time = max(msg.time for msg in all_messages)
|
||||
|
||||
# 连续无回复计算:从最近的未回复消息计数
|
||||
consecutive_no_reply = 0
|
||||
for msg in reversed(all_messages):
|
||||
if hasattr(msg, 'should_reply') and msg.should_reply:
|
||||
if not (hasattr(msg, 'actions') and 'reply' in (msg.actions or [])):
|
||||
consecutive_no_reply += 1
|
||||
else:
|
||||
break
|
||||
else:
|
||||
# 没有历史消息时的默认值
|
||||
avg_message_interest = 0.3
|
||||
action_rate = 0.0
|
||||
reply_rate = 0.0
|
||||
consecutive_no_reply = 0
|
||||
self.last_interaction_time = time.time()
|
||||
|
||||
# 获取用户关系分(对于私聊,群聊无效)
|
||||
relationship_factor = self._get_user_relationship_score()
|
||||
|
||||
# 时间衰减因子:最近活跃度
|
||||
current_time = time.time()
|
||||
if not self.last_interaction_time:
|
||||
if not hasattr(self, 'last_interaction_time') or not self.last_interaction_time:
|
||||
self.last_interaction_time = current_time
|
||||
time_since_interaction = current_time - self.last_interaction_time
|
||||
time_decay = max(0.3, 1.0 - min(time_since_interaction / (7 * 24 * 3600), 0.7)) # 7天衰减
|
||||
|
||||
# 连续无回复惩罚
|
||||
no_reply_penalty = max(0.1, 1.0 - self.consecutive_no_reply * 0.1)
|
||||
no_reply_penalty = max(0.1, 1.0 - consecutive_no_reply * 0.1)
|
||||
|
||||
# 获取AFC系统阈值,添加None值检查
|
||||
reply_threshold = getattr(global_config.affinity_flow, 'reply_action_interest_threshold', 0.4)
|
||||
@@ -250,45 +276,8 @@ class ChatStream:
|
||||
# 默认基础分
|
||||
return 0.3
|
||||
|
||||
def add_message_interest(self, interest_score: float):
|
||||
"""添加消息兴趣值并更新focus_energy"""
|
||||
self.message_interest_total += interest_score
|
||||
self.message_count += 1
|
||||
self.last_interaction_time = time.time()
|
||||
self.focus_energy = self._calculate_dynamic_focus_energy()
|
||||
|
||||
def update_focus_energy(self):
|
||||
"""手动触发更新focus_energy"""
|
||||
self.focus_energy = self._calculate_dynamic_focus_energy()
|
||||
|
||||
def record_action(self, is_reply: bool = False):
|
||||
"""记录动作执行"""
|
||||
self.action_count += 1
|
||||
if is_reply:
|
||||
self.reply_count += 1
|
||||
self.consecutive_no_reply = max(0, self.consecutive_no_reply - 1)
|
||||
self.last_interaction_time = time.time()
|
||||
self.focus_energy = self._calculate_dynamic_focus_energy()
|
||||
|
||||
def record_no_reply(self):
|
||||
"""记录无回复动作"""
|
||||
self.consecutive_no_reply += 1
|
||||
self.last_interaction_time = time.time()
|
||||
self.focus_energy = self._calculate_dynamic_focus_energy()
|
||||
|
||||
def get_adjusted_focus_energy(self) -> float:
|
||||
"""获取应用了afc调整的focus_energy"""
|
||||
try:
|
||||
from src.chat.message_manager.message_manager import message_manager
|
||||
if self.stream_id in message_manager.stream_contexts:
|
||||
context = message_manager.stream_contexts[self.stream_id]
|
||||
afc_adjustment = context.get_afc_threshold_adjustment()
|
||||
# 对动态计算的focus_energy应用AFC调整
|
||||
adjusted_energy = max(0.0, self.focus_energy - afc_adjustment)
|
||||
return adjusted_energy
|
||||
except Exception:
|
||||
pass
|
||||
return self.focus_energy
|
||||
|
||||
|
||||
class ChatManager:
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import asyncio
|
||||
import traceback
|
||||
import time
|
||||
import random
|
||||
from typing import Dict, Optional, Type, Any, Tuple
|
||||
|
||||
|
||||
@@ -210,8 +209,10 @@ class ChatterActionManager:
|
||||
target_message,
|
||||
)
|
||||
|
||||
# 如果动作执行成功且不是no_action,重置打断计数
|
||||
# 记录执行的动作到目标消息
|
||||
if success:
|
||||
await self._record_action_to_message(chat_stream, action_name, target_message, action_data)
|
||||
# 重置打断计数
|
||||
await self._reset_interruption_count_after_action(chat_stream.stream_id)
|
||||
|
||||
return {
|
||||
@@ -252,6 +253,9 @@ class ChatterActionManager:
|
||||
[], # actions
|
||||
)
|
||||
|
||||
# 记录回复动作到目标消息
|
||||
await self._record_action_to_message(chat_stream, "reply", target_message, action_data)
|
||||
|
||||
# 回复成功,重置打断计数
|
||||
await self._reset_interruption_count_after_action(chat_stream.stream_id)
|
||||
|
||||
@@ -268,6 +272,45 @@ class ChatterActionManager:
|
||||
"error": str(e),
|
||||
}
|
||||
|
||||
async def _record_action_to_message(self, chat_stream, action_name, target_message, action_data):
|
||||
"""
|
||||
记录执行的动作到目标消息中
|
||||
|
||||
Args:
|
||||
chat_stream: ChatStream实例
|
||||
action_name: 动作名称
|
||||
target_message: 目标消息
|
||||
action_data: 动作数据
|
||||
"""
|
||||
try:
|
||||
from src.chat.message_manager.message_manager import message_manager
|
||||
|
||||
# 获取目标消息ID
|
||||
target_message_id = None
|
||||
if target_message and isinstance(target_message, dict):
|
||||
target_message_id = target_message.get("message_id")
|
||||
elif action_data and isinstance(action_data, dict):
|
||||
target_message_id = action_data.get("target_message_id")
|
||||
|
||||
if not target_message_id:
|
||||
logger.debug(f"无法获取目标消息ID,动作: {action_name}")
|
||||
return
|
||||
|
||||
# 通过message_manager更新消息的动作记录并刷新focus_energy
|
||||
if chat_stream.stream_id in message_manager.stream_contexts:
|
||||
message_manager.add_action_and_refresh_energy(
|
||||
stream_id=chat_stream.stream_id,
|
||||
message_id=target_message_id,
|
||||
action=action_name
|
||||
)
|
||||
logger.debug(f"已记录动作 {action_name} 到消息 {target_message_id} 并更新focus_energy")
|
||||
else:
|
||||
logger.debug(f"未找到stream_context: {chat_stream.stream_id}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"记录动作到消息失败: {e}")
|
||||
# 不抛出异常,避免影响主要功能
|
||||
|
||||
async def _reset_interruption_count_after_action(self, stream_id: str):
|
||||
"""在动作执行成功后重置打断计数"""
|
||||
from src.chat.message_manager.message_manager import message_manager
|
||||
|
||||
@@ -7,7 +7,8 @@ from typing import List, Any, Dict, TYPE_CHECKING, Tuple
|
||||
from src.common.logger import get_logger
|
||||
from src.config.config import global_config, model_config
|
||||
from src.llm_models.utils_model import LLMRequest
|
||||
from src.chat.message_receive.chat_stream import get_chat_manager, ChatMessageContext
|
||||
from src.chat.message_receive.chat_stream import get_chat_manager
|
||||
from src.common.data_models.message_manager_data_model import StreamContext
|
||||
from src.chat.planner_actions.action_manager import ChatterActionManager
|
||||
from src.chat.utils.chat_message_builder import get_raw_msg_before_timestamp_with_chat, build_readable_messages
|
||||
from src.plugin_system.base.component_types import ActionInfo, ActionActivationType
|
||||
@@ -124,7 +125,7 @@ class ActionModifier:
|
||||
logger.debug(f"{self.log_prefix}阶段一移除动作: {disabled_action_name},原因: 用户自行禁用")
|
||||
|
||||
# === 第二阶段:检查动作的关联类型 ===
|
||||
chat_context = self.chat_stream.context
|
||||
chat_context = self.chat_stream.stream_context
|
||||
current_actions_s2 = self.action_manager.get_using_actions()
|
||||
type_mismatched_actions = self._check_action_associated_types(current_actions_s2, chat_context)
|
||||
|
||||
@@ -166,7 +167,7 @@ class ActionModifier:
|
||||
|
||||
logger.info(f"{self.log_prefix} 当前可用动作: {available_actions_text}||移除: {removals_summary}")
|
||||
|
||||
def _check_action_associated_types(self, all_actions: Dict[str, ActionInfo], chat_context: ChatMessageContext):
|
||||
def _check_action_associated_types(self, all_actions: Dict[str, ActionInfo], chat_context: StreamContext):
|
||||
type_mismatched_actions: List[Tuple[str, str]] = []
|
||||
for action_name, action_info in all_actions.items():
|
||||
if action_info.associated_types and not chat_context.check_types(action_info.associated_types):
|
||||
|
||||
@@ -95,6 +95,10 @@ class DatabaseMessages(BaseDataModel):
|
||||
chat_info_platform: str = "",
|
||||
chat_info_create_time: float = 0.0,
|
||||
chat_info_last_active_time: float = 0.0,
|
||||
# 新增字段
|
||||
interest_degree: float = 0.0,
|
||||
actions: Optional[list] = None,
|
||||
should_reply: bool = False,
|
||||
**kwargs: Any,
|
||||
):
|
||||
self.message_id = message_id
|
||||
@@ -103,6 +107,11 @@ class DatabaseMessages(BaseDataModel):
|
||||
self.reply_to = reply_to
|
||||
self.interest_value = interest_value
|
||||
|
||||
# 新增字段
|
||||
self.interest_degree = interest_degree
|
||||
self.actions = actions
|
||||
self.should_reply = should_reply
|
||||
|
||||
self.key_words = key_words
|
||||
self.key_words_lite = key_words_lite
|
||||
self.is_mentioned = is_mentioned
|
||||
@@ -191,6 +200,10 @@ class DatabaseMessages(BaseDataModel):
|
||||
"is_notify": self.is_notify,
|
||||
"selected_expressions": self.selected_expressions,
|
||||
"is_read": self.is_read,
|
||||
# 新增字段
|
||||
"interest_degree": self.interest_degree,
|
||||
"actions": self.actions,
|
||||
"should_reply": self.should_reply,
|
||||
"user_id": self.user_info.user_id,
|
||||
"user_nickname": self.user_info.user_nickname,
|
||||
"user_cardname": self.user_info.user_cardname,
|
||||
@@ -208,6 +221,60 @@ class DatabaseMessages(BaseDataModel):
|
||||
"chat_info_user_cardname": self.chat_info.user_info.user_cardname,
|
||||
}
|
||||
|
||||
def update_message_info(self, interest_degree: float = None, actions: list = None, should_reply: bool = None):
|
||||
"""
|
||||
更新消息信息
|
||||
|
||||
Args:
|
||||
interest_degree: 兴趣度值
|
||||
actions: 执行的动作列表
|
||||
should_reply: 是否应该回复
|
||||
"""
|
||||
if interest_degree is not None:
|
||||
self.interest_degree = interest_degree
|
||||
if actions is not None:
|
||||
self.actions = actions
|
||||
if should_reply is not None:
|
||||
self.should_reply = should_reply
|
||||
|
||||
def add_action(self, action: str):
|
||||
"""
|
||||
添加执行的动作到消息中
|
||||
|
||||
Args:
|
||||
action: 要添加的动作名称
|
||||
"""
|
||||
if self.actions is None:
|
||||
self.actions = []
|
||||
if action not in self.actions: # 避免重复添加
|
||||
self.actions.append(action)
|
||||
|
||||
def get_actions(self) -> list:
|
||||
"""
|
||||
获取执行的动作列表
|
||||
|
||||
Returns:
|
||||
动作列表,如果没有动作则返回空列表
|
||||
"""
|
||||
return self.actions or []
|
||||
|
||||
def get_message_summary(self) -> Dict[str, Any]:
|
||||
"""
|
||||
获取消息摘要信息
|
||||
|
||||
Returns:
|
||||
包含关键字段的消息摘要
|
||||
"""
|
||||
return {
|
||||
"message_id": self.message_id,
|
||||
"time": self.time,
|
||||
"interest_degree": self.interest_degree,
|
||||
"actions": self.actions,
|
||||
"should_reply": self.should_reply,
|
||||
"user_nickname": self.user_info.user_nickname,
|
||||
"display_message": self.display_message,
|
||||
}
|
||||
|
||||
|
||||
@dataclass(init=False)
|
||||
class DatabaseActionRecords(BaseDataModel):
|
||||
|
||||
@@ -47,6 +47,11 @@ class StreamContext(BaseDataModel):
|
||||
next_check_time: float = field(default_factory=time.time) # 下次检查时间
|
||||
distribution_interval: float = 5.0 # 当前分发周期(秒)
|
||||
|
||||
# 新增字段以替代ChatMessageContext功能
|
||||
current_message: Optional["DatabaseMessages"] = None
|
||||
priority_mode: Optional[str] = None
|
||||
priority_info: Optional[dict] = None
|
||||
|
||||
def add_message(self, message: "DatabaseMessages"):
|
||||
"""添加消息到上下文"""
|
||||
message.is_read = False
|
||||
@@ -55,6 +60,48 @@ class StreamContext(BaseDataModel):
|
||||
# 自动检测和更新chat type
|
||||
self._detect_chat_type(message)
|
||||
|
||||
def update_message_info(self, message_id: str, interest_degree: float = None, actions: list = None, should_reply: bool = None):
|
||||
"""
|
||||
更新消息信息
|
||||
|
||||
Args:
|
||||
message_id: 消息ID
|
||||
interest_degree: 兴趣度值
|
||||
actions: 执行的动作列表
|
||||
should_reply: 是否应该回复
|
||||
"""
|
||||
# 在未读消息中查找并更新
|
||||
for message in self.unread_messages:
|
||||
if message.message_id == message_id:
|
||||
message.update_message_info(interest_degree, actions, should_reply)
|
||||
break
|
||||
|
||||
# 在历史消息中查找并更新
|
||||
for message in self.history_messages:
|
||||
if message.message_id == message_id:
|
||||
message.update_message_info(interest_degree, actions, should_reply)
|
||||
break
|
||||
|
||||
def add_action_to_message(self, message_id: str, action: str):
|
||||
"""
|
||||
向指定消息添加执行的动作
|
||||
|
||||
Args:
|
||||
message_id: 消息ID
|
||||
action: 要添加的动作名称
|
||||
"""
|
||||
# 在未读消息中查找并更新
|
||||
for message in self.unread_messages:
|
||||
if message.message_id == message_id:
|
||||
message.add_action(action)
|
||||
break
|
||||
|
||||
# 在历史消息中查找并更新
|
||||
for message in self.history_messages:
|
||||
if message.message_id == message_id:
|
||||
message.add_action(action)
|
||||
break
|
||||
|
||||
def _detect_chat_type(self, message: "DatabaseMessages"):
|
||||
"""根据消息内容自动检测聊天类型"""
|
||||
# 只有在第一次添加消息时才检测聊天类型,避免后续消息改变类型
|
||||
@@ -150,6 +197,61 @@ class StreamContext(BaseDataModel):
|
||||
"""获取当前的afc阈值调整量"""
|
||||
return self.afc_threshold_adjustment
|
||||
|
||||
def set_current_message(self, message: "DatabaseMessages"):
|
||||
"""设置当前消息"""
|
||||
self.current_message = message
|
||||
|
||||
def get_template_name(self) -> Optional[str]:
|
||||
"""获取模板名称"""
|
||||
if self.current_message and hasattr(self.current_message, 'additional_config') and self.current_message.additional_config:
|
||||
try:
|
||||
import json
|
||||
config = json.loads(self.current_message.additional_config)
|
||||
if config.get('template_info') and not config.get('template_default', True):
|
||||
return config.get('template_name')
|
||||
except (json.JSONDecodeError, AttributeError):
|
||||
pass
|
||||
return None
|
||||
|
||||
def get_last_message(self) -> Optional["DatabaseMessages"]:
|
||||
"""获取最后一条消息"""
|
||||
if self.current_message:
|
||||
return self.current_message
|
||||
if self.unread_messages:
|
||||
return self.unread_messages[-1]
|
||||
if self.history_messages:
|
||||
return self.history_messages[-1]
|
||||
return None
|
||||
|
||||
def check_types(self, types: list) -> bool:
|
||||
"""检查消息类型"""
|
||||
if not self.current_message:
|
||||
return False
|
||||
|
||||
# 检查消息是否支持指定的类型
|
||||
# 这里简化处理,实际应该根据消息的格式信息检查
|
||||
if hasattr(self.current_message, 'additional_config') and self.current_message.additional_config:
|
||||
try:
|
||||
import json
|
||||
config = json.loads(self.current_message.additional_config)
|
||||
if 'format_info' in config and 'accept_format' in config['format_info']:
|
||||
accept_format = config['format_info']['accept_format']
|
||||
for t in types:
|
||||
if t not in accept_format:
|
||||
return False
|
||||
return True
|
||||
except (json.JSONDecodeError, AttributeError):
|
||||
pass
|
||||
return False
|
||||
|
||||
def get_priority_mode(self) -> Optional[str]:
|
||||
"""获取优先级模式"""
|
||||
return self.priority_mode
|
||||
|
||||
def get_priority_info(self) -> Optional[dict]:
|
||||
"""获取优先级信息"""
|
||||
return self.priority_info
|
||||
|
||||
|
||||
@dataclass
|
||||
class MessageManagerStats(BaseDataModel):
|
||||
|
||||
@@ -128,7 +128,6 @@ class ChatterActionPlanner:
|
||||
# 更新ChatStream的兴趣度数据
|
||||
from src.plugin_system.apis.chat_api import get_chat_manager
|
||||
chat_stream = get_chat_manager().get_stream(self.chat_id)
|
||||
chat_stream.add_message_interest(score)
|
||||
logger.debug(f"已更新聊天 {self.chat_id} 的ChatStream兴趣度,分数: {score:.3f}")
|
||||
|
||||
# 更新情绪状态和ChatStream兴趣度数据
|
||||
@@ -137,6 +136,39 @@ class ChatterActionPlanner:
|
||||
await chat_mood.update_mood_by_message(latest_message, score)
|
||||
logger.debug(f"已更新聊天 {self.chat_id} 的情绪状态,兴趣度: {score:.3f}")
|
||||
|
||||
# 为所有未读消息记录兴趣度信息
|
||||
for message in unread_messages:
|
||||
# 查找对应的兴趣度评分
|
||||
message_score = next((s for s in interest_scores if s.message_id == message.message_id), None)
|
||||
if message_score:
|
||||
message.interest_degree = message_score.total_score
|
||||
message.should_reply = self.interest_scoring.should_reply(message_score, message)[0]
|
||||
logger.debug(f"已记录消息 {message.message_id} - 兴趣度: {message_score.total_score:.3f}, 应回复: {message.should_reply}")
|
||||
|
||||
# 更新StreamContext中的消息信息并刷新focus_energy
|
||||
if context:
|
||||
from src.chat.message_manager.message_manager import message_manager
|
||||
message_manager.update_message_and_refresh_energy(
|
||||
stream_id=self.chat_id,
|
||||
message_id=message.message_id,
|
||||
interest_degree=message_score.total_score,
|
||||
should_reply=message.should_reply
|
||||
)
|
||||
else:
|
||||
# 如果没有找到评分,设置默认值
|
||||
message.interest_degree = 0.0
|
||||
message.should_reply = False
|
||||
|
||||
# 更新StreamContext中的消息信息并刷新focus_energy
|
||||
if context:
|
||||
from src.chat.message_manager.message_manager import message_manager
|
||||
message_manager.update_message_and_refresh_energy(
|
||||
stream_id=self.chat_id,
|
||||
message_id=message.message_id,
|
||||
interest_degree=0.0,
|
||||
should_reply=False
|
||||
)
|
||||
|
||||
# base_threshold = self.interest_scoring.reply_threshold
|
||||
# 检查兴趣度是否达到非回复动作阈值
|
||||
non_reply_action_interest_threshold = global_config.affinity_flow.non_reply_action_interest_threshold
|
||||
@@ -169,10 +201,13 @@ class ChatterActionPlanner:
|
||||
# 5. 使用 PlanExecutor 执行 Plan
|
||||
execution_result = await self.executor.execute(filtered_plan)
|
||||
|
||||
# 6. 根据执行结果更新统计信息
|
||||
# 6. 动作记录现在由ChatterActionManager统一处理
|
||||
# 动作记录逻辑已移至ChatterActionManager.execute_action方法中
|
||||
|
||||
# 7. 根据执行结果更新统计信息
|
||||
self._update_stats_from_execution_result(execution_result)
|
||||
|
||||
# 7. 检查关系更新
|
||||
# 8. 检查关系更新
|
||||
await self.relationship_tracker.check_and_update_relationships()
|
||||
|
||||
# 8. 返回结果
|
||||
|
||||
Reference in New Issue
Block a user